🛠 Publier une vignette et une image en MQTT
Objectives
Combine camera + Wi-Fi: publish a thumbnail (downscaled image encoded in base64) and metadata to an MQTT topic every N seconds, targeting a self-hosted broker.
Hardware
- Arduino Nicla Vision + 2.4 GHz Wi-Fi network + MQTT broker (e.g., Mosquitto on the LAN)
- ArduinoCore-mbed core; MQTT client library such as PubSubClient
- >
- MQTT golden rule: keep messages small. A full QVGA RGB565 image (150 KiB) does not pass decently; reduce it to an 80×60 grayscale thumbnail (4.8 KiB → ~6.4 KiB in base64).
Complete code
// 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);
}
Expected verification
mosquitto_sub -t 'nicla/vision/#' shows a message every 5 s; decoded from base64 and read back as 80×60 grayscale, it reproduces the scene. The LED does not blink an error, and the broker does not disconnect (messages < 10 KiB).
Common errors
- Publishing the full image: 150 KiB in base64 ≈ 200 KiB per message — the MQTT client and buffer RAM saturate; always downscale before encoding.
- QoS 1 in bursts: acknowledgments pile up network buffers; publish the thumbnail with QoS 0 and only the metadata with QoS 1.
- Decimation causing aliasing: sampling 1 pixel out of 4 without a filter results in flickering on fine patterns; acceptable for a control thumbnail.
- Ignoring TLS: port 1883 is unencrypted; for an untrusted network, plan for MQTT/TLS (18838) if the radio stack allows it.
- WiFi+PubSubClient stack not compiled: inclusion or memory bug? Fall back to MicroPython (umqtt.simple), confirmed available on the board's official port.
Other tutorials for this board
Code examples for this board
led_rgb.inoArduinoimu_lsm6dsox.inoArduinotof_distance.inoArduinomicro_pdm.inoArduinocamera_capture.inoArduinowifi_scan.inoArduino