Schauen wir erstmal auf die…
Adafruit MQTT Library
QoS konfigurieren
Da hier der Adafruit_MQTT_Publish
er verwendet wird, könnte man einmal folgendes versuchen, um die Situation zu verbessern:
// Let's get real.
#define MQTT_QOS 1
// Setup MQTT publishing handler.
Adafruit_MQTT_Publish mqtt_publisher = Adafruit_MQTT_Publish(&mqtt, MQTT_TOPIC, MQTT_QOS);
Unter der Haube I
Ich bin gespannt, wie dabei das Laufzeitverhalten im Erfolgs- bzw. v.a. im Fehlerfall auf dem ESP8266 aussieht bzw. ob das einfach so tut. Der Code von Adafruit_MQTT::publish(...)
sieht aber schonmal gut aus: Wenn dort im Falle von qos > 0
der Ruf nach
readFullPacket(buffer, MAXBUFFERSIZE, PUBLISH_TIMEOUT_MS);
so lange blockierend wartet wie über PUBLISH_TIMEOUT_MS
angegeben wird, dann sollte man summa summarum über
if (mqtt_publisher.publish(payload)) {
Serial.println("mqtt: success");
} else {
Serial.println("mqtt: error or timeout");
}
hoffentlich zuverlässigere Ergebnisse bekommen, was erfolgreiche Übertragungen und deren Bestätigungen angeht.
P.S.: Dies ist der voreingestellte Wert für PUBLISH_TIMEOUT_MS
, der aber selbstverständlich jederzeit verändert werden können sollte:
Unter der Haube II
Der Code von Adafruit_MQTT_Client::readPacket(...)
pollt im Intervall MQTT_CLIENT_READINTERVAL_MS
nach neuen Daten bis der Timeout erreicht ist. Hier wird also wie erwartet blockierend auf die PUBACK
Antwort des MQTT Brokers gewartet.
Auch dieser Wert könnte ggf. angepasst werden.
Fazit
Das sieht vom Code her anständig aus. Nebenläufigkeit im userspace code kann dadurch zwar vermutlich nicht erzielt werden, da die Funktion delay(MQTT_CLIENT_READINTERVAL_MS);
aus Sicht des Sketchs blockiert…
delay(ms)
pauses the sketch for a given number of milliseconds and allows WiFi, TCP/IP [and other] tasks to run.
– ESP8266 Arduino Core Reference: Timing and delays
… aber für unsere bescheidenen Anwendungen müsste das in Ordnung sein.