Photon breathing green

My photon breathes cyan for about 10 seconds, then starts breathing green. I am trying to log movement using a PIR sensor into google spreadsheets using IFTTT. The code works (and correctly logs) during those first ten second. My understanding of the problem is that I am not exiting the loop, but I can’t seem to identify the issue in my code. Help appreciated.

int sensor = D2;
unsigned long movement_time = 0;

void setup() {
    pinMode(sensor, INPUT);
}

void loop() {
    if (digitalRead(sensor) == HIGH)
    {
        if ((millis() + 120000) < movement_time)
        {
            Particle.publish("movement", "on");
            movement_time = millis();
        }
        else{
            
        }
    }
}

Do you get mutiple published messages?

The logic for the if statement is incorrect

Nope, it only publishes once. I will dance in front of the sensor for 10 seconds, it will add one row to my spreadsheet, then start breathing green.

OK I just noticed an even more fundamental problem - when I change the code around and flash it to the photon, my photon does not flash magenta. It keeps flashing green.

Breathing green means it has lost the connection to the cloud, thus programming it using the cloud isn’t going to work. Place your photon in safe mode, and try again, that should help.

Is this really the complete code? Since in the code above I’d not see an cause for this behaviour.

The most likely reason why your device dropps out the cloud (goes into breathing/blinking green) is that your code does not drop out of loop() often enough (at least once per 10sec).

BTW: To avoid signed/unsigned problems, I’d reword your timing condition like this

  if (millis() - movement_time > 120000)
  {
    ...
  }

And I’d agree with Kenneth, that the logic in your if statement is somewhat obscure.
I don’t even see why your code would publish the first time (let’s assume your code runs immediately (0 + 120000) < 0 will not be true for a long time - in fact using unsigned long it will never be true).

But even if you initialized movement_time for anything other than 0.
millis() will as good as always be greater or equal to movement_time, let alone millis() + 120000. So if you don’t intend to have a repetition time of 49+ days, you should go with the code above :wink:

1 Like

Thanks for the reply. My “if” statement logic was definitely messed up, but when I fixed that I was still having a weird issue where I started to get log entries exactly every 2 minute interval, regardless of whether or not there was motion. I’m not sure why, but the issue was fixed when I stored mills() in a variable at the beginning of each loop call, as opposed to using the function directly in the “if” boolean statement. This is my final complete program that is now working:

int sensor = D1;
unsigned long previous = 0;
const long interval = 60000;

void setup() {
    pinMode(sensor, INPUT);
}

void loop() {
        unsigned long current = millis();
        if (current - previous >= interval)
        {
            if (digitalRead(sensor) == HIGH)
            {
                Particle.publish("movement", "on");
                previous = current;
            }
        }
}

There should not be any difference in using the function call direct or using a variable.
I noticed that you also swapped the order of your if statements and you also changed the sensor pin.

What happens when you go back to using millis() direct with this code otherwise unaltered?

Just for “superstitious” reasons make your interval a const unsigned long too :wink:

You probably need some state change logic, or just use an interrupt. I think PIR sensors switch to high if motion is detected, then go low after a timeout of no motion. So checking for high every minute is going to miss any triggers in between, and just get lucky if it catches a high on the intervals.