Sensor BLE Low-Power com nRF54L15, ESP32 e MQTT

Monitoramento de temperatura e umidade com Zephyr, BLE advertising, gateway ESP32 e dashboard MQTT

Resumo

Este documento apresenta o projeto LowBLE, uma arquitetura didática de baixo consumo para aquisição de temperatura e umidade com um sensor DHT11 alimentado por GPIO em uma placa Nordic nRF54L15 DK. O firmware do nó sensor roda sobre Zephyr, empacota os dados em um payload binário compacto e transmite as amostras por BLE advertising legado. Um gateway ESP32 escaneia os anúncios BLE, valida o payload, calcula perdas de pacote pelo contador da amostra e publica telemetria JSON em um broker MQTT. Por fim, um dashboard local consome os tópicos MQTT via servidor Python e apresenta os dados para acompanhamento em tempo real.

O foco do projeto é demonstrar uma cadeia de ponta a ponta de IoT embarcada com baixo consumo: sensor, rádio BLE, gateway, MQTT e interface de monitoramento. A implementação também deixa pontos claros para evolução, como medição real de bateria, múltiplos sensores, armazenamento histórico, alertas e ajuste fino dos intervalos de amostragem.

Introdução

Aplicações IoT alimentadas por bateria precisam reduzir o tempo ativo de sensores, rádio e CPU. Em muitos casos, o dispositivo não precisa manter conexão BLE, GATT, pareamento ou canal bidirecional. Quando a aplicação exige apenas telemetria periódica, BLE advertising legado é uma alternativa simples: o nó sensor acorda, lê o sensor, transmite um pacote curto por uma janela controlada e volta para o período de espera.

No LowBLE, o payload de aplicação possui 14 bytes e é colocado dentro do campo manufacturer data do advertising. O gateway ESP32 filtra os pacotes por company ID e device ID, valida o checksum e transforma o dado binário em JSON para MQTT. Assim, o nó sensor permanece simples e energeticamente eficiente, enquanto o gateway assume a parte de conectividade Wi-Fi, TLS, autenticação MQTT e integração com a interface.

Objetivos do projeto

  • Criar um nó sensor BLE de baixo consumo usando Nordic nRF54L15 DK e Zephyr.
  • Ler a temperatura e umidade de um DHT11 alimentado por GPIO para permitir power cycling.
  • Transmitir um payload binário compacto por BLE advertising manufacturer data.
  • Usar um ESP32 como gateway BLE-to-MQTT com validação de checksum e estimativa de perda de pacotes.
  • Publicar telemetria em HiveMQ Cloud, ou broker MQTT compatível, usando tópicos organizados por device ID.
  • Exibir os dados em um dashboard local responsivo, sem expor credenciais MQTT ao navegador.
  • Documentar pontos de teste, build, operação e troubleshooting para reprodução do projeto.

Arquitetura geral

A arquitetura é dividida em três projetos independentes: firmware do nó BLE, firmware do gateway ESP32 e dashboard MQTT. Essa separação facilita testes isolados: o payload pode ser validado no gateway, a conectividade MQTT pode ser testada sem alterar o sensor e a interface web pode ser executada localmente recebendo eventos por Server-Sent Events.

Figura 1 – Fluxo de dados entre nó BLE, gateway ESP32, broker MQTT e dashboard

  1. O nRF54L15 DK liga o DHT11 quando o perfil ativo exige power cycling do sensor.
  2. O firmware aguarda estabilização, lê o frame de 40 bits do DHT11 e valida o checksum nativo do sensor.
  3. Os valores são convertidos para ponto fixo em escala x10 e inseridos em sensor_payload_t.
  4. O firmware calcula o checksum da aplicação e inicia advertising BLE legado não conectável.
  5. O ESP32 escaneia anúncios BLE, filtra manufacturer data, valida checksum e extrai a telemetria.
  6. O gateway publica JSON no tópico MQTT configurado.
  7. O dashboard recebe os eventos do servidor Python e atualiza a interface em tempo real.

Hardware do nó sensor

O nó sensor usa a placa Nordic nRF54L15 DK, núcleo de aplicação, e um DHT11. O DHT11 deve ser alimentado por VDDIO/3,3 V. Não se deve alimentar o módulo em 5 V neste projeto, pois os níveis de sinal devem permanecer compatíveis com a placa Nordic.

SinalLigaçãoObservação
VCCGPIO configurado como power-gpiosPermite ligar/desligar o sensor por firmware
DATAGPIO configurado como data-gpiosEntrada com pull-up; adicionar 4,7 k ou 10 k se o módulo não tiver pull-up
GNDGND da placaReferência comum com o nRF54L15 DK
TensãoVDDIO / 3,3 VNão usar 5 V
Tabela 1 – Ligações iniciais do DHT11

No overlay inicial, os pinos foram definidos como gpio1 10 para alimentação do DHT11 e gpio1 11 para DATA com GPIO_PULL_UP. Esses pinos devem ser conferidos no conector físico usado na nRF54L15 DK antes de ligar o hardware.

Observação: Como o DHT11 normalmente opera em 3,3 V ou 5 V, o pino DATA não deve ser conectado diretamente ao GPIO do nRF54L15 enquanto o rail de GPIO estiver em 1,8 V. Para usar o DHT11 diretamente, é necessário ajustar o nível dos GPIOs para 3,3 V usando o Nordic Board Configurator e confirmar a tensão com multímetro antes da ligação. Caso o rail permaneça em 1,8 V, deve ser usado um conversor de nível lógico bidirecional entre o DATA do DHT11 e o GPIO do nRF54L15.

Figura 2 – Ligação do DHT11 na nRF54L15 DK

Firmware Zephyr no nRF54L15

O firmware do nó sensor foi organizado em módulos pequenos para isolar responsabilidades: leitura do DHT11, codificação de payload, advertising BLE, simulação de bateria e seleção de perfil de energia. Essa divisão facilita a troca de sensor, ajuste de payload e medição separada do consumo de cada etapa.

.
|-- CMakeLists.txt
|-- Kconfig
|-- prj.conf
|-- boards/
|   `-- nrf54l15dk_nrf54l15_cpuapp.overlay
|-- include/
|   |-- battery_sim.h
|   |-- ble_adv.h
|   |-- dht11.h
|   |-- payload_codec.h
|   `-- power_profile.h
`-- src/
    |-- battery_sim.c
    |-- ble_adv.c
    |-- dht11.c
    |-- main.c
    |-- payload_codec.c
    `-- power_profile.c

Payload BLE

O payload de aplicação tem 14 bytes e é colocado após o company ID de 2 bytes dentro do manufacturer data. Os campos multibyte são transmitidos em little-endian. Temperatura e umidade usam escala x10 para evitar float no pacote BLE e manter o parser simples no gateway.

typedef struct __attribute__((packed)) {
    uint16_t device_id;
    int16_t temperature_x10;
    uint16_t humidity_x10;
    uint16_t battery_mv;
    uint32_t counter;
    uint8_t flags;
    uint8_t checksum;
} sensor_payload_t;

O checksum de aplicação e a soma de todos os bytes anteriores do payload, truncada para 8 bits:

checksum = sum(payload_bytes_without_checksum) & 0xff;
CampoTamanhoDescrição
device_id2 bytesIdentificador lógico do dispositivo
temperature_x102 bytesTemperatura em graus Celsius multiplicada por 10
humidity_x102 bytesUmidade relativa em porcentagem multiplicada por 10
battery_mv2 bytesTensão de bateria em milivolts; na V1 pode ser simulada
counter4 bytesContador sequencial de pacotes usado para estimar perdas
flags1 byteEstado do sensor, bateria simulada, modo eco e erro DHT
checksum1 byteSoma truncada dos bytes anteriores do payload
Tabela 2 – Campos do payload de aplicação

FlagSignificado
FLAG_SENSOR_OKLeitura válida do DHT11
FLAG_BATTERY_SIMValor de bateria simulado
FLAG_LOW_POWER_MODEPerfil eco ativo
FLAG_DHT_ERRORTimeout ou erro de checksum na leitura do DHT11
Tabela 3 – Bits de flags

O valor default CONFIG_LOWB_COMPANY_ID e 0xffff e deve ser tratado apenas como identificador de protótipo. Para produto real, o correto é substituir por um Bluetooth SIG Company Identifier atribuído.

Perfis de operação

O comportamento do firmware é selecionado por Kconfig. O prj.conf do projeto usa o modo eco como padrão, priorizando menor tempo de rádio e power cycling do DHT11 a cada amostra.

PerfilIntervalo de transmissãoJanela BLEAlimentação do DHT11
DEMO2 s1200 msMantido ligado
BALANCED10 s800 msPower-cycled por amostra
ECO60 s350 msPower-cycled por amostra
Tabela 4 – Perfis de energia
CONFIG_LOWB_PROFILE_DEMO=y
CONFIG_LOWB_PROFILE_BALANCED=y
CONFIG_LOWB_PROFILE_ECO=y

Somente um símbolo CONFIG_LOWB_PROFILE_* deve ficar ativo por build. Para mudar o perfil, edite o prj.conf ou use um overlay de configuração contendo exatamente um perfil.

Build e flash do nó BLE

Com Zephyr/NCS configurado, o build principal usa o board target novo da nRF54L15 DK:

west build -b nrf54l15dk/nrf54l15/cpuapp .<br><br>west flash

Se o ambiente ainda usar o nome antigo da placa, tente:

west build -b nrf54l15dk_nrf54l15_cpuapp .

Gateway ESP32 BLE-to-MQTT

O gateway ESP32 converte a rede BLE local em telemetria MQTT. Ele não precisa parear com o sensor, pois apenas escaneia anúncios legados BLE. O firmware filtra os pacotes pela combinação de company ID e device ID, valida o checksum de aplicação e calcula a perda de pacotes observando saltos no campo counter.

FunçãoDescrição
BLE scanEscaneia anúncios BLE legados e acessa manufacturer data
FiltroConfere company ID e target device ID configurados
ParserDecodifica o payload little-endian de 14 bytes
IntegridadeValida checksum e indica checksum_valid no JSON
Perda de pacotesCalcula packet_loss_delta e packet_loss_total pelo counter
MQTTPublica telemetria JSON no broker configurado
PortalFornece AP de configuração quando não há credenciais válidas
OTAAceita upload de firmware pela interface de configuração
Tabela 5 – Responsabilidades do gateway

Build do firmware ESP32

O projeto foi preparado para ESP-IDF com suporte a ESP32. Para ESP32, o fluxo de build e flash é:

idf.py set-target esp32
idf.py build
idf.py -p /dev/ttyUSB0 flash monitor

A porta serial deve ser ajustada conforme o host. A tabela de partições incluída no projeto considera módulos ESP32 com 4 MB de flash e suporte a OTA. O layout não possui partição factory; ele usa duas partições de aplicação OTA, ota_0 e ota_1, cada uma com 1920K. Portanto, o binário final gerado pelo ESP-IDF deve caber dentro desse limite.

Configuração privada e portal AP

O firmware pode carregar defaults locais a partir de config/default_config.h quando ainda não existe configuração salva na NVS. Esse arquivo deve ficar fora do git porque contém Wi-Fi, MQTT e parâmetros privados. A partir do exemplo versionado:

cp config/default_config.example.h config/default_config.h

Se a configuração salva estiver ausente ou inválida, ou se a conexão Wi-Fi não for estabelecida em até 30 segundos, o gateway abre um AP de configuração.

ItemValor / Função
SSIDESP32-Gateway-Setup
URLhttp://192.168.4.1/
Wi-FiSSID e senha
MQTTHost, porta, usuário, senha, TLS, client ID e base topic
BLECompany ID e target device ID
ResetBotão no portal ou GPIO0 baixo durante boot para apagar configuração
Tabela 6 – Portal de configuração do gateway
Figura 3 – Portal AP do gateway ESP32

OTA

O portal de configuração inclui campo para upload de firmware. O arquivo normalmente gerado pelo ESP-IDF fica em:

build/esp32_ble_mqtt_gateway.bin

O endpoint de upload grava a imagem pelas APIs OTA do ESP-IDF, valida o binário, define a próxima partição de boot e reinicia em caso de sucesso. Esse recurso é útil para atualizar o gateway sem abrir o gabinete ou depender de cabo serial durante testes de campo.

MQTT e schema JSON

O gateway publica a telemetria no tópico baseado em base_topic e device_id. Com base_topic igual a lowbie e device_id igual a 1, o tópico final e:

lowble/1/telemetry

HiveMQ Cloud normalmente usa TLS na porta 8883 com usuário e senha. No ESP-IDF, o modo TLS usa o certificate bundle do framework.

{
  "device_id": 1,
  "temperature_c": 24.7,
  "humidity_percent": 53.2,
  "battery_mv": 3010,
  "counter": 42,
  "flags": 1,
  "sensor_ok": true,
  "dht_error": false,
  "low_power_mode": false,
  "battery_simulated": false,
  "rssi": -63,
  "packet_loss_total": 0,
  "packet_loss_delta": 0,
  "checksum_valid": true,
  "timestamp_ms": 123456
}
CampoUso no dashboard
temperature_cExibir temperatura em graus Celsius
humidity_percentExibir umidade relativa
battery_mvAcompanhar tensão ou simulação de bateria
counterVerificar sequência de pacotes
rssiAvaliar a qualidade aproximada do enlace BLE
packet_loss_totalAcumulado de pacotes perdidos estimados
checksum_validIndicador de integridade do payload
sensor_ok / dht_errorDiagnóstico da leitura DHT11
Tabela 7 – Campos principais publicados em JSON

Dashboard MQTT local

O dashboard local é executado por um servidor Python. Ele assina lowble e lowble/# no broker MQTT usando TLS na porta 8883 e encaminha eventos para o navegador via SSE. Assim, o browser não precisa conhecer credenciais MQTT nem abrir conexão direta com o broker.

python3 server.py

# Abrir no navegador:
http://127.0.0.1:8080

As credenciais locais ficam em config.local.json, arquivo ignorado pelo git. Também é possível sobrescrever as configurações por variáveis de ambiente:

MQTT_HOST=host MQTT_USERNAME=user MQTT_PASSWORD=pass python3 server.py
Figura 5 – Dashboard local recebendo telemetria MQTT

Limitações da versão V1

  • Não há GATT, pareamento, bonding ou BLE Long Range.
  • A bateria pode ser simulada; medição real exige circuito e ADC adequados.
  • O DHT11 tem precisão e taxa de atualização limitadas; sensores como SHT3x, BME280 ou AHT20 podem melhorar a qualidade dos dados.
  • O company ID 0xffff é apenas para prototipagem e não deve ser usado em produto final.
  • O dashboard local não substitui uma plataforma histórica completa; para produção, adicionar banco de dados, retenção e alertas.

Estimativa de consumo

Para estimar o consumo do nó BLE, foi utilizado o Nordic Online Power Profiler for Bluetooth LE, configurado com o chip nRF54L15, alimentação de 3,0 V, regulador DCDC habilitado, clock externo, potência de transmissão em 0 dBm e modo Advertising TX only.
No cenário simulado, o intervalo de advertising foi configurado em aproximadamente 100 ms, com taxa de transmissão de 1 Mbps. A ferramenta estimou uma carga total por evento BLE de 3,15 µC, corrente em idle de 3,0 µA e corrente média total de aproximadamente 33 µA.

Figura 6 – Estimativa de consumo do nó BLE no Nordic Online Power Profiler.

Com uma bateria tipo CR2032, considerando uma capacidade nominal aproximada de 220 mAh, é possível estimar a autonomia teórica do nó sensor a partir da corrente média obtida na simulação:

Autonomia = Capacidade da bateria / Corrente média
Autonomia = 220 mAh / 0,033 mA
Autonomia ≈ 6666 h
Autonomia ≈ 278 dias

Portanto, para esse cenário de simulação, a autonomia estimada fica em torno de 278 dias, ou aproximadamente 9 meses. Esse primeiro valor considera apenas a corrente média estimada pela ferramenta no cenário de advertising BLE. Ele é útil para avaliar o impacto do rádio, mas não representa sozinho o consumo completo do nó sensor, pois não inclui a corrente consumida pelo DHT11, o tempo de estabilização do sensor, a leitura do frame de dados, o processamento pela CPU e possíveis perdas no circuito de alimentação.

Para aproximar melhor o comportamento real do nó, também foi feita uma segunda estimativa incluindo as principais etapas do ciclo de amostragem. No perfil ECO, considera-se um intervalo de transmissão de 60 s e uma janela BLE de 350 ms. Como o advertising interval usado na simulação é de aproximadamente 100 ms, a janela de 350 ms pode conter cerca de quatro eventos BLE.

A carga consumida pelo BLE em cada ciclo pode ser estimada por:

Q_BLE = 4 × 3,15 µC
Q_BLE = 12,6 µC

Para incluir o sensor, foi considerado um cenário conservador com o DHT11 ligado por 1,2 s durante a estabilização e leitura, consumindo aproximadamente 2,5 mA. Também foi considerado um período de CPU ativa de 100 ms, com corrente aproximada de 3,0 mA, além da corrente em idle de 3,0 µA estimada pela ferramenta.

A carga consumida pelo DHT11 em cada ciclo é:

Q_DHT11 = I_DHT11 × t_DHT11
Q_DHT11 = 2,5 mA × 1,2 s
Q_DHT11 = 3000 µC

A carga consumida pela CPU ativa é:

Q_CPU = I_CPU × t_CPU
Q_CPU = 3,0 mA × 0,1 s
Q_CPU = 300 µC

O tempo restante em idle é:

t_idle = 60 s – 1,2 s – 0,1 s – 0,35 s
t_idle = 58,35 s

A carga consumida em idle é:

Q_idle = I_idle × t_idle
Q_idle = 3,0 µA × 58,35 s
Q_idle = 175,05 µC

Somando as principais etapas do ciclo:

Q_total = Q_DHT11 + Q_CPU + Q_BLE + Q_idle
Q_total = 3000 µC + 300 µC + 12,6 µC + 175,05 µC
Q_total = 3487,65 µC

A corrente média estimada para o ciclo completo é:

I_média = Q_total / T_intervalo
I_média = 3487,65 µC / 60 s
I_média ≈ 0,058 mA

Com essa corrente média, a autonomia teórica passa a ser:

Autonomia = Capacidade da bateria / Corrente média
Autonomia = 220 mAh / 0,058 mA
Autonomia ≈ 3793 h
Autonomia ≈ 158 dias

Assim, considerando BLE advertising, DHT11, CPU ativa e idle, a autonomia estimada fica em torno de 158 dias, ou aproximadamente 5 meses. Esse valor é menor que a estimativa inicial de 278 dias porque inclui etapas que não estavam representadas diretamente na simulação do rádio, principalmente o tempo em que o DHT11 permanece alimentado.

Esse valor deve ser entendido como uma estimativa teórica. Na prática, a autonomia pode variar de acordo com fatores como capacidade real da bateria, temperatura ambiente, envelhecimento da célula, corrente consumida pelo sensor, perdas no circuito, tempo de estabilização do DHT11 e consumo adicional durante leituras ou estados ativos do firmware.

A comparação entre as duas estimativas também mostra que o consumo do sensor pode ter impacto maior do que o próprio evento BLE. No cenário adotado, o BLE consome cerca de 12,6 µC por ciclo, enquanto o DHT11 consome aproximadamente 3000 µC. Portanto, reduzir o tempo em que o sensor permanece ligado é uma das principais estratégias para aumentar a autonomia.

Essa análise reforça a importância da escolha do perfil de operação. Quanto maior o intervalo entre transmissões e menor a janela ativa de advertising, menor tende a ser a corrente média do sistema. Para aplicações em que temperatura e umidade variam lentamente, como salas técnicas, depósitos, painéis elétricos e ambientes de armazenamento, o perfil ECO é o mais adequado, pois prioriza autonomia em vez de atualização em tempo real.

Código completo, demonstração e contribuições

O projeto foi separado em repositórios ou pastas independentes para facilitar a manutenção: firmware Zephyr do no nRF54L15, firmware ESP32 BLE-to-MQTT e dashboard MQTT. O código completo, arquivos de configuração, overlays, exemplos e instruções de build estão disponíveis no GitHub.

GitHub: https://github.com/Silvio347/ble-low-energy-zephyr-iot/

Vídeo de demonstração

Conclusão

O LowBLE demonstra uma arquitetura simples e robusta para telemetria ambiental de baixo consumo. A escolha por BLE advertising reduz a complexidade do nó sensor e elimina a necessidade de conexão permanente. Já o gateway ESP32 concentra as tarefas mais pesadas, como Wi-Fi, TLS, MQTT, portal de configuração e OTA.

Essa divisão torna o projeto adequado tanto para fins didáticos quanto para aplicações reais, como monitoramento de temperatura e umidade em salas técnicas, painéis elétricos, almoxarifados, estufas, rastreamento logístico e ambientes de armazenamento. O sensor envia um pacote binário curto, o gateway transforma esse pacote em informação legível e o dashboard apresenta o estado do sistema.

A principal vantagem do projeto é evidenciar a fronteira entre firmware de baixo consumo e integração IoT. Com isso, a solução se torna modular, fácil de demonstrar e pronta para evoluir para múltiplos dispositivos, histórico de dados, alarmes e análises de consumo mais detalhadas.

Referências

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Inscrever-se
Notificar de
0 Comentários
mais recentes
mais antigos Mais votado
Home » Internet Das Coisas » Sensor BLE Low-Power com nRF54L15, ESP32 e MQTT

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste: