Need help on how to use IR sensor for quick and hold reading

I’m helping my son with a school project and I can’t find or create a code to work with IR sensor to turn on one led when sensor reads < 28 for quick reading, like a button and then turns on another led for when the sensor reads < 28 for 4 seconds

Any help would be greatly appreciated and my head is spinning in circles.

//I want to use a sensor to turn on one led for quick reading, like a button and then
//turn on another led for when the sensor reads < 28 for 4 seconds


#define buttonPin 0 // ir sensor
#define ledPin1 9 // digital output pin for LED 1 indicator
#define ledPin2 13 // digital output pin for LED 2 indicator

#define debounce 20 // ms debounce period to prevent flickering when pressing or releasing the button
#define holdTime 4000 // ms hold period: how long to wait for press+hold event

// Button variables
int buttonVal = 0; // value read from sensor
int buttonLast = 0; // buffered value of the button's previous state
long btnDnTime; // time the sensor read < 28
long btnUpTime; // time the sensor  read > 100
boolean ignoreUp = false; // whether to ignore the sensor release because the click+hold was triggered

// LED variables
boolean ledVal1 = false; // state of LED 1
boolean ledVal2 = false; // state of LED 2


//=================================================


void setup()
{

// Set sensor input pin
pinMode(buttonPin, INPUT);


// Set LED output pins
pinMode(ledPin1, OUTPUT);
digitalWrite(ledPin1, ledVal1);
pinMode(ledPin2, OUTPUT);
digitalWrite(ledPin2, ledVal2);

}


//=================================================


void loop()
{

// Read the state of the sensor
buttonVal = analogRead(buttonPin);

// Test for sensor pressed and store the down time
if (buttonVal < 28 && buttonLast > 100 && (millis() - btnUpTime) > long(debounce)) 

{
btnDnTime = millis();
}

// Test for button release and store the up time
if (buttonVal  > 100 && buttonLast < 28 && (millis() - btnDnTime) > long(debounce))

{
if (ignoreUp == false) event1();
else ignoreUp = false;
btnUpTime = millis();
}

// Test for button held down for longer than the hold time

if (buttonVal < 28 && (millis() - btnDnTime) > long(holdTime))

{
event2();
ignoreUp = true;
btnDnTime = millis();
}

buttonLast = buttonVal;

}


//=================================================
// Events to trigger by click and press+hold

void event1()
{
ledVal2 = !ledVal2;
digitalWrite(ledPin2, ledVal2);
}

void event2()
{
ledVal1 = !ledVal1;
digitalWrite(ledPin1, ledVal1);
}

Is this the logic you seek?

#define buttonPin 0
#define ledPin1 9 
#define ledPin2 13

#define holdTime 4000 

void setup()
{
  pinMode(buttonPin, INPUT);

  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
}

void loop()
{
  int buttonVal = analogRead(buttonPin);
  long hold = 0;
  long saveHold = millis();
  
  while((buttonVal < 28)&&(hold < holdTime)) 
  {
    hold = millis() - saveHold;
    buttonVal = analogRead(buttonPin);
    digitalWrite(ledPin1, HIGH);
  }
  
  digitalWrite(ledPin1, LOW);
  
  while((buttonVal < 28)&&(hold >= holdTime))
  {
    buttonVal = analogRead(buttonPin);
    digitalWrite(ledPin2, HIGH);
  }
  
  digitalWrite(ledPin2, LOW);
}

It compiles.
I removed debounce and other extraneous task unrelated to quick and hold.
This is just so you can understand what’s going on and implement the logic in your own way (with debounce etc…)

Thanks for your help. I kind of understand and it is working. But what I need the code to do is turn on the first led using the quick read of < 28 for 2 seconds and then if hold is two seconds turn off the first led and turn on the second for two seconds.

It’s a matter of translating an imaginary flow chart to coding syntax.
If you need ideas on coding syntax I recommend knowing the control structures.
http://arduino.cc/en/Reference/HomePage

#define buttonPin 0
#define ledPin1 9 
#define ledPin2 13

#define holdTime 2000 

void setup()
{
  pinMode(buttonPin, INPUT);

  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
}

void loop()
{
  int buttonVal = analogRead(buttonPin);
  long hold = 0;
  long saveHold = millis();
  boolean flag = false;
  
  if(buttonVal < 28) 
  {
    flag = true;
    while(hold < holdTime)
    {
      hold = millis() - saveHold;
      buttonVal = analogRead(buttonPin);
      digitalWrite(ledPin1, HIGH);
      if(buttonVal >= 28)
      {
        flag = false;
      }
    }
  }
  
  digitalWrite(ledPin1, LOW);
  
  if(flag)
  {
    hold = 0;
    saveHold = millis();
   
    while(hold < holdTime)
    {
      hold = millis() - saveHold;
      digitalWrite(ledPin2, HIGH);
    }
  }
  
  digitalWrite(ledPin2, LOW);
}

Thanks for your help, the code works great. My son and did try to read through the control structures and that’s how we came up with the if command but are usual codes also used delay commands. We looked at examples for hold button but got lost with the button commands and timing.

No that we have the code, how would we expand this for a third and fourth led with same timing? Would I just multiply the holdtime by 2 and then by 4 for a forth led?

 if(flag)
  {
    hold = 0;
    saveHold = millis();
   
    while(hold < holdTime*2)  // hold time x 2
    {
      hold = millis() - saveHold;
      digitalWrite(ledPin2, HIGH);
    }
  }
  
  digitalWrite(ledPin2, LOW);
}

The program flow should go like so:

  1. if buttonVal < 28, immediately turn on led1 for two seconds while checking that buttonVal is still under 28. *If you use delay you cannot check to see if it was continuously held
  2. if it was continuously held, turn a flag variable on.
  3. that variable turns on the next peice of code which is the second led, for two seconds.

If you want to add a 3rd and 4th led, repeat steps 2 and 3.

There are many ways to code this. Mine is probably the ugliest, but hopefully easiest to understand.

Just the loop part…

void loop()
{
  int buttonVal = analogRead(buttonPin);
  long hold = 0;
  long saveHold = millis();
  boolean flag1 = false;
  boolean flag2 = false;
  boolean flag3 = false;
  
  //for first LED
  if(buttonVal < 28) 
  {
    flag1 = true;
    while(hold < holdTime)
    {
      hold = millis() - saveHold;
      buttonVal = analogRead(buttonPin);
      digitalWrite(ledPin1, HIGH);
      if(buttonVal >= 28)
      {
        flag1 = false;
      }
    }
  }
  
  digitalWrite(ledPin1, LOW);
  
  //for second LED
  if(flag1)
  {
    hold = 0;
    saveHold = millis();
    flag2 = true;
    
    while(hold < holdTime)
    {
      hold = millis() - saveHold;
      digitalWrite(ledPin2, HIGH);
      if(buttonVal >= 28)
      {
        flag2 = false;
      }
    }
  }
    
  digitalWrite(ledPin2, LOW);
    
  //for third LED
  if(flag2)
  {
    hold = 0;
    saveHold = millis();
    flag3 = true;
    
    while(hold < holdTime)
    {
      hold = millis() - saveHold;
      digitalWrite(ledPin3, HIGH);
      if(buttonVal >= 28)
      {
        flag3 = false;
      }
    }
  }
  
  digitalWrite(ledPin3, LOW);
  
  //for fourth LED
  if(flag3)
  {
    hold = 0;
    saveHold = millis();
    
    while(hold < holdTime)
    {
      hold = millis() - saveHold;
      digitalWrite(ledPin4, HIGH);
    }
  }
  
  digitalWrite(ledPin4, LOW);
}

Thanks again for all your help.

We just tried the code and it works great for the first two leds but not third and fourth. The third and fourth leds lite up right after second without the sensor < 28 being active for 4 or 6 seconds

The way it works now is.
quick reading - led1 on for two seconds
reading after two seconds - led2 on for two seconds, then led3 on for two seconds and then led4 on for two seconds

Here’s how we need it to work
quick reading - led1 on for two seconds
2 second reading - led2 on for two seconds
4 second reading - led3 on for two seconds
6 second reading - led4 on for two seconds

Sorry if I wasn’t clear on what we’re trying to do with the third and fourth led.

#define buttonPin 0
#define ledPin1 9 
#define ledPin2 10
#define ledPin3 11
#define ledPin4 13

#define holdTime 2000 

void setup()
{
  pinMode(buttonPin, INPUT);
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(ledPin4, OUTPUT);
  
}
void loop()
{
  int buttonVal = analogRead(buttonPin);
  long hold = 0;
  long saveHold = millis();
  boolean flag1 = false;
  boolean flag2 = false;
  boolean flag3 = false;
  
  //for first LED
  if(buttonVal < 28) 
  {
    flag1 = true;
    while(hold < holdTime)
    {
      hold = millis() - saveHold;
      buttonVal = analogRead(buttonPin);
      digitalWrite(ledPin1, HIGH);
      if(buttonVal >= 28)
      {
        flag1 = false;
      }
    }
  }
  
  digitalWrite(ledPin1, LOW);
  
  //for second LED
  if(flag1)
  {
    hold = 0;
    saveHold = millis();
    flag2 = true;
    
    while(hold < holdTime)
    {
      hold = millis() - saveHold;
      digitalWrite(ledPin2, HIGH);
      if(buttonVal >= 28)
      {
        flag2 = false;
      }
    }
  }
    
  digitalWrite(ledPin2, LOW);
    
 
  //for third LED
  if(flag2)
  {
    hold = 0;
    saveHold = millis();
    flag3 = true;
    
    while(hold < holdTime)
    {
      hold = millis() - saveHold;
      digitalWrite(ledPin3, HIGH);
      if(buttonVal >= 28)
      {
        flag3 = false;
      }
    }
  }
  
  digitalWrite(ledPin3, LOW);
  
  //for fourth LED
  if(flag3)
  {
    hold = 0;
    saveHold = millis();
    
    while(hold < holdTime)
    {
      hold = millis() - saveHold;
      digitalWrite(ledPin4, HIGH);
    }
  }
  
  digitalWrite(ledPin4, LOW);
}

Have you tried to fix the problem? Have you tried a different approach?

Did you use Serial to debug? What's the value of buttonVal after you let go?

Serial.begin(9600); in setup() And Serial.println(buttonVal); in the areas of the code that you think makes sense to look at. Then run the code and open up serial window to look at results.

Sorry, I just don't want to do all the work. It's not my project. :)

This is missing from the code for all LEDs after the first one:

buttonVal = analogRead(buttonPin);

Thanks, I haven't had a chance to debug because my wife decided she wanted a web site this weekend. So I've been busy with learning wordpress. Weekends used to be a time for relaxation but now ...

Thanks, school project was a huge success. Now we're working on modifying the code. We trying to control how long each led is on for. In other words if you have 2 second reading turn led on for 4 seconds, if you have 4 second reading, turn on Led 1 for 4 seconds and then Led 2 on for 4 seconds.

We know the hold time defines the sensor reading and led on time but how do we break that apart?

Thanks