Programming led lightning under kitchen shelf

Hi everyone,
I successfully made an LED strip that lights up when a PIR sensor detect motion in the kitchen and it turns itself off after a few minutes. The thing is, I would like to learn about the millis function as it will keep looping instead of the delay function I’m using at the moment. So instead of turning off after the set delay, I’d rather have it reset the delay everytime the sensor catches some movement so I would not see the quick blink of the LED.

I don’t want to sound lazy but I have been trying different approach for a few hours now and could use some pointers, anything vague I could adapt to my code.

#define RED_PIN 5
#define GREEN_PIN 6
#define BLUE_PIN 3

int Brightness_R;
int Brightness_G;
int Brightness_B;
int PIR = 2;

void setup() {
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);
  pinMode(PIR, INPUT);    //sensor input

}

void loop() {

  if (digitalRead(PIR) == HIGH)
  {
    analogWrite (RED_PIN, Brightness_R = 255);
    analogWrite (GREEN_PIN, Brightness_G = 120);
    analogWrite (BLUE_PIN, Brightness_B = 45);
    delay(300000);
  }


  else
  {
    analogWrite (RED_PIN, Brightness_R = 0);
    analogWrite (GREEN_PIN, Brightness_G = 0);
    analogWrite (BLUE_PIN, Brightness_B = 0);
  }
}

Thanks everyone for your time reading through this.

See this simple millis() tutorial...

If I understand your problem correctly, if there isn't movement in the kitchen the lights will switch off and somebody has to move to switch them on again. If so, you will need to think differently; you need to 'delay' the switching off.

Your kitchen light can in that case be in one of three states if above description is correct; off, on and waiting to switch off after no movement, delay before switching off. You need a variable to keep track of the state.

#define RED_PIN 5
#define GREEN_PIN 6
#define BLUE_PIN 3

int Brightness_R;
int Brightness_G;
int Brightness_B;
int PIR = 2;
// state of the light: 0 = off (waiting for pir trigger), 1 = on, 2 = delay before switching off
byte lightState = 0;

...
...

The neater way is to use enums so you can use descriptive names for this.

enum LIGHTSTATES
{
  OFF,
  ON,
  DELAY,
};

#define RED_PIN 5
#define GREEN_PIN 6
#define BLUE_PIN 3

int Brightness_R;
int Brightness_G;
int Brightness_B;
int PIR = 2;
// the state of the light
LIGHTSTATES lightState = OFF;

You will also need a variable to hold the start time that the lights would go off and.
[code]#define RED_PIN 5
#define GREEN_PIN 6
#define BLUE_PIN 3

int Brightness_R;
int Brightness_G;
int Brightness_B;
int PIR = 2;

// the state of the light
LIGHTSTATES lightState = OFF;
// keep track when the lights would go
uint32_t startTime;
...
...

In below I use a switch/case to do specific actions in the specific states.
1)
If the system is in the OFF state, a movement will switch the lights on and next the system will switch to the ON state.
2)
If the system is in the ON state, a 'no movement' will start a timer for the delay before the lights will be switched off and next the system will switch to the DELAY state. If movement was detected, it will
3)
If the system is in the DELAY state, it will check if there has been movement; if so, it will switch back to the ON state (canceling the delay). If there was no movement, it will check the time that has lapsed since no movement was detected and if 300 seconds has passed; if that's the case, the lights will be switched off and the system will switch to the OFF state.

void loop()
{
  // check the PIR trigger
  byte trigger = digitalRead(PIR);

  switch (lightState)
  {
    case OFF:
      // if a movement was detected
      if (trigger == HIGH)
      {
        // switch on the lights
        analogWrite (RED_PIN, Brightness_R = 255);
        analogWrite (GREEN_PIN, Brightness_G = 120);
        analogWrite (BLUE_PIN, Brightness_B = 45);

        // and go to next state
        lightState = ON;
      }
      break;
    case ON:
      // if no movement detected
      if (trigger == LOW)
      {
        // start the timer
        startTime = millis();

        // and switch to the delay state
        lightState = DELAY;
      }
      break;
    case DELAY:
      // if a new movement was detected, cancelling the delay
      if (trigger == HIGH)
      {
        // go back to the ON state
        lightState = ON;
      }
      else
      {
        // if it's time to switch off
        if (millis() - startTime >= 300000UL)
        {
          // switch off the lights
          analogWrite (RED_PIN, Brightness_R = 0);
          analogWrite (GREEN_PIN, Brightness_G = 0);
          analogWrite (BLUE_PIN, Brightness_B = 0);

          // and go to the OFF state waiting for a trigger
          lightState = OFF;
        }
      }
      break;
  }
}

Study it and use it if you understand it; else ask.

Code compiles but is not tested.

Note: movement in the above description and code might not be the correct word.

hi,

take a look into this tutorial. compared to the "standard"-tutorial it is pretty compact

best regards Stefan

Thank you sterretje,
I've learned a lot reading your code. I've written it all instead of copy/paste to practice and I've set the delay lower for testing purpose. It's working perfectly as intended.
I did not think of this simpler approach but I'll remember how easier it is to keep track of things if you add multiple state.

Thanks for linking the millis tutorial, I'm bookmarking it.