knolleary / pubsubclient

A client library for the Arduino Ethernet Shield that provides support for MQTT.
http://pubsubclient.knolleary.net/
MIT License
3.78k stars 1.46k forks source link

Asynchronous connect #579

Open 9a4gl opened 5 years ago

9a4gl commented 5 years ago

Can we have asynchronous connect ? I need to update display, own watchdog and other stuff during connecting. Or at least a connect to which we provide own yield function that will be called.

atuline commented 4 years ago

My outdoor LED displays halt and/or stutter when my MQTT server (my phone) goes in and out of range. Have yet to find an MQTT library that doesn't block the loop in some manner. As a result, I've had to remove MQTT (or pubsubclient) from the majority of those displays.

WebDust21 commented 4 years ago

I ran up against this exact same problem. Tried two solutions... ...for the first, I gutted the "connect" routine, putting the blocking "are we connected yet?" into the LOOP call, as well as adding a new MQTT state handler for "connecting" mode. You might notice that LOOP only does anything if the socket is connected...which makes it very easy to add non-blocking code for a non-connected state. I'd provide a lot more documentation EXCEPT that I can't say that it helped at all. It didn't break anything, though.

Second solution? Redesign multiple thousands of lines of my program code to use an RTOS setup...putting all the WiFi stuff on its own thread on the other core. Problem solved.

atuline commented 4 years ago

I moved on from pubsubclient to the async-mqtt-client library and am now onto WLED. Am learning it.

ilker07 commented 2 years ago

include

extern "C" {

include "freertos/FreeRTOS.h"

include "freertos/timers.h"

}

include

define TINY_GSM_MODEM_SIM800 // Modem is SIM800L

define SerialMon Serial

define SerialAT Serial1

define TINY_GSM_DEBUG SerialMon

const char apn[] ="internet";//internet const char gprsUser[] =""; const char gprsPass[] ="";

include

include

ifdef DUMP_AT_COMMANDS

include

StreamDebugger debugger(SerialAT, SerialMon); TinyGsm modem(debugger);

else

TinyGsm modem(SerialAT);

endif

TinyGsmClient client(modem);

// Digital Ocean MQTT Mosquitto Broker

define MQTT_HOST IPAddress(xxx,xxx,xxx,xxx)

define MQTT_PORT 1883

define MQTT_USERNAME "REPLACE_WITH_YOUR_MQTT_USER"

define MQTT_PASSWORD "REPLACE_WITH_YOUR_MQTT_PASSWORD"

// Test MQTT Topic

define MQTT_PUB_TEST "led"

// TTGO T-Call pins

define MODEM_RST 5

define MODEM_PWKEY 4

define MODEM_POWER_ON 23

define MODEM_TX 27

define MODEM_RX 26

define I2C_SDA 21

define I2C_SCL 22

TwoWire I2CPower = TwoWire(0);

define IP5306_ADDR 0x75

define IP5306_REG_SYS_CTL0 0x00

bool setPowerBoostKeepOn(int en){ I2CPower.beginTransmission(IP5306_ADDR); I2CPower.write(IP5306_REG_SYS_CTL0); if (en) { I2CPower.write(0x37); // Set bit1: 1 enable 0 disable boost keep on } else { I2CPower.write(0x35); // 0x37 is default reg value } return I2CPower.endTransmission() == 0; }

AsyncMqttClient mqttClient; TimerHandle_t mqttReconnectTimer;

void connectToMqtt() { Serial.println("Connecting to MQTT..."); mqttClient.connect(); }

void onMqttConnect(bool sessionPresent) { Serial.println("Connected to MQTT."); Serial.print("Session present: "); Serial.println(sessionPresent); }

void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) { Serial.println("Disconnected from MQTT.");

xTimerStart(mqttReconnectTimer, 0);

}

void onMqttPublish(uint16_t packetId) { Serial.print("Publish acknowledged."); Serial.print(" packetId: "); Serial.println(packetId); }

void setup() { SerialMon.begin(115200); delay(10);

/* I2CPower.begin(I2C_SDA, I2C_SCL, 400000);

bool isOk = setPowerBoostKeepOn(1); SerialMon.println(String("IP5306 ") + (isOk ? "OK" : "FAIL"));*/

pinMode(MODEM_PWKEY, OUTPUT); pinMode(MODEM_RST, OUTPUT); pinMode(MODEM_POWER_ON, OUTPUT); digitalWrite(MODEM_PWKEY, LOW); digitalWrite(MODEM_RST, HIGH); digitalWrite(MODEM_POWER_ON, HIGH);

SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX); delay(6000);

modem.restart(); //modem.init();

String modemInfo = modem.getModemInfo(); SerialMon.print("Sim: "); SerialMon.println(modemInfo);

Serial.println("MQTT Ayarlari...");

//mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast(connectToMqtt));

mqttClient.onConnect(onMqttConnect); mqttClient.onDisconnect(onMqttDisconnect); mqttClient.onPublish(onMqttPublish); mqttClient.setServer(MQTT_HOST, MQTT_PORT);

if(!modem.gprsConnect(apn, gprsUser, gprsPass)) SerialMon.println("Internet fail!!!!");

if (modem.isGprsConnected()) { SerialMon.println("GPRS OK!!"); connectToMqtt(); //it reboots here. }

}

void loop() {

}