ESP8266 hangs in Cayenne.loop when WiFi Connection is lost


#1

I have set up an ESP8266 to control a heater for some plants in my garden. The logic is, that the heater should switch on, once the temperature drops below 0°C and switches off again, once the temperature goes above 5°C. As the ESP8266 is physically located in the garden, the WiFi connection is not totally reliable, sometimes it fails for some time. That’s why I kept the control logic for switching on and off in the microcontroller code instead of using an event trigger by Cayenne. Cayenne is used to display temperature and status information and to control some other, less critical things (addtitional sensors and switches to turn garden lights on/off). The problem that I have is, that once the WiFi connection gets lost, it seems that the ESP8266 hangs in the “Cayenne.loop()” function and effectively does nothing else anymore. This means, that the heating function will not work during off-line. Is there a way around this?

Would using interrrupts be a good idea or does anybody have another suggestion? Here is my code (only an extract with the relevant parts):

#include <OneWire.h>
#include <DallasTemperature.h>
// WiFi network info.
char ssid[] = “…”;
char wifiPassword[] = “…”;
// Cayenne authentication info.
char username[] = “uuuuuuuuuuuu”;
char password[] = “ppppppppp”;
char clientID[] = “ccccccccc”;
float p; // temperature
byte h=1 ; // heater
OneWire ds_2(5); // Temperature sensor
DallasTemperature sensor_Palme(&ds_2);

void setup() {
Serial.begin(9600);
Cayenne.begin(username, password, clientID, ssid, wifiPassword);
sensor_Palme.begin();
pinMode(D5, OUTPUT); // heater relay
digitalWrite(D5, HIGH); // relay off
}

void loop() {
Cayenne.loop(); // System hangs here when WiFi connection is lost!
sensor_Palme.requestTemperatures();
p=sensor_Palme.getTempCByIndex(0);
Cayenne.virtualWrite(8, p); //Display Temperature
if (p<0) {h=0;} // heater on
if (p>5) {h=1;} // heater off
digitalWrite (D5, h);
Cayenne.virtualWrite(10, h); // Display heater status
}


#2

@mike2506red have a look at this Arduino Online/Offline Override


#3

Does not work for me. Here is the trial code I put in:

//#define CAYENNE_DEBUG
#define CAYENNE_PRINT Serial

#include <CayenneMQTTESP8266.h>
#include <RCSwitch.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// WiFi network info.
char ssid[] = “sssss”;
char wifiPassword[] = “ppp”;

// Cayenne authentication info.
char username[] = “uuuu”;
char password[] = “6pppp”;
char clientID[] = “cccc”;
float p=5; // temperatur palme
long lastMillis = 0;
boolean onlineStatus=false;
OneWire ds_2(5); // GPIO5: Sensor Palme
DallasTemperature sensor_Palme(&ds_2);

void setup() {
Serial.begin(9600);
Serial.println(“starting”);
Cayenne.begin(username, password, clientID, ssid, wifiPassword);
sensor_Palme.begin();
}

CAYENNE_CONNECTED(){onlineStatus=true;}
CAYENNE_DISCONNECTED(){onlineStatus=false;}

void loop() {
if (onlineStatus==true)
{Cayenne.loop();
Serial.print(“Online”);}
else{ Serial.println(“Offline”); }

}

When I run this, the system permanently prints “Online”, even when the connection gets lost. Means “onlineStatus” is never set to false. In the post, something is mentioned about “editing a Keyword file”. I have no clue what that means. Do you have concrete information, what file to edit and what needs to be changed in that file? Maybe that is the problem, because the Arduino IDE highlights the “CAYENNE_CONNECTED” text, while it does not hightlight the “CAYENNE_DISCONNECTED” text, which seems strange to me. A short explanation of these “CAYENNE_CONNECTED” and “CAYENNE_DISCONNECTED” would also help. Where and when is the code executed, that would set the onlineStatus to true or false?


#4

search for a file “BlynkProtocol.h” in arduino folder. open and remove the comments on ALL the lines like this: //BlynkOnDisconnected(); There are 5 or six or so from memory and save it.


#5

I did edit the “BlynkProtocl.h” and removed the comment slashes in the 6 lines where BlynkOnDisconnected() was found. No change. Continues to give me “online” message, once the WiFi is off, I get no status “offline”. Here is the output I see, when I switch off WiFi:

[20918] Connected to WiFi
[20918] IP: 192.168.178.52
[20918] Connecting to mqtt.mydevices.com:1883
[21199] Connected
Online
Online
Online
Online
Online
Online
Online
Online
[43109] Disconnected
[43109] Connecting to mqtt.mydevices.com:1883
[49933] Network connect failed
[57957] Network connect failed

So no recognition of the “offline” status.


#6

i am not sure where you are going wrong. @rsiegel can you help here with this.


#7

I think I got it. There is a much simpler solution. All I need is this:

if (WiFi.status() == WL_CONNECTED) { Cayenne.loop(); }

This works for me now!


#8

No - I need to take that back. It does not work reliably. Sometimes it works, sometimes it does not. I guess it only works, if the WiFi is lost, while the ESP8266 executes outside of the Cayenne.loop. If WiFi is lost, while ESP8266 executes already inside the Cayenne.loop it still hangs. Also using ticker and interrupt does not work, because after executing the ISR routine, the control is simply returned to the Cayenne.loop, and the system continues to hang…Any other ideas?


#9

My suggestion would be to start a millis timer and reset the timer every loop. if it hangs for more than x seconds call a reset for the board.


#10

Tried this already. Does not work either, as the “Cayenne.begin” routine, which is executed during setup is also written in a way, that it hangs up indefinitely, if no WiFi is present. Besides that, I found that the ESP8266 does not reset reliably neither with ESP.restart() nor with ESP.reset() - there are several discussions of this problem in various forums.

I examined the Cayenne libraries. In the CayenneArduinoMQTTClient.h, there is a function “connect()”, which contains a do/while loop, that looks like the one causing the problem:

do {/ attempt to connect; delay(1000); /}
while (error != MQTT_SUCCESS);

it looks to me, that if I could replace this with an equivalent for-loop, which counts up to 10 executions, this could work as some timeout, if after 10 seconds there is still no connection possible. I just have not figured out, how to jump out of the Cayenne.loop function in that case. Would be grateful, if anybody has an idea here - unfortunately I am not very skilled in programming…


#11

I will take a look at it and see what I can come up with. I modified the blynk connection method to do that over here so it should be possible.

Yes, I have seen a few people posting about this. Might be better to just put the ESP is deep sleep mode (also in the link above)

This must be an MQTT issues since I don’t remember seeing that behavior in the blynk connection method. Again, I’ll take a look and see if I can get it working.

I really need to update the battery powered ESP project page so maybe I’ll take some time to update it to the officially supported MQTT connection method while I’m testing these things.


#12

Any progress, I’m working a esp8266 project and worried about the same issue …