🛠 Publier capteurs et batterie en MQTT via une passerelle
Objectifs
Boucler un nœud capteur sur batterie qui publie température et niveau de batterie jusqu'à un courtier MQTT. Architecture imposée par le matériel : le Nicla (sans WiFi) tient le rôle de périphérique BLE avec un service personnalisé, la carte hôte MKR WiFi 1010 joue la passerelle BLE-vers-MQTT. Côté Nicla, l'API Nicla_System donne un niveau de batterie honnête lu sur les registres du chargeur BQ25120 (nicla::getBatteryVoltagePercentage, nicla::getCurrentBatteryVoltage), bien plus fiable qu'un simple diviseur de tension. C'est le schéma de référence des réseaux de capteurs sans fil au format Nicla décrit par Arduino Pro.
Matériel
- Nicla Sense ME (ABX00050) + batterie LiPo sur J4 (avec ou sans NTC selon la batterie :
nicla::setBatteryNTCEnabled(false)si absente) - MKR WiFi 1010 (ou Portenta C33) comme passerelle ; bibliothèques ArduinoBLE côté Nicla, WiFi101 + PubSubClient côté hôte
- Courtier MQTT accessible (broker local ou hébergé)
- >
Code complet
// 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);
}
}
Vérification attendue
mosquitto_sub -t 'maison/nicla1' affiche un JSON périodique avec le pourcentage de batterie lu sur le chargeur. La LED verte du Nicla signale l'alimentation ; avec nRF Connect on peut auditer les caractéristiques 2A19/2A6E entre deux publications. En déchargeant la LiPo, le pourcentage doit décroître régulièrement (recalibrer si la courbe semble plate, la tension d'une LiPo étant peu linéaire).
Erreurs fréquentes
- Publier à l'aveugle sans gérer les déconnexions : le BLE du Nicla dort, le WiFi de l'hôte tombe ; prévoir des boucles de reconnexion complètes avant de laisser le nœud seul en production.
- Oublier
BLE.pollcôté Nicla : les centrales lisent des valeurs figées ; même symptôme siBHY2.updateest absent. - Se fier à un pourcentage brut sans tenir compte de la charge :
nicla::getOperatingStatuset la tension de charge modifient la lecture ; afficher aussi la tension brute pour débugger. - Cadencer trop vite : 10 s côté Nicla et 30 s côté MQTT sont confortables pour une LiPo 200 mAh ; le datasheet donne 1,15 mA typique en publicité + une mesure par heure, chaque seconde de radio en plus se paie en autonomie.
- >
Autres tutoriels pour cette carte
Exemples de code pour cette carte
led_rgb.inoArduinoimu_bhi260.inoArduinorotation_fusion.inoArduinopression_bmp390.inoArduinonose_electronique.inoArduinoboussole_bmm150.inoArduino