🛠 Publier capteurs et batterie en MQTT via une passerelle

Arduino Nicla Sense ME · avance · Schéma : IMG-nicla-sense-me-avance-3-niclasense-mqtt-batterie.svg — Chaîne complète : Nicla Sense ME sur batterie publiant en BLE, MKR WiFi 1010 en passerelle, flux MQTT pointillé vers un courtier sur un serveur, jauge de batterie affichée sur un téléphone

Objectives

Build a battery-powered sensor node that publishes temperature and battery level to an MQTT broker. The hardware architecture is fixed: the Nicla (no WiFi) acts as a BLE peripheral with a custom service, while the MKR WiFi 1010 host board serves as the BLE-to-MQTT gateway. On the Nicla side, the Nicla_System API provides an accurate battery level read from the BQ25120 charger registers (nicla::getBatteryVoltagePercentage, nicla::getCurrentBatteryVoltage), which is much more reliable than a simple voltage divider. This is the reference schema for Nicla-format wireless sensor networks as described by Arduino Pro.

Hardware

Complete Code

// Sketch NICLA : peripheral BLE batterie + temperature
#include "Nicla_System.h"
#include "Arduino_BHY2.h"
#include <ArduinoBLE.h>

Sensor temp(SENSOR_ID_TEMP);
BLEService batteryService("180F");
BLEUnsignedCharCharacteristic battLevel("2A19", BLERead | BLENotify);
BLEFloatCharacteristic tempChar("2A6E", BLERead | BLENotify);

void setup {
  Serial.begin(9600);
  nicla::begin;
  nicla::setBatteryNTCEnabled(false);
  nicla::leds.begin;
  nicla::leds.setColor(green);
  BHY2.begin;
  temp.begin;
  if (!BLE.begin) { while (1); }
  BLE.setLocalName("NiclaNode");
  BLE.setAdvertisedService(batteryService);
  batteryService.addCharacteristic(battLevel);
  batteryService.addCharacteristic(tempChar);
  BLE.addService(batteryService);
  BLE.advertise;
}

void loop {
  static auto t = millis;
  BHY2.update;
  BLE.poll;
  if (millis - t >= 10000) {
    t = millis;
    battLevel.writeValue((unsigned char)nicla::getBatteryVoltagePercentage);
    if (temp.dataAvailable) tempChar.writeValue(temp.value);
  }
}
// Sketch HOTE (MKR WiFi 1010) : passerelle BLE -> MQTT
#include <WiFi101.h>
#include <PubSubClient.h>

WiFiClient net;
PubSubClient mqtt(net);
BLEDevice node;

void setup {
  WiFi.begin("MON_WIFI", "MON_MOT_DE_PASSE");
  mqtt.setServer("192.168.1.40", 1883);
  BLE.begin;
  BLE.setScanTimeout(5000);
  node = BLE.scanForName("NiclaNode");
  while (!node) { node = BLE.scanForName("NiclaNode"); }
  node.connect;
  mqtt.connect("nicla-gateway");
}

void loop {
  if (!node.connected || !mqtt.connected) { return; } // reconnexion a gerer
  BLE.poll;
  static auto t = millis;
  if (millis - t >= 30000) {
    t = millis;
    unsigned char batt = node.characteristic("2A19").readValue;
    char payload[96];
    snprintf(payload, sizeof(payload), "{\"batt_pct\":%u}", batt);
    mqtt.publish("maison/nicla1", payload);
  }
}

Expected Verification

mosquitto_sub -t 'maison/nicla1' displays periodic JSON containing the battery percentage read from the charger. The green LED on the Nicla indicates power; using nRF Connect, you can audit the 2A19/2A6E characteristics between publications. As the LiPo discharges, the percentage should decrease regularly (recalibrate if the curve appears flat, as LiPo voltage is not very linear).

Common Errors

Other tutorials for this board

Code examples for this board

← Back to the board 🛠 All tutorials