Device hangs on cyan an needs hard-reset

Hello

I have the problem that my particle hangs on cyan after a few minutes or days.
I will attach the code below, after I have read several times that other people has the same problem and it is code-specific.

Its my first time I use the particle and writing C++. Normally I use Python and PHP.
Maybe someone can find something, thanks for looking.

My Envirement:

1 DHT22 Sensor
3 Movment Sensors
PWM Output for PhaseAngel (Kemo M150)
Outputs for Switching Lights
I use MQTT to communicate with my OpenHab Server

My Code:

// This #include statement was automatically added by the Particle IDE.
#include "PietteTech_DHT/PietteTech_DHT.h"
#include "MQTT/MQTT.h"
#include <string>

#define DHTTYPE  AM2302              // Sensor type DHT11/21/22/AM2301/AM2302
#define DHTPIN   6         	    // Digital pin for communications
#define DHT_SAMPLE_INTERVAL   10000  // Sample every two seconds
SYSTEM_MODE(SEMI_AUTOMATIC);

//declaration
void dht_wrapper(); // must be declared before the lib initialization

// Lib instantiate
PietteTech_DHT DHT(DHTPIN, DHTTYPE, dht_wrapper);

// globals
unsigned int DHTnextSampleTime;	    // Next time we want to start sample
bool bDHTstarted;		    // flag to indicate we started acquisition
int n;// counter
int PinAbluft = D0;
int PinBWM = D5;
int PinBWMwc = D4;
int PinBWMwt = D3;
int PinLicht = A1;
int PinLichtwt = A0;
int PinSound = D1;
int duty = 0;
int DutyMin = 80;
int DutyMax = 255;
int DutySpan = DutyMax - DutyMin;
volatile int StatusBWM = 0;
volatile int StatusBWM_wc = 0;
volatile int StatusBWM_wt = 0;


void callback(char* topic, byte* payload, unsigned int length);
/**
 * if want to use IP address,
 * byte server[] = { XXX,XXX,XXX,XXX };
 * MQTT client(server, 1883, callback);
 * want to use domain name,
 * MQTT client("www.sample.com", 1883, callback);
 **/
byte server[] = { 192,168,184,170 };
MQTT client(server, 1883, callback);

// recieve message
void callback(char* topic, byte* payload, unsigned int length) {
    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;
    String message(p);
    if (strcmp(topic,"bad_abluft")==0){
            double setpoint = atof(p);
            if (setpoint > 0){
                duty = setpoint / 100 * DutySpan + DutyMin;
                Spark.publish("Abluft",String(duty));
            }else{
                duty = 0;
            }
        }else if(strcmp(topic,"bad_licht")==0){
            if(message=="1"){
                digitalWrite(PinLicht,HIGH);
            }else{
                digitalWrite(PinLicht,LOW);
            }
        }else if(strcmp(topic,"bad_licht_wt")==0){
            if(message=="1"){
                digitalWrite(PinLichtwt,HIGH);
                Spark.publish("BAD WT","1");
            }else{
                digitalWrite(PinLichtwt,LOW);
                Spark.publish("BAD WT","0");
            }
        }else if(strcmp(topic,"bad_sound")==0){
            Spark.publish("BAD Sount","?");
            if(message=="1"){
                digitalWrite(PinSound,HIGH);
                Spark.publish("BAD Sount","1");
            }else{
                digitalWrite(PinSound,LOW);
                Spark.publish("BAD Sount","0");
            }
        }
}


void send_BWM(){
    StatusBWM = digitalRead(PinBWM);
    StatusBWM_wc = digitalRead(PinBWMwc);
    StatusBWM_wt = digitalRead(PinBWMwt);
    client.publish("bad_bwm",String(StatusBWM));
    client.publish("bad_bwm_wc",String(StatusBWM_wc));
    client.publish("bad_bwm_wt",String(StatusBWM_wt));    
}

Timer sendBWM(500, send_BWM);

void setup() {
    WiFi.on();
    Particle.connect();
    sendBWM.start();
    //RGB.control(true);
    pinMode(PinAbluft,OUTPUT);
    pinMode(PinBWM,INPUT);
    pinMode(PinBWMwc,INPUT);
    pinMode(PinBWMwt,INPUT);
    pinMode(PinLicht,OUTPUT);
    pinMode(PinLichtwt,OUTPUT);
    pinMode(PinSound,OUTPUT);

    
    // connect to the server
    client.connect("bunker");
    // publish/subscribe
    if (client.isConnected()) {
        client.subscribe("bad_abluft");
        client.subscribe("bad_licht");
        client.subscribe("bad_licht_wt");
        client.subscribe("bad_sound");
        Spark.publish("MQTT","isConnected");
    }
    
    //Serial.begin(9600);
    //while (!Serial.available()) {
    //    Serial.println("Press any key to start.");
    //    delay (1000);
    //}
    //Serial.println("DHT Example program using DHT.acquire and DHT.aquiring");
    //Serial.print("LIB version: ");
    //Serial.println(DHTLIB_VERSION);
    //Serial.println("---------------");

    DHTnextSampleTime = 0;  // Start the first sample immediately
    
}

// This wrapper is in charge of calling
// mus be defined like this for the lib work
void dht_wrapper() {
    DHT.isrCallback();
}

void loop() {

    if (!Particle.connected()){
                Particle.connect();
    }

    if (client.isConnected()) {
        client.loop();
    }
    else
    {
        client.connect("bunker");
    // publish/subscribe
        if (client.isConnected()) {
            client.subscribe("bad_abluft");
            client.subscribe("bad_licht");
            client.subscribe("bad_licht_wt");
            client.subscribe("bad_sound");
            Spark.publish("MQTT","isConnected");
        }
    }
    
     analogWrite(PinAbluft,duty,500);
    //RGB.color(0,0,duty);
    //StatusBWM = digitalRead(PinBWM);
    
    // Check if we need to start the next sample
  if (millis() > DHTnextSampleTime) {
	if (!bDHTstarted) {		// start the sample
	  //  Serial.print("\n");
	  //  Serial.print(n);
	  //  Serial.print(": Retrieving information from sensor: ");
	    DHT.acquire();
	    bDHTstarted = true;
	}

    	if (!DHT.acquiring()) {		// has sample completed?
    
    	    // get DHT status
    	    int result = DHT.getStatus();
    
    	 //   Serial.print("Read sensor: ");
    	    switch (result) {
    		case DHTLIB_OK:
    	//	    Serial.println("OK");
    	        client.publish("Bad_Sensor_Status","OK");
    		    break;
    		case DHTLIB_ERROR_CHECKSUM:
        		client.publish("Bad_Sensor_Status","Checksum Error");
    	//	    Serial.println("Error\n\r\tChecksum error");
    		    break;
    		case DHTLIB_ERROR_ISR_TIMEOUT:
        		client.publish("Bad_Sensor_Status","tISR time out Error");
    	//	    Serial.println("Error\n\r\tISR time out error");
    		    break;
    		case DHTLIB_ERROR_RESPONSE_TIMEOUT:
    	//	    Serial.println("Error\n\r\tResponse time out error");
    		    break;
    		case DHTLIB_ERROR_DATA_TIMEOUT:
    	//	    Serial.println("Error\n\r\tData time out error");
    		    break;
    		case DHTLIB_ERROR_ACQUIRING:
    	//	    Serial.println("Error\n\r\tAcquiring");
    		    break;
    		case DHTLIB_ERROR_DELTA:
    	//	    Serial.println("Error\n\r\tDelta time to small");
    		    break;
    		case DHTLIB_ERROR_NOTSTARTED:
    	//	    Serial.println("Error\n\r\tNot started");
    		    break;
    		default:
    	//	    Serial.println("Unknown error");
    		    break;
    	    }
    
        float feuchte = DHT.getHumidity();
        float temp = DHT.getCelsius();
        client.publish("Bad_Sensor_Feuchte",String(feuchte));    
        client.publish("Bad_Sensor_Temp",String(temp));
        
        //Spark.publish("Feuchte",feuchte);
        //Spark.publish("Temp",temp);
        
    	//    Serial.print("Humidity (%): ");
    	//    Serial.println(DHT.getHumidity(), 2);
        
    	//    Serial.print("Temperature (oC): ");
    	//    Serial.println(DHT.getCelsius(), 2);
    
    	//    Serial.print("Temperature (oF): ");
    	//    Serial.println(DHT.getFahrenheit(), 2);
    
    	//   Serial.print("Temperature (K): ");
    	//    Serial.println(DHT.getKelvin(), 2);
    
    	//    Serial.print("Dew Point (oC): ");
    	//    Serial.println(DHT.getDewPoint());
    
    	//    Serial.print("Dew Point Slow (oC): ");
    	//    Serial.println(DHT.getDewPointSlow());
    
    	    n++;  // increment counter
    	    bDHTstarted = false;  // reset the sample flag so we can take another
    	    DHTnextSampleTime = millis() + DHT_SAMPLE_INTERVAL;  // set the time for next sample
    	}
    }

    
}

That’s a large chunk of code to debug by inspection only. I suggest removing parts until the problem disappears.

A solid LED is indicative of a system crash, or many many interrupts occurring.

Add diagnostic logging for the amount of free memory via System.freeMemory(), since stack overflow/heap corruption can cause the system to stall.

Try removing the DHT22 sensor which uses interrupts which might be contributing to the problem.

Your test:

will fail after 2^32 microseconds (46 days or so)

use something like
if ((millis() - DHTLastSampleTime) >= DHT_SAMPLE_INTERVAL){
DHTLastSampleTime = millis();

}
This works even when millis() overflows.
Al

1 Like

Okay, I will try, but yesterday it failed after one Minute. To short for overflow.

I hoped, that I have a kind of beginner-mistake which is clear to see.
Or is there any option that it restarts like a watchdog on AVR?

It seems to be a problem with the MQTT Subscripten and/or that what I am making with the values I get. I will go forward analysing by uncomment the lines.

In the meantime I was able to produce an “SOS” Error and fix it :smile:
So its not so easy as Verify/Flash.

But the question about the watchdog persists. That or some kind of “auto-safe-mode” after “SOS”?

Hiere is the code I commented out, so that it works again:

void callback(char* topic, byte* payload, unsigned int length) {
    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;
    String message(p);
    if (strcmp(topic,"bad_abluft")==0){
            double setpoint = atof(p);
            if (setpoint > 0){
                duty = setpoint / 100 * DutySpan + DutyMin;
                Spark.publish("Abluft",String(duty));
            }else{
                duty = 0;
            }
        }else if(strcmp(topic,"bad_licht")==0){
            if(message=="1"){
                digitalWrite(PinLicht,HIGH);
            }else{
                digitalWrite(PinLicht,LOW);
            }
        }else if(strcmp(topic,"bad_licht_wt")==0){
            if(message=="1"){
                digitalWrite(PinLichtwt,HIGH);
                Spark.publish("BAD WT","1");
            }else{
                digitalWrite(PinLichtwt,LOW);
                Spark.publish("BAD WT","0");
            }
        }else if(strcmp(topic,"bad_sound")==0){
            Spark.publish("BAD Sount","?");
            if(message=="1"){
                digitalWrite(PinSound,HIGH);
                Spark.publish("BAD Sount","1");
            }else{
                digitalWrite(PinSound,LOW);
                Spark.publish("BAD Sount","0");
            }
        }
}

[…]

 if (client.isConnected()) {
        client.subscribe("bad_abluft");
        client.subscribe("bad_licht");
        client.subscribe("bad_licht_wt");
        client.subscribe("bad_sound");
    }