Open 9a4gl opened 5 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.
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.
I moved on from pubsubclient to the async-mqtt-client library and am now onto WLED. Am learning it.
extern "C" {
}
const char apn[] ="internet";//internet const char gprsUser[] =""; const char gprsPass[] ="";
StreamDebugger debugger(SerialAT, SerialMon); TinyGsm modem(debugger);
TinyGsm modem(SerialAT);
TinyGsmClient client(modem);
// Digital Ocean MQTT Mosquitto Broker
// Test MQTT Topic
// TTGO T-Call pins
TwoWire I2CPower = TwoWire(0);
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
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() {
}
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.