Um sensor Pico W a bateria com MQTT só funciona se a placa passar quase toda a vida dormindo e apenas alguns segundos acordada. Neste tutorial você vai montar um nó sensor em MicroPython que acorda por timer, lê um sensor e a própria tensão da bateria, publica uma mensagem QoS 1 em um broker MQTT, desliga o rádio e volta ao lightsleep. Você também vai descobrir quais decisões de projeto realmente aumentam a autonomia e quais são esforço desperdiçado.
Por que a alimentação por bateria é difícil no Pico W
O Pico W foi projetado como uma placa microcontroladora barata e flexível, não como uma plataforma de sensores de ultrabaixo consumo. O RP2040 em si é eficiente o suficiente, mas três fatores jogam contra você quando o assunto é bateria:
- O chip Wi-Fi CYW43439 consome muito mais corrente ao se associar e transmitir do que o microcontrolador ao processar. Cada segundo com o rádio ligado custa mais do que minutos de sono.
- O regulador buck-boost da placa tem uma corrente quiescente que nunca desaparece, mesmo com o RP2040 dormindo.
- Os modos de sono do MicroPython são limitados em comparação com chips como o ESP32.
machine.lightsleep()para os clocks e mantém a RAM, o que é útil, mas a placa ainda consome visivelmente mais do que um nó de baixo consumo dedicado.
A consequência prática é simples: a autonomia é dominada por com que frequência você acorda e quanto tempo leva a conexão Wi-Fi. Otimizar o código Python que lê o sensor quase não faz diferença. Passar de um intervalo de publicação de 30 segundos para 5 minutos, ou reduzir o tempo de conexão de oito para três segundos, faz uma diferença enorme.
Se você ainda não conectou um Pico W ao MQTT, comece pelo guia de MQTT com Raspberry Pi Pico W e volte aqui quando uma publicação básica estiver funcionando.
O projeto do duty cycle
Todo despertar segue o mesmo roteiro curto. Mantê-lo estritamente linear (sem tarefas em segundo plano, sem conexão de longa duração) é o que o torna previsível.
- Acordar do lightsleep (ou de um cold boot após uma queda de energia).
- Ler a tensão da bateria antes de ligar o Wi-Fi.
- Ler o sensor.
- Ligar o Wi-Fi com uma configuração estática e um timeout rígido.
- Conectar ao broker, publicar uma mensagem com QoS 1 e aguardar a confirmação.
- Desconectar de forma limpa, desligar o rádio e desinicializá-lo.
- Entrar em lightsleep pelo intervalo configurado e repetir o ciclo.
| Decisão de projeto | Efeito na autonomia | Recomendação |
|---|---|---|
| Intervalo de publicação | Maior fator isolado | 5 a 15 minutos para dados de clima ambiente |
| Tempo de conexão Wi-Fi | Segundo maior fator | Sinal forte, WPA2, timeout curto |
| Manter o MQTT conectado durante o sono | O rádio fica parcialmente ativo | Nunca com bateria |
| Publicação QoS 1 | Uma ida e volta extra | Vale a pena, você sabe que a mensagem chegou |
Lightsleep vs. time.sleep() ativo |
Lightsleep para os clocks | Sempre lightsleep entre ciclos |
| LED piscando para status | Consumo pequeno, mas constante | Desative em produção |
| Chip timer externo (TPL5110 ou similar) | Corta totalmente a alimentação da placa | Melhor opção para meses de autonomia |
Hardware e ligações
Você precisa de um Pico W (ou Pico 2 W), um sensor e uma fonte de energia no VSYS. Uma configuração comum são três pilhas AA ou AAA em série alimentando o VSYS diretamente, ou uma única célula LiPo com placa de proteção. Não ultrapasse o limite de VSYS indicado no datasheet oficial e nunca conecte baterias ao VBUS com o USB ligado sem um diodo.
Para o sensor, qualquer componente I2C com baixa corrente em standby serve. Este exemplo usa um BME280 no I2C0 (GP4 = SDA, GP5 = SCL), mas a lógica de duty cycle independe do sensor.
O Pico W consegue medir a própria tensão de alimentação no ADC3, que está ligado ao VSYS por um divisor 1:3. No Pico W esse pino (GP29) é compartilhado com o clock SPI do chip Wi-Fi, então você precisa lê-lo com o rádio desligado e com o GP25 em nível alto. É por isso que a leitura de tensão acontece primeiro no ciclo.
Prepare o MicroPython e a biblioteca MQTT
Grave um firmware MicroPython atual para o Pico W a partir da documentação oficial do Raspberry Pi e depois instale a biblioteca umqtt.simple e um driver do BME280 com o mpremote:
pip install mpremote
mpremote mip install umqtt.simple
mpremote cp bme280.py :bme280.py
Crie um secrets.py na placa para manter as credenciais fora do script principal:
# secrets.py
WIFI_SSID = "your-ssid"
WIFI_PASSWORD = "your-wifi-password"
MQTT_HOST = "broker.connectmq.com"
MQTT_PORT = 1883
MQTT_CLIENT_ID = "pico-bat-7f3a91" # não pode ser vazio e deve ser único
MQTT_USER = None # defina YOUR_USERNAME para um broker privado
MQTT_PASSWORD = None # defina YOUR_PASSWORD para um broker privado
TOPIC = "connectmq/demo/7f3a91/garden/climate"
INTERVAL_S = 600 # 10 minutos entre leituras
O servidor MQTT público em broker.connectmq.com aceita conexões anônimas com qualquer client ID não vazio. Tudo o que é publicado ali pode ser lido por qualquer pessoa, então use um prefixo de topic aleatório e nunca envie dados pessoais. O guia do servidor MQTT público gratuito lista os limites dele.
O script MQTT completo para bateria
Salve como main.py. Ele roda automaticamente a cada boot e, como o loop usa lightsleep em vez de reset, o estado da RAM, como o contador de ciclos, sobrevive entre os despertares.
# main.py - sensor MQTT com Pico W alimentado por bateria
import time
import json
import network
import machine
from machine import Pin, ADC, I2C
from umqtt.simple import MQTTClient
import bme280
import secrets
led = Pin("LED", Pin.OUT)
led.off()
i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=100_000)
cycle = 0
def read_vsys():
"""Read VSYS on the Pico W. Must run while the Wi-Fi chip is off."""
Pin(25, Pin.OUT).value(1) # desseleciona o barramento SPI do CYW43
Pin(29, Pin.IN, None) # libera o pino compartilhado para o ADC
adc = ADC(3)
total = 0
for _ in range(8):
total += adc.read_u16()
time.sleep_ms(2)
raw = total / 8
return round(raw * 3.3 * 3 / 65535, 3)
def read_sensor():
sensor = bme280.BME280(i2c=i2c)
t, p, h = sensor.read_compensated_data()
# O driver retorna centésimos de grau, Pa*256 e %UR*1024
return round(t / 100, 2), round(h / 1024, 1), round(p / 25600, 1)
def wifi_up(timeout_ms=10_000):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(secrets.WIFI_SSID, secrets.WIFI_PASSWORD)
start = time.ticks_ms()
while not wlan.isconnected():
if time.ticks_diff(time.ticks_ms(), start) > timeout_ms:
return wlan, False
time.sleep_ms(100)
return wlan, True
def wifi_down(wlan):
try:
wlan.disconnect()
except OSError:
pass
wlan.active(False)
wlan.deinit()
def publish(payload):
client = MQTTClient(
secrets.MQTT_CLIENT_ID,
secrets.MQTT_HOST,
port=secrets.MQTT_PORT,
user=secrets.MQTT_USER,
password=secrets.MQTT_PASSWORD,
keepalive=30,
)
client.connect()
# QoS 1: publish() bloqueia até o broker devolver o PUBACK
client.publish(secrets.TOPIC, payload, qos=1)
client.disconnect()
while True:
cycle += 1
vbat = read_vsys()
try:
temp_c, rh, hpa = read_sensor()
except OSError:
temp_c, rh, hpa = None, None, None
awake_start = time.ticks_ms()
wlan, ok = wifi_up()
if ok:
msg = json.dumps({
"t": temp_c, "rh": rh, "hpa": hpa,
"vbat": vbat, "cycle": cycle,
"rssi": wlan.status("rssi"),
"awake_ms": time.ticks_diff(time.ticks_ms(), awake_start),
})
try:
publish(msg)
except OSError as exc:
print("MQTT failed:", exc)
wifi_down(wlan)
# Recua mais quando a bateria está baixa para proteger as células
sleep_s = secrets.INTERVAL_S if vbat > 3.3 else secrets.INTERVAL_S * 3
machine.lightsleep(sleep_s * 1000)
Alguns detalhes são intencionais. O script informa awake_ms e rssi em cada mensagem, para que você veja, do lado do broker, se um nó está demorando demais para conectar. O ramo de bateria baixa triplica o intervalo em vez de parar de vez, o que dá tempo de trocar as pilhas sem perder o nó. E o deinit() após active(False) garante que o driver do CYW43 libere o rádio antes de a placa dormir.
Teste as mensagens MQTT do Pico W a bateria
Antes de rodar com pilhas, teste no USB com um intervalo curto, como 30 segundos. Faça a assinatura a partir do seu notebook:
mosquitto_sub -h broker.connectmq.com -p 1883 -i laptop-7f3a91 \
-t 'connectmq/demo/7f3a91/#' -v
Você deve ver uma mensagem JSON por ciclo. Observe o campo awake_ms. Em uma rede saudável ele se estabiliza em uma faixa estreita e repetível. Se variar muito, o problema é o access point, não o seu código.
Observe que, quando o Pico W dorme conectado ao USB, o REPL serial se desconecta. Isso é normal. Para retomar o controle, desconecte o cabo, segure o BOOTSEL se necessário ou use o mpremote logo após ligar a placa, antes de o main.py entrar no primeiro sono. Um truque útil é adicionar uma janela de dois segundos bem no início do main.py que sai para o REPL se um botão em um pino GPIO estiver pressionado.
Como extrair mais autonomia do Pico W
Quando o ciclo básico estiver funcionando, estes refinamentos dão o melhor retorno:
- Aumente o intervalo primeiro. Reduzir pela metade o número de despertares corta aproximadamente pela metade a energia do rádio, que é o maior consumidor.
- Agrupe leituras. Leia o sensor a cada minuto durante o lightsleep, guarde os valores em uma lista e publique todos em uma única mensagem a cada dez minutos. Você paga pelo Wi-Fi uma vez em vez de dez.
- Melhore o caminho do Wi-Fi. Posicione o nó onde o sinal for forte. Sinal fraco significa retransmissões, taxas de dados menores e mais tempo acordado.
- Use um timer de alimentação externo. Um chip timer que corta a energia da placa inteira e a religa conforme um agendamento elimina totalmente as correntes do regulador e de sono. Nesse projeto o script roda uma vez a partir do cold boot, publica e sinaliza ao timer para desligar. Você perde a RAM entre os ciclos, então grave contadores na flash com moderação ou deixe o broker guardar o estado por meio de retained messages.
- Desative tudo o que pisca. LEDs de status do Pico e das placas breakout dos sensores consomem corrente o tempo todo. Remova ou corte o LED de alimentação das breakouts quando possível.
Produção: migre para credenciais privadas e TLS
O servidor público é ideal para desenvolvimento, mas um sensor implantado deve usar suas próprias credenciais. Em um broker MQTT gerenciado como o ConnectMQ, você cria um broker no portal e recebe usuário, senha e client ID gerados. Coloque-os no secrets.py como YOUR_USERNAME, YOUR_PASSWORD e YOUR_CLIENT_ID. O client ID fica vinculado às credenciais emitidas, então cada nó precisa do que foi gerado para ele.
TLS na porta 8883 adiciona um handshake a cada despertar, o que custa tempo acordado extra e, portanto, bateria. Para sensores em uma rede doméstica confiável, algumas pessoas aceitam TCP puro; para qualquer coisa que saia do prédio, a criptografia vale o custo. O tutorial de MQTT sobre TLS com Pico W mostra a configuração do contexto SSL no MicroPython. Meça o awake_ms antes e depois para conhecer o impacto real no seu nó.
Retained messages também são úteis aqui. Se você publicar a última leitura com a flag retain, um dashboard aberto horas depois mostra o valor mais recente imediatamente, em vez de esperar até dez minutos pelo próximo despertar. O ConnectMQ suporta retained messages em todos os planos, e o dashboard do portal e o explorador de topics ao vivo permitem acompanhar as mensagens de cada nó chegando sem escrever um subscriber.
Solução de problemas
| Sintoma | Causa provável | Correção |
|---|---|---|
vbat perto de zero ou aleatório |
ADC lido com o Wi-Fi ativo | Leia o VSYS antes de wlan.active(True) |
| O nó publica uma vez e para | Wi-Fi não desinicializado antes do lightsleep | Chame active(False) e deinit() |
OSError: -2 ao conectar |
Falha de DNS ou Wi-Fi não totalmente ativo | Verifique isconnected() e tente de novo uma vez |
awake_ms não para de crescer |
Sinal fraco ou access point congestionado | Mova o nó ou o AP |
| A bateria acaba muito antes do esperado | LED, standby do sensor ou consumo do regulador | Remova LEDs, verifique o modo de sono do sensor, adicione um timer de alimentação |
Comece com o ConnectMQ
Quando o protótipo com Pico W estiver pronto para sair da bancada, crie um broker privado no portal do ConnectMQ em app.connectmq.com. O plano Serverless gratuito não exige cartão de crédito, suporta QoS 1 e até 25 conexões, o que cobre com folga uma pequena frota de sensores a bateria. Para mais projetos com Pi, o tutorial de MQTT com Raspberry Pi reúne a série completa.
Perguntas frequentes
Quanto tempo um Pico W dura com bateria usando MQTT?
Depende principalmente do intervalo de publicação, do tempo de conexão Wi-Fi e das pilhas usadas, então meça o seu próprio nó em vez de confiar em um número único. Registrar awake_ms e vbat por alguns dias dá uma tendência confiável para extrapolar.
O Pico W pode ficar conectado ao MQTT enquanto dorme?
Não de forma amigável à bateria. Manter a sessão MQTT ativa exige que o rádio continue associado, o que esgota as pilhas rapidamente, então reconecte a cada despertar.
Devo usar QoS 0 ou QoS 1 em um sensor a bateria?
QoS 1 costuma ser a melhor escolha, porque publish() aguarda a confirmação do broker antes de você desligar o rádio. A ida e volta extra é pequena comparada ao custo de entrar no Wi-Fi.
machine.deepsleep é melhor que lightsleep no Pico W?
No port do MicroPython para o RP2040 a diferença é modesta, e o deepsleep reinicia a placa, então você perde o estado da RAM. Para a maior autonomia, um timer externo que corta totalmente a alimentação supera os dois.



