🛠 Publier une vignette et une image en MQTT
Objetivos
Combinar cámara + Wi-Fi: publicar cada N segundos una miniatura (imagen reducida codificada en base64) y los metadatos en un topic MQTT, hacia un broker autoalojado.
Material
- Arduino Nicla Vision + red Wi-Fi 2,4 GHz + broker MQTT (p. ej. Mosquitto en la LAN)
- Core ArduinoCore-mbed; biblioteca cliente MQTT tipo PubSubClient
- >
- Regla de oro MQTT: mensajes pequeños. Una imagen QVGA RGB565 completa (150 KiB) no pasa decentemente; reducir a una miniatura de 80×60 en niveles de gris (4,8 KiB → ~6,4 KiB en base64).
Código completo
// 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);
}
Verificación esperada
mosquitto_sub -t 'nicla/vision/#' muestra un mensaje cada 5 s; decodificado en base64 y releído en 80×60 gris, reproduce la escena. El LED no parpadea en error, el broker no desconecta (mensajes < 10 KiB).
Errores frecuentes
- Publicar la imagen entera: 150 KiB en base64 ≈ 200 KiB por mensaje — el cliente MQTT y la RAM de búfer se saturan; siempre reducir a miniatura antes de codificar.
- QoS 1 en ráfaga: los acuses de recibo apilan los búferes de red; publicar la miniatura en QoS 0 y solo los metadatos en QoS 1.
- Diezmado que crea aliasing: tomar 1 píxel de cada 4 sin filtro produce parpadeo en patrones finos; aceptable para una miniatura de control.
- TLS ignorado: el puerto 1883 es en claro; para una red no controlada, prever MQTT/TLS (18838) si la pila de radio lo permite.
- Pila WiFi+PubSubClient no compilada: ¿bug de inclusión o de memoria? Recurrir a MicroPython (umqtt.simple), confirmado disponible en el port oficial de la placa.
Otros tutoriales para esta placa
Ejemplos de código para esta placa
led_rgb.inoArduinoimu_lsm6dsox.inoArduinotof_distance.inoArduinomicro_pdm.inoArduinocamera_capture.inoArduinowifi_scan.inoArduino