🛠 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

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

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

Autres tutoriels pour cette carte

Exemples de code pour cette carte

← Retour à la fiche 🛠 Tous les tutoriels