Inserting IR sensor code into existing project

I have this existing project that I would like to modify.

existing, a push button counts and toggles through different combination of LEDS.

I would like to add a IR sensor that drops all LEDS to red when the sensor is HIGH.

where do I place the IR Sensor If statement?

[code]
// this constant won't change:
 const int  buttonPin = 7;    
 const int ledPinredTop = 4;      
 const int ledPinyellowTop = 3;       
 const int ledPingreenTop = 2;  
 const int ledPingreenBtm = 5;
 const int ledPinredBtm = 6;
 const int IRSensor = 8;
 
// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {
   // initialize the button pin as a input:
   pinMode(buttonPin, INPUT);
   // initialize the LED as an output:
   pinMode(ledPinredTop, OUTPUT);
   pinMode(ledPinyellowTop, OUTPUT); 
   pinMode(ledPingreenTop, OUTPUT); 
   pinMode(ledPingreenBtm, OUTPUT); 
   pinMode(ledPinredBtm, OUTPUT); 
   pinMode(IRSensor, INPUT); 
   // initialize serial communication:
   Serial.begin(9600);
}


void loop() {
   // read the pushbutton input pin:
   buttonState = digitalRead(buttonPin);

   // compare the buttonState to its previous state
   if (buttonState != lastButtonState) {
     // if the state has changed, increment the counter
     if (buttonState == HIGH) {
       // if the current state is HIGH then the button
       // wend from off to on:
       buttonPushCounter++;
       Serial.println("on");
       Serial.print("number of button pushes:  ");
       Serial.println(buttonPushCounter);

  
       
     } else {
       // if the current state is LOW then the button
       // wend from on to off:
       Serial.println("off");
     }
     // Delay a little bit to avoid bouncing
     delay(50);
   }
   // save the current state as the last state,
   //for next time through the loop
   lastButtonState = buttonState;



   

   //added
   if (buttonPushCounter == 1) {
     digitalWrite(ledPinredTop, LOW);
     digitalWrite(ledPinyellowTop, HIGH);
     digitalWrite(ledPingreenTop, HIGH);  //STOP - RED OVER RED
     digitalWrite(ledPinredBtm, LOW);
     digitalWrite(ledPingreenBtm, HIGH);
   } else if (buttonPushCounter == 2) {
     digitalWrite(ledPinredTop, HIGH);
     digitalWrite(ledPinyellowTop, HIGH);
     digitalWrite(ledPingreenTop, LOW);  //CLEAR - GREEN OVER RED
     digitalWrite(ledPinredBtm, LOW);
     digitalWrite(ledPingreenBtm, HIGH);
   } else if (buttonPushCounter == 3) {
     digitalWrite(ledPinredTop, HIGH);
     digitalWrite(ledPinyellowTop, LOW);
     digitalWrite(ledPingreenTop, HIGH);  //APPROACH DIVERGING - YELLOW OVER GREEN
     digitalWrite(ledPinredBtm, LOW);
     digitalWrite(ledPingreenBtm, HIGH);
   } else if (buttonPushCounter == 4) {
     digitalWrite(ledPinredTop, HIGH);
     digitalWrite(ledPinyellowTop, LOW);
     digitalWrite(ledPingreenTop, HIGH);  //APPROACH - YELLOW OVER RED
     digitalWrite(ledPinredBtm, HIGH);
     digitalWrite(ledPingreenBtm, LOW);
   
   }
   
   else {
     digitalWrite(ledPinredTop, HIGH);
     digitalWrite(ledPinyellowTop, LOW);
     digitalWrite(ledPingreenTop, HIGH);  //When it powers up and button has not been pushed.
     digitalWrite(ledPinredBtm, LOW);
     digitalWrite(ledPingreenBtm, HIGH);
     
     buttonPushCounter =0;
   }

}
[/code]

there are two leds which have a name containing the word "red" do you mean to switch on those two LEDs if the IR-receiver is high?

shall the red leds be switched on through a high-pulse and then stay on?
(for how how long?) should there be any possability to switch them off again?

or do you want to have the two red leds switched on as long as the IR-input is HIGH and whenever the IR-input is LOW the red leds shall be switched off?

best regards Stefan

Yes sir. I would like to turn on those two Reds and turn off the others regardless of the push button count.

The all red condition would only activate when the IR sensor detects an obstacle. As soon as the sensor is clear the LEDs can go back to their original indication.

Here are the IR sensors I purchased:

HiLetgo 10pcs IR Infrared Obstacle Avoidance Sensor Module for Arduino Smart Car Robot 3-Wire Reflective Photoelectric for Arduino Smart Car Robot Amazon.com

Thanks!
Kennedy

This additional information that is very important and changes the functionality compared to the description you have posted before.
Is this the final functionality that you want to have?

If Yes: you would insert an if-condition that checks for the IR-sensor-Input beeing high
pdeudo-code:
if (IR-sensor == HIGH)

digitalWrite(Red-leds HIGH)
digitalWrite(all other Leds LOW)

else // IR-sensor-Low
switch LEDS on/off as already programmed

best regards Stefan

Do I place the new IF state prior to the button counts? And do I tell all the LEDs to go HIGH (Off) in the “Else”?

  int statusSensor = digitalRead (IRSensor);
  
  if (statusSensor == 1)
    digitalWrite(ledPinredTop, LOW); 
    digitalWrite(ledPinredBtm, LOW);               digitalWrite(ledpingreenBtm, HIGH);
     digitalWrite(ledPinyellowTop, HIGH);
     digitalWrite(ledPingreenTop, HIGH); 

  }
  
  else
  {
    digitalWrite….???
  }
  
}

if (buttonPushCounter == 1)……

looks like a model RR signal controller. not sure about your use of a button.

if the IR sensor is active, shouldn't it set the signal LEDs and ignore the buttons? in other words, only look at the button count if the IR sensor is not active

consier

#undef MyHW     // my hardware
#ifdef MyHW
const int buttonPin         = A1;
const int IRSensor          = A2;

const int ledPinredTop      = 13;
const int ledPinyellowTop   = 12;
const int ledPingreenTop    = 11;
const int ledPinredBtm      = 10;
const int ledPingreenBtm    = 9;

#else
const int buttonPin         = 7;

const int ledPinredTop      = 4;
const int ledPinyellowTop   = 3;
const int ledPingreenTop    = 2;
const int ledPingreenBtm    = 5;
const int ledPinredBtm      = 6;
const int IRSensor          = 8;
#endif

// Variables will change:
int butCnt      = 0;
int butState;

enum { Off = HIGH, On = LOW };

// -----------------------------------------------------------------------------
struct Sig {
    byte    pinRed;
    byte    pinYellow;
    byte    pinGreen;
};

#define PinNone 0

Sig sigTop = { ledPinredTop, ledPinyellowTop, ledPingreenTop };
Sig sigBtm = { ledPinredBtm, PinNone,         ledPingreenBtm };

void
sig (
    Sig    &sig,
    byte    red,
    byte    yellow,
    byte    green )
{
    digitalWrite (sig.pinRed,    red);
    digitalWrite (sig.pinGreen,  green);
    if (PinNone != sig.pinYellow)
        digitalWrite (sig.pinYellow,  yellow);
}

// -----------------------------------------------------------------------------
enum { Stop, Clear, AppDiv, App };

void loop()
{
    byte but = digitalRead(buttonPin);
    if (butState != but) {
        butState = but;
        delay(10);

        if (LOW == but)
            butCnt++;
    }

    if (On == digitalRead (IRSensor))  {
        butCnt = 1;
    }

    switch (butCnt)  {
    case Stop:                      //STOP - RED OVER RED
        sig (sigTop, On,  Off, Off);
        sig (sigBtm, On,  Off, Off);
        break;

    case Clear:                     //CLEAR - GREEN OVER RED
        sig (sigTop, Off, Off, On);
        sig (sigBtm, On,  Off, Off);
        break;

    case AppDiv:                    //APPROACH DIVERGING - YELLOW OVER GREEN
        sig (sigTop, Off, On,  Off);
        sig (sigBtm, Off, Off, On);
        break;

    case App:                       //APPROACH - YELLOW OVER RED
        sig (sigTop, Off, On,  Off);
        sig (sigBtm, On,  Off, Off);
        break;

    default:
        butCnt = Stop;
        break;
    }
}

// -----------------------------------------------------------------------------
void setup() {
    pinMode(buttonPin, INPUT_PULLUP);
    butState = digitalRead (buttonPin);

    pinMode(IRSensor,  INPUT_PULLUP);

    // initialize the LED as an output:
    pinMode(ledPinredTop,    OUTPUT);
    pinMode(ledPinyellowTop, OUTPUT);
    pinMode(ledPingreenTop,  OUTPUT);
    pinMode(ledPingreenBtm,  OUTPUT);
    pinMode(ledPinredBtm,    OUTPUT);
    // initialize serial communication:
    Serial.begin(9600);
}

Yes you guessed it. I am trying to animate this signal in the photo. The IR sensors will be mounted directly under the signal cantilever. one sensor on each track.


g

You are correct I The buttons need to be ignored when the IR sensor is occupied.

const int buttonPin         = A1;
const int IRSensor          = A2;

const int ledPinredTop      = 13;
const int ledPinyellowTop   = 12;
const int ledPingreenTop    = 11;
const int ledPinredBtm      = 10;
const int ledPingreenBtm    = 9;

#else
const int buttonPin         = 7;

const int ledPinredTop      = 4;
const int ledPinyellowTop   = 3;
const int ledPingreenTop    = 2;
const int ledPingreenBtm    = 5;
const int ledPinredBtm      = 6;
const int IRSensor          = 8;

I am confused why are the LEDs and IR sensors being declared twice on different Pins?

Thanks!

the #if/#else#endif is a c preprocessor directive that allow me to easily select different blocks of code so that i can compile it for my HW while retaining yours

why don't you have additional IR sensors in the tracks after the turnout as well as an input for the turnout position to determine all the signal indications?

Ok so I need leave my current hardware into the pins I originally had?

Good question. My layout is a relatively small loop with long trains. The trains occupy too much of the track to separate into blocks. The train would always be running on approaches. I also do not have powered turnouts. All hand throw switches. So I do not have turnout position feedback. I personally like this level of reliability on the layout.

So what I was thinking was to manually select a signal indication at a control board with a push button. Then have the IR sensor do the "drop to red effect" to give it some realism. then when the train clears, it will return to the selected indication. This will allow me to sit back and just let the train run.

I know others that do resistor wheel sets on all there rolling stock and do occupancy detection. But I would prefer to stay away form the level of complexity.

Thanks!

using a single detector, you could indicate stop and once clear of the detector, indicates approach on a timer and clear when the timer expires.

some other mechanism, possibly a manual switch would be needed for approach-diverging

I don't know what "resistor wheel-sets" are
is there a gap between each wagon? this could be used to count up / down to have information about where the train is.

Another idea is a light-barrier that detects state-change from "light-detected" = no object between light-source and receiver to "no light" = object between light-source and receiver which indicates tran arrived at light-barrier

and that can detect state-change from "no light" to light-detected"
which indicates last wagon of train leaves light-barrier.

Same thing should be possible with an IR-sensor. detecting state-change

If you post a plan of your tracks and how long your trains are so that it becomes visible to "the forum".
The forum can analyse it and make suggestions how to get the maximum of information out of a small number of sensors to keep the hardware-complexity as low as possible.

Unpowered turnouts. hm well I think as long as you keep most things unpowered automating requires human action or a humanoid robot.

A way inbetween would be to add small magnets and reed-relay for turnout-feedback.

If you use a bus-system for powered actions like turnouts, lights etc. there will run only two wires along with your tracks where all components are connected to in parallel. The distinguishing to choose a particular turnout or light etc is then done through a device-number.
You send a command on the bus "device no 7 turn to possition B") etc.

best regards Stefan

1 Like

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