I need help writing a fairly basic if/else statement

Hello, new to Arduino.

I am using this photo eye.

If the sensor is detecting an object for > 10 seconds, I would like for it to turn on an LED. I am OK with the wiring but am not sure how to write the code. I believe that I will need to use a timer function? If the sensor is turning on/off every couple of seconds, I'd like the LED to remain off, but if it is sensing an object for > 10 seconds, LED goes on. Thank you.

Welcome to the group.


Always show us a good schematic of your proposed circuit.

Show us a good image of your ‘actual’ wiring.

Give links to components.


Show us your attempt at writing the code.

Draw a flow chart of your idea, put it in words...

  1. Is an object detected?
    no - go to 1.
    yes - start a timer.
  2. Is timer greater than 10 seconds
    no - go to 1
    yes - set LED on.

Then put your words into a program.

Using millis() for non-blocking timing tutorials:
Blink without delay().
Blink without delay detailed explanation
Beginner's guide to millis().
Several things at a time.

Thank you for the feedback. Here is my code so far:

const int MOTION_SENSOR_PIN = 7;   // Arduino pin connected to the OUTPUT pin of motion sensor
const int LED_PIN           = 3;   // Arduino pin connected to LED's pin
int motionStateCurrent      = LOW; // current  state of motion sensor's pin
int motionStatePrevious     = LOW; // previous state of motion sensor's pin
unsigned long startMillis;  //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 5000;  //the value is a number of milliseconds

void setup() {
  Serial.begin(9600);                // initialize serial
  pinMode(MOTION_SENSOR_PIN, INPUT); // set arduino pin to input mode
  pinMode(LED_PIN, OUTPUT);          // set arduino pin to output mode
  startMillis = millis();  //initial start time
}

void loop() {
  motionStatePrevious = motionStateCurrent;             // store old state
  motionStateCurrent  = digitalRead(MOTION_SENSOR_PIN); // read new state

 currentMillis = millis();
//  if (currentMillis - startMillis >= period)  //test whether the period has elapsed
  //{
    //digitalWrite(LED_PIN, !digitalRead(LED_PIN));  //if so, change the state of the LED.  Uses a neat trick to change the state
  //  startMillis = currentMillis;  //IMPORTANT to save the start time of the current LED state.
  

  if (motionStatePrevious == LOW && motionStateCurrent == HIGH && currentMillis - startMillis >= period) { // pin state change: LOW -> HIGH
  
    Serial.println("Motion detected!");
    digitalWrite(LED_PIN, HIGH); // turn on
    //startMillis = currentMillis;
 // }
  }
  else
  if (motionStatePrevious == HIGH && motionStateCurrent == LOW) { // pin state change: HIGH -> LOW
    Serial.println("Motion stopped!");
    digitalWrite(LED_PIN, LOW);  // turn off
  }
}

It...kind of works. If I place my hand in front of the sensor for 5 seconds or more, the LED will go on AFTER I remove my hand. I'd like for it to go off as soon as it hits 5 seconds. I also have to work out how to reset the timer. It also doesn't require a consecutive 5 second count. I can place my hand for 1 second, remove it, 1 second hand, five times and the LED will go off. Any guidance? Thank you.

Always show us a good schematic of your proposed circuit.

Show us a good image of your ‘actual’ wiring.

Give links to components.

Review what is done in this example.

Add to or remove code as needed.

//
//  Version   YY/MM/DD     Comments
//  =======   ========     ========================================================
//  1.00      22/08/25     Running code
//
//

#define CLEAR                     HIGH
#define DETECTED                  LOW

#define ledON                     HIGH
#define ledOFF                    LOW

enum FlagStates {ENABLED, EXPIRED, DISABLED};

const byte heartbeatLED         = 13;
const byte MOTION_SENSOR_PIN    = 7;
const byte LED_PIN              = 3;

FlagStates motionFlag           = DISABLED;

byte lastMotion                 = CLEAR;

unsigned long heartbeatTime;
unsigned long sensorTime;
unsigned long motionTime;

const unsigned long period      = 5000;


//                                      s e t u p ( )
//********************************************^************************************************
void setup()
{
  Serial.begin(9600);

  pinMode(MOTION_SENSOR_PIN, INPUT_PULLUP);

  pinMode(LED_PIN, OUTPUT);
  pinMode(heartbeatLED, OUTPUT);

} //END of   setup()


//                                       l o o p ( )
//********************************************^************************************************
void loop()
{
  //*********************************                         h e a r t b e a t   T I M E R
  //is it time to toggle the heartbeatLED (every 500ms)?
  if (millis() - heartbeatTime >= 500ul)
  {
    //restart this TIMER
    heartbeatTime = millis();

    //toggle the heartbeatLED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

  //*********************************                         s e n s o r   T I M E R
  //is it time to check the sensors (every 50ms)?
  if (millis() - sensorTime >= 50ul)
  {
    //restart this TIMER
    sensorTime = millis();

    checkSensors();
  }

  //*********************************                         m o t i o n   T I M E R
  //is the TIMER enabled ?
  if (motionFlag == ENABLED)
  {
    //has the interval expired ?
    if (millis() - motionTime >= period)
    {
      //we have finished with this event
      motionFlag = EXPIRED;

      Serial.println("Motion TIMER has expired");

      digitalWrite(LED_PIN, ledON);
    }
  }

  //*********************************
  //other non blocking code goes here
  //*********************************

} //END of   loop()


//                                 c h e c k S e n s o r s ( )
//********************************************^************************************************
void checkSensors()
{
  byte currentState;

  //*********************************                         MOTION_SENSOR_PIN
  currentState = digitalRead(MOTION_SENSOR_PIN);

  //did the sensor change state ?
  if (lastMotion != currentState)
  {
    //update to the new state
    lastMotion = currentState;

    //if we are not timing, is there an object ?
    if (motionFlag == DISABLED && currentState == DETECTED)
    {
      Serial.println("Detected");

      //enable TIMER
      motionFlag = ENABLED;

      //reset this TIMER
      motionTime = millis();
    }

    else
    {
      Serial.println("Clear");

      //disable TIMER
      motionFlag = DISABLED;

      digitalWrite(LED_PIN, ledOFF);
    }

  } //END of this sensor

  //*********************************

} //END of checkSensors()


//********************************************^************************************************

EDIT, added Serial prints

This accomplishes exactly what I was looking for. I am going to try and understand what the code is actually doing. Appreciate it!

I got this code proven out with small LEDs but am now looking to use an industrial grade LED that requires 18-24VDC. I understand Arduino does not play nice with high voltages - is this where I need to incorporate a MOSFET? I am a little confused on the differences between relays, MOSFETs, and transistors...

Give us a link to the LEDs.

This is the LED.

Thanks!

Unfortunately, I made a royal mistake. I tried wiring the MOSFET on my own before looking at/understanding your schematic and fried my laptop. My power supply was reading 8 VDC and knowing the LED requires more I cranked it up to 15 and noticed smoke coming from the Arduino. I figured I destroyed the Arduino but then realized my laptop had turned off. Obviously I wired something incorrectly.

Looks like this project is on hold until I can figure out if my laptop is repairable. Thanks for your help thus far.

Revisiting this topic after many months. The light I linked above is PNP only - may I ask why your diagram has callouts for two lights (one PNP and one NPN)? The entire project only has one light which is OFF in all states unless a JAM is detected and then it turns on. Thank you.

Both were shown in the schematic to demonstrate the two different options you can have.