Home › Forums › Mayfly Data Logger › DigiXBeeWifi class mqtt codeflow example
- This topic has 4 replies, 2 voices, and was last updated 2026-03-20 at 2:35 PM by
Sabin.
-
AuthorPosts
-
-
2026-03-20 at 12:57 PM #19620
I am trying to make mayfly work as publisher, send data to broker running on raspberry pi. I am using Xbee s6b wifi modem.
While using this class to create client that I could pass into pubsub or arduinomqtt as constructor variable. But, DigiXbeeWifi class would always reset my DL to 0.0.0.0 which I set using xctu to correct broker address and therefore couldn’t be connected.
Are there any good working example of this? -
2026-03-20 at 1:26 PM #19621
Ooooh.. yup, there’s a bug in DigiXBeeWifi.cpp. I’ll look into it.
Exactly which version of the library are you using (release, master branch, develop branch)?
For now, you may be able to get it working by commenting out lines ~303-310 in src/modems/DigiXBeeWifi.cpp, the section starting with “set the destination IP to 0”
-
2026-03-20 at 1:45 PM #19622
Thank you for your response.
I think it’s the master branch.Also, this is what I am trying to do.
DigiXBeeWifi modemXBWF(&Serial1, powerPin, statusPin, false,
modemResetPin, modemSleepRqPin,
ssid, pwd, false);Client* netClient = nullptr;
MqttClient* mqttClient = nullptr;void setup() {
Serial.begin(9600);
Serial1.begin(9600);
delay(2000);if (!modemXBWF.connectInternet(60000L)) {
Serial.println(“WiFi failed!”);
return;
}
Serial.println(“WiFi connected!”);delay(1200);
netClient = modemXBWF.createClient();
mqttClient = new MqttClient(*netClient);<div>Somehow this code is called. bool DigiXBeeWifi::extraModemSetup(void). I don’t know which line does this. So the broker connection fails.
I have used this workaround by implementing the Client with just a fake abstract wrapper and preconnect xbee s6b with xctu…
class XBeeTransparentClient : public Client {
public:
XBeeTransparentClient(Stream& s) : _stream(s) {}int connect(IPAddress ip, uint16_t port) override { return 1; }
int connect(const char* host, uint16_t port) override { return 1; }
void stop() override {}
uint8_t connected() override { return 1; }
operator bool() override { return true; }size_t write(uint8_t b) override { return _stream.write(b); }
size_t write(const uint8_t* buf, size_t size) override { return _stream.write(buf, size); }
int available() override { return _stream.available(); }
int read() override { return _stream.read(); }
int read(uint8_t* buf, size_t size) override { return _stream.readBytes(buf, size); }
int peek() override { return _stream.peek(); }
void flush() override {}private:
Stream& _stream;
};</div>
-
2026-03-20 at 2:23 PM #19623
Are you using anything else from the Modular Sensors library? Post your entire sketch as code (use the <> button to post as code)? Are you setting the host and port for the mqttClient? (
mqttClient.setServer(ip, port)) Use your local IP there. If you do that, I don’t see why you’re not getting a connection even with the bad DL setting in the extraModemSetup function. The correct DL should be set by PubSubClient when it connects because it will call client.connect(ip, port) on the client created bymodemXBWF.createClient();That client is a TinyGSM object which should properly set DL using XBee command mode.If you don’t need the power on/power off via pins that are in the DigiXBeeWifi class, use a TinyGSMModem/TinyGSMClient object directly. There’s no need for that fake client thing. TinyGSM does all the work of converting the xBee into a client and provides you with the functions to connect to the network and a host so you don’t need XCTU.
The reason the extraModemSetup forces DL to 0.0.0.0 is to force the Bee to grab a new IP address each time. Doing that means that you *can’t* use XCTU – which is the “bug.” But the reason that’s done is that the WiFi bee tends to get stuck thinking it has an open socket to an IP address if it has one in memory – even if the module isn’t connected to the internet. Sorry, it took me a bit of thinking to remember why that was done. This is not a bug that should be fixed.
If you’re going to leave your Mayfly and XBee fully powered the whole time you program is running and you’re confident that your never going to lose the internet or socket connection and you’re comfortable with XCTU, then you may be fine with your faked client.
-
2026-03-20 at 2:35 PM #19624
Thank you for your response.
I used TinyGSM directly and got into this problem. I was deploying broker locally,, the code on the inside check for dns lookup.. Currently I commented this code out and tinygsm works.
https://github.com/issues/created?issue=vshymanskyy%7CTinyGSM%7C854This is what my full code looks without tinygsm:
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131#define XBEE_PWR 18#define XBEE_SERIAL Serial1#include <ModularSensors.h>#include <modems/DigiXBeeWifi.h>#include <ArduinoMqttClient.h>// the broker id doesn't matter as client is already connected to that ip with xctuconst char broker[] = "asdasd";const int port = 1883;const char* mqttClientID = "MayflyXBee";const int8_t powerPin = 18;const int8_t statusPin = 19;const int8_t modemResetPin = 20;const int8_t modemSleepRqPin = 23;const char* ssid = "USU-guest";const char* pwd = "";DigiXBeeWifi modemXBWF(&Serial1, powerPin, statusPin, false,modemResetPin, modemSleepRqPin,ssid, pwd, false);class XBeeTransparentClient : public Client {public:XBeeTransparentClient(Stream& s) : _stream(s) {}int connect(IPAddress ip, uint16_t port) override { return 1; }int connect(const char* host, uint16_t port) override { return 1; }void stop() override {}uint8_t connected() override { return 1; }operator bool() override { return true; }size_t write(uint8_t b) override { return _stream.write(b); }size_t write(const uint8_t* buf, size_t size) override { return _stream.write(buf, size); }int available() override { return _stream.available(); }int read() override { return _stream.read(); }int read(uint8_t* buf, size_t size) override { return _stream.readBytes(buf, size); }int peek() override { return _stream.peek(); }void flush() override {}private:Stream& _stream;};XBeeTransparentClient xbeeClient(Serial1);MqttClient mqttClient(xbeeClient);void setup() {Serial.begin(9600);pinMode(XBEE_PWR, OUTPUT);digitalWrite(XBEE_PWR, HIGH);delay(2000);XBEE_SERIAL.begin(9600);if (!checkForConnection()) {Serial.println("Could not connect to WiFi");return;}Serial.println("WiFi connected!");delay(5000);mqttClient.setId(mqttClientID);Serial.println("starting mqtt");if (!mqttClient.connect(broker, port)) {Serial.print("MQTT failed, error: ");Serial.println(mqttClient.connectError());} else {Serial.println("MQTT connected!");}}void loop() {if (!mqttClient.connected()) {Serial.println("MQTT disconnected, reconnecting...");delay(3000);mqttClient.connect(broker, port);return;}mqttClient.poll();mqttClient.beginMessage("sensors/data");mqttClient.print("temperature=23.5");mqttClient.endMessage();Serial.println("Message sent");delay(2000);}bool checkForConnection() {String status = "F";int attempts = 0;XBEE_SERIAL.print("+++");delay(1100);clearXbeeSerialBuffer();while (status != "0" && attempts < 50) {XBEE_SERIAL.println("ATAI");delay(500);if (XBEE_SERIAL.available()) {String response = XBEE_SERIAL.readStringUntil('\n');response.trim();status = response;}attempts++;Serial.println(status);delay(1000);}XBEE_SERIAL.println("ATCN");delay(3000);clearXbeeSerialBuffer();delay(2000);return status == "0";}void clearXbeeSerialBuffer() {while (XBEE_SERIAL.available()) {XBEE_SERIAL.read();}}This is how I am implementing tinygsm
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192// this is the working code// but the mqtt connection closes immediately after first time// need to figure out the reason#define TINY_GSM_MODEM_XBEE#define TINY_GSM_RX_BUFFER 256#define TINY_GSM_USE_GPRS false#define TINY_GSM_USE_WIFI true#define TINY_GSM_DEBUG Serial#include <Arduino.h>#include <TinyGsmClient.h>#include <ArduinoMqttClient.h>#include <StreamDebugger.h>#define SerialMon Serial#define SerialAT Serial1#define XBEE_PWR 18const char* broker = "raspberrypi1.mypc.usu.edu";const int port = 1883;const char* topicTemp = "sensor/temperature";StreamDebugger debugger(SerialAT, SerialMon);TinyGsm modem(debugger);TinyGsmClient client(modem);MqttClient mqtt(client);void setup() {SerialMon.begin(9600);delay(20);pinMode(XBEE_PWR, OUTPUT);digitalWrite(XBEE_PWR, HIGH);delay(2000);SerialAT.begin(9600);delay(3000);SerialMon.println("Waiting for WiFi...");delay(5000);SerialMon.print("Local IP: ");SerialMon.println(modem.localIP());mqtt.setId("ArduinoTempSensor");mqtt.setTxPayloadSize(512);SerialMon.print("Connecting to MQTT broker: ");SerialMon.println(broker);if (!mqtt.connect(broker, port)) {SerialMon.print("MQTT connection failed, error code: ");SerialMon.println(mqtt.connectError());} else {SerialMon.println("MQTT connected!");}}void loop() {// Reconnect if droppedif (!mqtt.connected()) {SerialMon.print("MQTT disconnected, reconnecting... ");delay(1000);if (!mqtt.connect(broker, port)) {SerialMon.print("failed, error code: ");SerialMon.println(mqtt.connectError());delay(5000);return;}SerialMon.println("reconnected!");}mqtt.poll();// Publish temperature every 10 secondsstatic unsigned long lastMsg = 0;if (millis() - lastMsg > 10000L) {lastMsg = millis();float temperature = 20.0 + random(0, 150) / 10.0;SerialMon.println();SerialMon.print("This is the console output Publishing temperature: ");SerialMon.println(temperature);SerialMon.println();mqtt.beginMessage(topicTemp);mqtt.print(temperature);mqtt.endMessage();}}Tinygsm implementation will result in flaky broker connection like this:
1773954855: New client connected from 144.39.141.49:49164 as ArduinoTempSensor (p4, c1, k15). 1773954865: Client ArduinoTempSensor [144.39.141.49:49164] disconnected: connection closed by client. 1773954865: New connection from 144.39.141.49:49165 on port 1883. 1773954865: Protocol error from 144.39.141.49:49165: First packet not CONNECT (30). 1773954865: Client 144.39.141.49 [144.39.141.49:49165] disconnected: protocol error.
-
-
AuthorPosts
- You must be logged in to reply to this topic.
Welcome to EnviroDIY, a community for do-it-yourself environmental science and monitoring. EnviroDIY is part of