Does Particle Auto Timeout? (Phillips Hue/Pir Sensor)

I’m working on my first Photon project and got it working. The project is to use a PIR sensor attached to turn on the Hue lights when tripped. The code below works great doing the following:

  • After 30 seconds turn off the lights
  • Wait 30 more seconds then enable the motion sensor
  • If motion trigger is active turn on lights

As mentioned it seems that after X amount of hours the photon will turn off. I’m wondering if I should either put the device in sleep mode or try to use an interrupt prevent the device from going to sleep. However, I can’t find anything that talks about the device going to sleep on it self.

Here is the full code:

TCPClient client;
byte server[] = { 192, 168, 1, 100 }; // Local light server
    
const int pirPin = 0;     // the number of the pushbutton pin
const int buttonPin = 1;     // the number of the pushbutton pin

int buttonState = 0;         // variable for reading the pushbutton status
int pirState = 0;         // variable for reading the pushbutton status
int pushCount = 0;

bool awayState = true; // start up with motion sensor disabled until button is pressed

//function to send JSON data to client 
void sendJSON(String jsonData) 
{
    if (client.connect(server, 80)) {
        if(client.connected()) {
            unsigned int jsonLen = jsonData.length(); //get length of JSON data
            client.println("PUT /api/API-KEY/groups/1/action");
            client.println("Connection: keep-alive"); //
            client.println("Host: 192.168.1.100"); //same as server 
            client.println("Content-Type: text/plain;charset=UTF-8"); //
            client.print("Content-Length: "); //param 
            client.println(jsonLen); //brightness string + val length;
            client.println();  // blank line before body
            client.print(jsonData);
            delay(100); // slight delay IMPORTAN
        }
        client.stop();
    }
}

void setup() {
    pinMode(buttonPin, INPUT); //button as input
    pinMode(pirPin, INPUT);   // pir as input
    
    Serial.begin(9600);

    RGB.control(true); //let us control the on-board rgb led 
 
    for (short d = 0; d < 40; d++) { // give the pir 40 seconds to calibrate
        RGB.brightness(64);
        RGB.color(255, 0, 0);
        delay (500);
        RGB.color(0, 0, 0);
        delay(500);
    }
    
    client.connect(server, 80);
    if (client.connected()) { //initiate connection
        Serial.println("connected");
    }  else {
        Serial.println("failed");
    }
}
    
void loop() {
    buttonState = digitalRead(buttonPin);
    pirState = digitalRead(pirPin);
    
    if (buttonState == HIGH) { // runs on button press
                    //give 30 seconds to leave room
        for (short t = 0; t < 30; t++) {
            RGB.brightness(64);
            RGB.color(255, 255, 0);
            delay (500);
            RGB.color(0, 0, 0);
            delay(500);
        }

        //turn off lights
        String jsonOff = "{\"on\": false }";
    
        sendJSON(jsonOff); 
        //after 30 more seconds turn on motion sensor 
        delay(30000); 
        awayState = false;
    }  
 
    if (pirState == HIGH && awayState != true) { 
        //if away mode is disabled and we detect motion turn on lights 
        String jsonOn = "{\"on\": true,\"scene\": \"########-on-0\" }"; 
        sendJSON(jsonOn); 
        awayState = true; 
    } 
    if (awayState == false) { 
        RGB.brightness(20); 
        RGB.color(0, 155, 255); //turn led cyan to indicate standby 
    } 
}

(ScruffR: I “corrected” your formatting - discourse has obviously got some indentation problems ;-))

I just realized the other thing that may be happening is that the Internet connection is cutting out. I may re-work the code a bit so it goes into listen mode under setup() so if the Internet cuts out when I’m away the code will still work.

One of the first things you should look into is SYSTEM_MODE.
If you’re not actually using any of the cloud features, you might want to use SYSTEM_MODE(SEMI_AUTOMATIC).
In setup() you’d only do this

...
uint32_t msDelay;

void setup()
{
  WiFi.connect();
  msDelay = millis();
  while(!WiFi.ready() && (millis() - msDelay) < 10000)
  {
    Particle.process();
    delay(100);  // Oops forgot the parameter at first
  }
  ...
}

In one of the next firmware releases the cloud service will be running in a seperate thread, but for the time being in AUTOMATIC mode your code will be blocked if the cloud connection gets lost.
But even with the multithreaded system firmware using a suitable SYSTEM_MODE should be considered good style.


I’d also rather got for

    pinMode(buttonPin, INPUT_PULLDOWN); //button as input

to avoid a floating pin when the button is not pressed.


If you experience difficulties with OTA flashing with your code, this might be due to your use of delay() (expecially 30000).
You could consider using non-blocking approaches.

1 Like

Thanks so much for the tips!

So I understand what SYSTEM_MODE(SEMI_AUTOMATIC) and the WiFi.connect(); this is saying that when starting up connect to WiFi but only activity connect to the cloud when needing to send data (correct?)

I also had to modify delay(); to delay(100);

I’m also looking at non-blocking approaches to the delay :smile:

1 Like