attachInterrupt crashes photon and core

I have a program that I have been running on a Core and Photon for some weeks now. The core and photon is used as a movement sensor and if the area is dark enough and movement is detected it sends a command through to my philips hue bulb to light up at a specific colour to help guide my way. The bulb stays illuminated as long as it see movement and then goes off when no movement is detected for 10 secs.
As I mentioned this has worked great for some weeks now, but recently, last week, I noticed it was not working. Upon investigation, everything works fine upto the attachInterrupt code then it locks up.
The Spark Core gives an SOS and then 11 red pulses.
The Photon gives SOS and then 1 red pulse.
Has anything changed in the firmware?
Although I have tried all versions of firmware it still fails so I don’t think it is this.
I just do not know where to start looking for the fault and any help would be appreciated as I have just blown about 4 days looking for this fault. The code has not changed from when it was working.

// functions


void light_on(void);
//void light_off(void);

int sensorLED = A0;                                     // LDR as sensor connected to analog pin A0
int LED = D7;
int movementLED = D2;                                          // LED connected to digital pin D2
int LDRval = 0;                                         //Variable to store the LDR sensor value
int light = 35;                                         //Threshold level

volatile bool flagState = false;
volatile bool lightsensor = false;                      // Local light level detection for stopping movement detection
unsigned long set_time;
TCPClient client;
byte server[] = { ***, ***, ***, *** };                   // Local HUE light server for HOME

// 10 secs
#define FIFTEEN_MIN_MILLIS (10 * 1000)

void setup()
{
  pinMode(D1, INPUT_PULLDOWN);
  pinMode(LED,OUTPUT);
  pinMode(movementLED,OUTPUT);
  pinMode(sensorLED,INPUT);
  digitalWrite(LED, HIGH);
  digitalWrite(movementLED, HIGH);
  
  attachInterrupt(D1, light_on, RISING);                // Movement sensor interrupt
  
  set_time = millis();
  Serial.begin(9600);
        delay(400);
    	RGB.control(true);                              // Turn down for what? The status light is crazy bright = wasted mAh battery.
	    RGB.brightness(2);                                  // This sets the RGB LED brightness : 0-256
    	RGB.control(false);                             // release the LED to the system
        delay(5000);
        client.connect(server, 80);
        if (client.connected())                         //initiate connection
            {                            
                Serial.println("connected");
                digitalWrite(LED, LOW);                 //Visible
                delay(100);                             //confirmation
                digitalWrite(LED, HIGH);                //server
                delay(100);                             //is
                digitalWrite(LED, LOW);                 //connected
                delay(100);
                digitalWrite(LED, HIGH);
                delay(200);
                
            }
        else
            {
                Serial.println("failed");
                client.connect(server, 80);
                Serial.println("connecting");
                return;
            }
}

void loop() 
{
    LDRval = analogRead(sensorLED);
  
    Serial.println("LDR Value:= " + String(LDRval));    //debug value
   
    delay(50);
    
    if (LDRval <= light)                                // check if light is above threshold 
        {                      
            digitalWrite(LED, LOW);                     // if dark, turn off led
            lightsensor = false;                        // enable movement detection
         }
    else 
        {                     
            digitalWrite(LED, HIGH);                    // if light, turn on led
            lightsensor = true;                         // disable movement detection
        } 
        
        if (flagState == true)
            {
                delay(200);
                set_time = millis();
                flagState = false;
            }
        if( millis() - set_time > FIFTEEN_MIN_MILLIS)
            {
   
                Serial.println("Movement Stopped");     //debug notice
               
                delay(50);
                digitalWrite(movementLED, LOW);
 
		        if(client.connect(server, 80))
		            {
                        client.println("PUT /api/*******************************/lights/4/state");
                        client.println("Connection: keep-alive");   //
                        client.println("Host: ***.***.***.***");      //HOME same as server
                        client.println("Content-Type: text/plain;charset=UTF-8"); //
                        client.print("Content-Length: ");           //param
                        client.println(16);                         //brightness string + val length
                        client.println();                           // blank line before body
                        client.print("{\"on\":false}");
                        delay(50);
		            }
	            client.stop();
		
            }
        delay(2000);
}

void light_on()
{
    
    if(lightsensor == false )                                   //Daylight check to avoid use during day time
        {
            delay(10);
            flagState = true;
            //Serial.println("Movement Detected");     //debug notice
            //delay(1000);
            digitalWrite(movementLED, HIGH);
            /*delay(1000);
            digitalWrite(movementLED, LOW);
            delay(1000);
            digitalWrite(movementLED, HIGH);
            delay(1000);*/
            
	        if(client.connect(server, 80))
	                {
                        client.println("PUT /api/*******************************/lights/4/state");
                        client.println("Connection: keep-alive");   //
                        client.println("Host: ***.***.***.***");      //HOME same as server
                        client.println("Content-Type: text/plain;charset=UTF-8"); //
                        client.print("Content-Length: ");           //param
                        client.println(53);                         //brightness string + val length
                        client.println();                           // blank line before body
                        client.print("{\"on\":true,\"bri\":139,\"sat\":248,\"hue\":61894}");
                        delay(50);
		            }
	        client.stop();
	        delay(200);
        }
}

I’d say it’s not attachInterrupt() that crashes but your ISR.

Don’t use delay() in an ISR!!!

And you should not use potentially long running loops/functions/libraries (e.g. TCPClient) either.

1 Like

Thanks ScruffR moved the code around as your suggestion and now it works.
I thought I had done this earlier but obviously I had not. Also why did it work for so long without this change? Maybe H.A.L. is alive and well and now called a Photon!
Just goes to prove coding is a black art and I have many years ahead of me.
Thanks again for your help.

// functions


void light_on(void);
//void light_off(void);

int sensorLED = A0;                                     // LDR as sensor connected to analog pin A0
int LED = D7;
int movementLED = D2;                                          // LED connected to digital pin D2
int LDRval = 0;                                         //Variable to store the LDR sensor value
int light = 35;                                         //Threshold level

volatile bool flagState = false;
volatile bool lightsensor = false;                      // Local light level detection for stopping movement detection
unsigned long set_time;
TCPClient client;
byte server[] = { ***, ***, ***, *** };                   // Local HUE light server for HOME

// 10 secs
#define FIFTEEN_MIN_MILLIS (10 * 1000)

void setup()
{
  pinMode(D1, INPUT_PULLDOWN);
  pinMode(LED,OUTPUT);
  pinMode(movementLED,OUTPUT);
  pinMode(sensorLED,INPUT);
  digitalWrite(LED, HIGH);
  digitalWrite(movementLED, HIGH);
  
  attachInterrupt(D1, light_on, RISING);                // Movement sensor interrupt
  
  set_time = millis();
  Serial.begin(9600);
        delay(400);
    	RGB.control(true);                              // Turn down for what? The status light is crazy bright = wasted mAh battery.
	    RGB.brightness(2);                                  // This sets the RGB LED brightness : 0-256
    	RGB.control(false);                             // release the LED to the system
        delay(5000);
        client.connect(server, 80);
        if (client.connected())                         //initiate connection
            {                            
                Serial.println("connected");
                digitalWrite(LED, LOW);                 //Visible
                delay(100);                             //confirmation
                digitalWrite(LED, HIGH);                //server
                delay(100);                             //is
                digitalWrite(LED, LOW);                 //connected
                delay(100);
                digitalWrite(LED, HIGH);
                delay(200);
                
            }
        else
            {
                Serial.println("failed");
                client.connect(server, 80);
                Serial.println("connecting");
                return;
            }
}

void loop() 
{
    LDRval = analogRead(sensorLED);
  
    Serial.println("LDR Value:= " + String(LDRval));    //debug value
   
    delay(50);
    
    if (LDRval <= light)                                // check if light is above threshold 
        {                      
            digitalWrite(LED, LOW);                     // if dark, turn off led
            lightsensor = false;                        // enable movement detection
         }
    else 
        {                     
            digitalWrite(LED, HIGH);                    // if light, turn on led
            lightsensor = true;                         // disable movement detection
        } 
        
        if (flagState == true)
            {
                 if(client.connect(server, 80))
	                {
                        client.println("PUT /api/**********************************/lights/4/state");
                        client.println("Connection: keep-alive");   //
                        client.println("Host: ***.***.***.***");      //HOME same as server
                        client.println("Content-Type: text/plain;charset=UTF-8"); //
                        client.print("Content-Length: ");           //param
                        client.println(53);                         //brightness string + val length
                        client.println();                           // blank line before body
                        client.print("{\"on\":true,\"bri\":139,\"sat\":248,\"hue\":61894}");
                        delay(50);
		            }
	        client.stop();
	        delay(200);
                delay(200);
                set_time = millis();
                flagState = false;
            }
        if( millis() - set_time > FIFTEEN_MIN_MILLIS)
            {
   
                Serial.println("Movement Stopped");     //debug notice
               
                delay(50);
                digitalWrite(movementLED, LOW);
 
		        if(client.connect(server, 80))
		            {
                        client.println("PUT /api/**********************************/lights/4/state");
                        client.println("Connection: keep-alive");   //
                        client.println("Host: ***.***.***.***");      //HOME same as server
                        client.println("Content-Type: text/plain;charset=UTF-8"); //
                        client.print("Content-Length: ");           //param
                        client.println(16);                         //brightness string + val length
                        client.println();                           // blank line before body
                        client.print("{\"on\":false}");
                        delay(50);
		            }
	            client.stop();
		
            }
        delay(2000);
}

void light_on()
{
    
    if(lightsensor == false )                                   //Daylight check to avoid use during day time
        {
         flagState = true;
        }
}