I don't know if this is a hardware, firmware, Internet or cloud issue, but I have a Photon 2 running pre-production firmware in a development environment that randomly - about once or twice per day - stops communicating with the cloud.
Between such outages, the application runs perfectly for hours on end. When it disconnects, the LED glows a continuous cyan color - no "breathng" - indicating that it is solidly connected to WiFi but not to the Particle cloud. A reboot via a power cycle restores everything to normal operation. Much less frequently. the Photon will completely disconnect from WiFi (flashing green) but it then reconnects quite quickly.
Note that the Photon is running Device OS 5.9.0. Note, also, that the WiFi signal strength is very strong (three mesh WiFi routers). I have another in-production Photon at another site, running the same OS version and similar - but not identical - code, that never exhibits this behavior even though it reports a signal strength of only "fair".
The symptoms surely suggest that the problem might be somewhere between my WiFi network and the Internet, but I have about dozen other devices that connect to the Internet via the same network including 3 computers, TVs and several IoT devices (Ring doorbell, thermostat, garage door openers, security cameras, etc.) and I have never seen this issue with any of them. Nonetheless, I re-booted my ISP's fiber modem and, subsequently, did the same with the closest router - about 20 feet away - while the Photon was off line. No reconnect. That then suggests maybe the code has hung, but I can find nothing that would suggest that is even possible; remember that the code runs for many hours without interruption and the outages appear to be completely random.
Any ideas as to why this might be happening?
The firmware:
// This #include statement was automatically added by the Particle IDE.
#include <NCD2Relay.h>
NCD2Relay controller;
SYSTEM_THREAD(ENABLED);
String data = String(10);
int status;
int GPIOStatus3;
int setZone (String zone);
int PhotonOff = 0;
long int publishInterval = 600; // 10 minutes
long int lastPublish = Time.now();
long int StartWaitTime = Time.now();
long int StartOnesTime;
unsigned long lastReset = System.millis();
bool Restart = true;
bool Disable = false;
String myID = System.deviceID();
//STARTUP(WiFi.selectAntenna(ANT_AUTO));
void setup(){
//WiFi.setCredentials("MTWA", "Cr3st0n!");
WiFi.setCredentials("Pubbuds", "d0wnunder");
waitUntil(Particle.connected);
controller.setAddress(0,0,0);
lastPublish = Time.now();
lastReset = System.millis();
Particle.function("Disable", DisableAuto);
Particle.variable("GPIO3", GPIOStatus3);
Particle.variable("Is_Disabled", PhotonOff);
Time.zone(-5);
StartOnesTime = Time.now();
myID = myID.substring(21);
}
// Function to disable or enable transmissions
int DisableAuto(String command){
String Command = command;
if (Command.equalsIgnoreCase("yes")){
Disable = true;
int (PhotonOff = 1);
StartWaitTime = Time.now(); // Start disable interval timer
Particle.publish ("Disabled", "Photon " + myID + " disabled manually");
return 1;
}
if (Command.equalsIgnoreCase("no")){
Disable = false;
int (PhotonOff = 0);
Particle.publish ("Disabled", "Photon " + myID + " re-enabled manually");
return 1;
}
return -1;
}
void loop(){
int(GPIOStatus3 = controller.readInputStatus(3));
if ( Particle.connected() ){
if ( Restart == true){
Particle.publish("Restart", "Photon " + myID + " restarted"); // Send status to log
Restart = false;
}
}
if ( millis() > lastReset + 3600000 ){ // Reinitialize the MCP23008 chip on the NCD relay board every hour
controller.setAddress(0,0,0); // Reinitialize the MCP23008 chip on the NCD relay board
lastReset = System.millis(); // Reset last initialization time to current program time
}
if ( Time.now() >= lastPublish + publishInterval){ // If it's been 10 minutes since last publish
int status = controller.readInputStatus(3); // Read input terminal 3
if ( status == 1){ // Need water
if ( Time.now() - StartOnesTime >= 9000 & Disable == false){ // If 1's have been sent for more than 2-1/2 hours
Particle.publish ("Test",myID + " sent ones for " + String((Time.now() - StartOnesTime)/60) + " minutes");
status = 0;
Particle.publish("Test", "Photon " + myID + " sent " + String(status));
//Particle.publish("Wait", "Tank too long"); // Send an email alert
Disable = true; // Disable all transmissions
PhotonOff = 1;
StartWaitTime = Time.now(); // Start disable interval timer
Particle.publish ("Disabled", "Photon " + myID + " disabled automatically");
StartOnesTime = Time.now();
lastPublish = Time.now();
}
}else{
if ( Disable == true){
Particle.publish ("Disabled", "Photon " + myID + " re-enabled automatically");
}
Disable = false;
StartWaitTime = Time.now(); // Reset wait time
StartOnesTime = Time.now(); // Reset StartOnesTime
}
if ( Disable == false){
// Particle.publish("Tank", String(status));
Particle.publish("Test", "Photon " + myID + " sent " + String(status));
PhotonOff = 0;
lastPublish = Time.now();
delay(20);
}
}
if ( Time.now() - StartWaitTime >= 43200 & Disable == true){ // If the Photon has been disabled for 12 hours
Disable = false; // Re-enable transmissions
PhotonOff = 0;
StartWaitTime = Time.now();
StartOnesTime = Time.now(); // If the next transmit interval is 1 rather than a 0
Particle.publish ("Disabled", "Photon " + myID + " re-enabled automatically");
}
}
Typical Google Sheet log entries: