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.

A post was split to a new topic: Can anyone here write a simple marine autopilot program?

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.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.