🛠 Publier une vignette et une image en MQTT
Objectifs
Combiner caméra + Wi-Fi : publier toutes les N secondes une vignette (image réduite encodée en base64) et les métadonnées sur un topic MQTT, vers un broker auto-hébergé.
Matériel
- Arduino Nicla Vision + réseau Wi-Fi 2,4 GHz + broker MQTT (ex. Mosquitto sur le LAN)
- Core ArduinoCore-mbed ; bibliothèque client MQTT type PubSubClient
- >
- Règle d'or MQTT : des messages petits. Une QVGA RGB565 complète (150 Kio) ne passe pas décemment ; réduire à une vignette 80×60 en niveaux de gris (4,8 Kio → ~6,4 Kio en base64).
Code complet
// Vignette base64 + metadonnees sur MQTT
#include <WiFi.h>
#include <PubSubClient.h>
#include "camera.h"
#include "gc2145.h"
GC2145 galaxyCore;
Camera cam(galaxyCore);
FrameBuffer fb;
WiFiClient net;
PubSubClient mqtt(net);
const char* SSID = "MON_RESEAU";
const char* PASS = "MON_MOT_DE_PASSE";
const char* BROKER = "192.168.1.50";
const int W = 80, H = 60; // vignette 80x60 gris
char b64[9000];
static const char T[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void toB64(const uint8_t* in, size_t n, char* out) {
size_t o = 0;
for (size_t i = 0; i < n; i += 3) {
uint32_t v = in[i] << 16 | (i + 1 < n ? in[i+1] << 8 : 0) | (i + 2 < n ? in[i+2] : 0);
out[o++] = T[(v >> 18) & 63]; out[o++] = T[(v >> 12) & 63];
out[o++] = i + 1 < n ? T[(v >> 6) & 63] : '=';
out[o++] = i + 2 < n ? T[v & 63] : '=';
}
out[o] = 0;
}
void setup {
Serial.begin(115200);
WiFi.begin(SSID, PASS);
while (WiFi.status != WL_CONNECTED) delay(300);
mqtt.setServer(BROKER, 1883);
while (!mqtt.connect("nicla-vision")) delay(500);
cam.begin(CAMERA_R320x240, CAMERA_RGB565, 10);
}
void loop {
if (!mqtt.connected) mqtt.connect("nicla-vision");
mqtt.loop;
if (cam.grabFrame(fb, 3000) == 0) {
static uint8_t thumb[4800];
uint16_t* px = (uint16_t*)fb.getBuffer;
for (int y = 0; y < H; y++) for (int x = 0; x < W; x++) {
uint16_t p = px[(y * 4 + 2) * 320 + (x * 4 + 2)]; // decimation /4
uint8_t r = (p >> 11) << 3, g = ((p >> 5) & 0x3F) << 2, b = (p & 0x1F) << 3;
thumb[y * W + x] = (uint8_t)((r * 77 + g * 151 + b * 28) >> 8);
}
toB64(thumb, sizeof thumb, b64);
mqtt.publish("nicla/vision/thumb", b64); // QoS 0
mqtt.publish("nicla/vision/status", "ok");
Serial.println(F("vignette publiee"));
}
delay(5000);
}
Vérification attendue
mosquitto_sub -t 'nicla/vision/#' montre un message toutes les 5 s ; décodé en base64 puis relu en 80×60 gris, il reproduit la scène. La LED ne clignote pas en erreur, le broker ne déconnecte pas (messages < 10 Kio).
Erreurs fréquentes
- Publier l'image entière : 150 Kio en base64 ≈ 200 Kio par message — le client MQTT et la RAM de tampon saturent ; toujours vignetter avant d'encoder.
- QoS 1 en rafale : les accusés de réception empilent les tampons réseau ; publier la vignette en QoS 0 et les métadonnées seules en QoS 1.
- Décimation qui crée du aliasing : prélever 1 pixel sur 4 sans filtre donne du fourmillement sur motifs fins ; acceptable pour de la vignette de contrôle.
- TLS ignoré : le port 1883 est en clair ; pour un réseau non maîtrisé, prévoir MQTT/TLS (18838) si la pile radio le permet.
- Empilement WiFi+PubSubClient non compilé : bug d'inclusion ou de mémoire ? Se rabattre sur MicroPython (umqtt.simple), confirmé disponible sur le port officiel de la carte.
Autres tutoriels pour cette carte
Exemples de code pour cette carte
led_rgb.inoArduinoimu_lsm6dsox.inoArduinotof_distance.inoArduinomicro_pdm.inoArduinocamera_capture.inoArduinowifi_scan.inoArduino