Project in progress
Block Detection 3 Aspect Light Control

Block Detection 3 Aspect Light Control © GPL3+

This is a simple IR sensor block detector for model railroads. It controls three lights: red, yellow and green.

  • 2,742 views
  • 12 comments
  • 17 respects

Components and supplies

Apps and online services

About this project

I have many hobbies including model trains, electronics and 4 welling in my Jeep. I am not a very good programmer. I was intrigued by the capabilities of the Arduino and wanted to make something practical so I could learn some programming skills. So I chose this as a starting place.

I used the Arduino UNO because it was cheep and easy to use. The Arduino community was very helpful. One person wrote a program to do what I wanted and from that I studied what the program did and how it run. I changed it from using analog inputs to using IR detectors to give a HIGH or LOW input to the Arduino.

Code

BLOCK DETECTION 3 ASPECT LIGHT CONTROLArduino
This is my BLOCK DETECTION 3 ASPECT LIGHT CONTROL program. It detecets the train entering and leaving a block of track and changes the lights accordingly.
// initilize the Digital input pins
int sensePin1 = 7;
int sensePin2 = 4;
//Initilize the OUTPUT pins for the RED,GREEN and YELLOW lights.
int ledPinGRN = 10;
int ledPinYEL = 11;
int ledPinRED = 12;



void setup() {
  analogReference(DEFAULT); //isn't necessary
  Serial.begin(9600);
  pinMode(ledPinGRN, OUTPUT);//Set pin MODES for lights
  pinMode(ledPinYEL, OUTPUT);//Set pin MODES for lights
  pinMode(ledPinRED, OUTPUT);//Set pin MODES for lights

}

enum LIGHTSTATES
{
  ST_GREEN,       // light green
  ST_YELLOWFLASH, // light yellow flash
  ST_YELLOW,      // yellow on for given time
  ST_RED,         // light red
  ST_RED1,         // light red
};

// state of statemachine for block 1; initial value green
LIGHTSTATES block1State = ST_GREEN;

// current time
static unsigned long currentTime;

void loop()
{
  // get current time
  currentTime = millis();

  // read sensors
  
  int valA1 = digitalRead(sensePin1);
  int valA2 = digitalRead(sensePin2);


  //Serial.print('valA1');
  //Serial.println("");
  //Serial.print('valA2');
  //Serial.println("");
   //Serial.println("");
     //delay(1500);
  switch (block1State)
  {
    // show green light
    // we will switch to red if sensors are triggered
    case ST_GREEN:
      block1Green(valA1, valA2);
      break;
    case ST_YELLOWFLASH:
      block1YellowFlash(valA1, valA2);
      break;
    case ST_YELLOW:
      block1Yellow(valA1, valA2);
      break;
    case ST_RED:
      block1Red(valA1, valA2);
      break;
      case ST_RED1:
      block1Red1(valA1, valA2);
      break;
  }
}

/*
  switch green light on for block 1
  'wait' for sensors to trigger and switches to red
  input: values of sensors A1 and A2
*/
void block1Green(int valA1, int valA2)
{
  digitalWrite(ledPinGRN, LOW);
  digitalWrite(ledPinYEL, HIGH);
  digitalWrite(ledPinRED, HIGH);

  if (valA1 == LOW && valA2 == HIGH)
  {
    // change state to red
    block1State = ST_RED;}
  else if (valA1 == HIGH && valA2 == LOW)
  {
    // change state to red
    block1State = ST_RED1;
  }
  }


/*
  flash yellow led 10 times for block 1
  after that, switch to steady yellow
  input: values of sensors A1 and A2; both are not used but added for consistency in the calls to the light functions
*/
void block1YellowFlash(int valA1, int valA2)
{
  // on and off duration
  const unsigned long duration = 500;
  // number of flashes
  const byte numFlashes = 10;

  // remember last time that we changed from 'yellow on' to 'yellow off' or vice versa
  static unsigned long startTime = 0;
  // keep a counter for the number of flashes
  static byte counter = 0;

  // if called after coming from red
  if (startTime == 0)
  {
    // switch yellow on
    digitalWrite(ledPinGRN, HIGH);
    digitalWrite(ledPinYEL, LOW);
    digitalWrite(ledPinRED, HIGH);

    // start timing
    startTime = currentTime;

    // nothing else to do
    return;
  }

  // if it's time to toggle the yellow led
  // based on blink without delay
  if (currentTime - startTime >= duration)
  {
    // set start time
    startTime += duration;

    // toggle the yellow led
    digitalWrite(ledPinYEL, !digitalRead(ledPinYEL));

    // increment the counter
    counter++;
  }

  if (counter > numFlashes * 2)
  {
    // reset variables
    // as a result, the next time this function is called, the sequence is started from scratch
    startTime = 0;
    counter = 0;

    // change state to steady yellow
    block1State = ST_YELLOW;
  }
}

/*
  switch yellow light on for N seconds for block 1
  after that, switch to green
  input: values of sensors A1 and A2; both are not used but added for consistency in the calls to the light functions
*/
void block1Yellow(int valA1, int valA2)
{
  // duration for yellow on
  const unsigned long duration = 2000;
  // start time of delay
  static unsigned long startTime = 0;

  if (startTime == 0)
  {
    // switch yellow on
    digitalWrite(ledPinGRN, HIGH);
    digitalWrite(ledPinYEL, LOW);
    digitalWrite(ledPinRED, HIGH);

    // set start time of delay
    startTime = currentTime;

    // nothing else to do
    return;
  }

  // if N milliseconds passed
  if (currentTime - startTime >= duration)
  {
    // reset variables so next call to this sequence will start sequence from scratch
    startTime = 0;
    // change state to green
    block1State = ST_GREEN;
  }
}

/*
  switch red light on for block1
  'wait' for sensors to trigger and switches to yellow flash
  input: values of sensors A1 and A2
*/
void block1Red(int valA1, int valA2)
{
  digitalWrite(ledPinGRN, HIGH);
  digitalWrite(ledPinYEL, HIGH);
  digitalWrite(ledPinRED, LOW);
  if (valA1 == HIGH && valA2 == LOW)
  {
    // change state to yellow flash
    block1State = ST_YELLOWFLASH;
  }
}
void block1Red1(int valA1, int valA2)
{
  digitalWrite(ledPinGRN, HIGH);
  digitalWrite(ledPinYEL, HIGH);
  digitalWrite(ledPinRED, LOW);
  if (valA1 == LOW && valA2 == HIGH)
  {
    // change state to yellow flash
    block1State = ST_YELLOWFLASH;
  }

}
IR Block DetectorArduino
Block detection for model trains.
// initilize the Digital input pins
int sensePin1 = 7;
int sensePin2 = 4;
//Initilize the OUTPUT pins for the RED,GREEN and YELLOW lights.
int ledPinGRN = 10;
int ledPinYEL = 11;
int ledPinRED = 12;



void setup() {
  analogReference(DEFAULT); //isn't necessary
  Serial.begin(9600);
  pinMode(ledPinGRN, OUTPUT);//Set pin MODES for lights
  pinMode(ledPinYEL, OUTPUT);//Set pin MODES for lights
  pinMode(ledPinRED, OUTPUT);//Set pin MODES for lights

}

enum LIGHTSTATES
{
  ST_GREEN,       // light green
  ST_YELLOWFLASH, // light yellow flash
  ST_YELLOW,      // yellow on for given time
  ST_RED,         // light red
  ST_RED1,         // light red
};

// state of statemachine for block 1; initial value green
LIGHTSTATES block1State = ST_GREEN;

// current time
static unsigned long currentTime;

void loop()
{
  // get current time
  currentTime = millis();

  // read sensors
  
  int valA1 = digitalRead(sensePin1);
  int valA2 = digitalRead(sensePin2);


  //Serial.print('valA1');
  //Serial.println("");
  //Serial.print('valA2');
  //Serial.println("");
   //Serial.println("");
     //delay(1500);
  switch (block1State)
  {
    // show green light
    // we will switch to red if sensors are triggered
    case ST_GREEN:
      block1Green(valA1, valA2);
      break;
    case ST_YELLOWFLASH:
      block1YellowFlash(valA1, valA2);
      break;
    case ST_YELLOW:
      block1Yellow(valA1, valA2);
      break;
    case ST_RED:
      block1Red(valA1, valA2);
      break;
      case ST_RED1:
      block1Red1(valA1, valA2);
      break;
  }
}

/*
  switch green light on for block 1
  'wait' for sensors to trigger and switches to red
  input: values of sensors A1 and A2
*/
void block1Green(int valA1, int valA2)
{
  digitalWrite(ledPinGRN, LOW);
  digitalWrite(ledPinYEL, HIGH);
  digitalWrite(ledPinRED, HIGH);

  if (valA1 == LOW && valA2 == HIGH)
  {
    // change state to red
    block1State = ST_RED;}
  else if (valA1 == HIGH && valA2 == LOW)
  {
    // change state to red
    block1State = ST_RED1;
  }
  }


/*
  flash yellow led 10 times for block 1
  after that, switch to steady yellow
  input: values of sensors A1 and A2; both are not used but added for consistency in the calls to the light functions
*/
void block1YellowFlash(int valA1, int valA2)
{
  // on and off duration
  const unsigned long duration = 500;
  // number of flashes
  const byte numFlashes = 10;

  // remember last time that we changed from 'yellow on' to 'yellow off' or vice versa
  static unsigned long startTime = 0;
  // keep a counter for the number of flashes
  static byte counter = 0;

  // if called after coming from red
  if (startTime == 0)
  {
    // switch yellow on
    digitalWrite(ledPinGRN, HIGH);
    digitalWrite(ledPinYEL, LOW);
    digitalWrite(ledPinRED, HIGH);

    // start timing
    startTime = currentTime;

    // nothing else to do
    return;
  }

  // if it's time to toggle the yellow led
  // based on blink without delay
  if (currentTime - startTime >= duration)
  {
    // set start time
    startTime += duration;

    // toggle the yellow led
    digitalWrite(ledPinYEL, !digitalRead(ledPinYEL));

    // increment the counter
    counter++;
  }

  if (counter > numFlashes * 2)
  {
    // reset variables
    // as a result, the next time this function is called, the sequence is started from scratch
    startTime = 0;
    counter = 0;

    // change state to steady yellow
    block1State = ST_YELLOW;
  }
}

/*
  switch yellow light on for N seconds for block 1
  after that, switch to green
  input: values of sensors A1 and A2; both are not used but added for consistency in the calls to the light functions
*/
void block1Yellow(int valA1, int valA2)
{
  // duration for yellow on
  const unsigned long duration = 2000;
  // start time of delay
  static unsigned long startTime = 0;

  if (startTime == 0)
  {
    // switch yellow on
    digitalWrite(ledPinGRN, HIGH);
    digitalWrite(ledPinYEL, LOW);
    digitalWrite(ledPinRED, HIGH);

    // set start time of delay
    startTime = currentTime;

    // nothing else to do
    return;
  }

  // if N milliseconds passed
  if (currentTime - startTime >= duration)
  {
    // reset variables so next call to this sequence will start sequence from scratch
    startTime = 0;
    // change state to green
    block1State = ST_GREEN;
  }
}

/*
  switch red light on for block1
  'wait' for sensors to trigger and switches to yellow flash
  input: values of sensors A1 and A2
*/
void block1Red(int valA1, int valA2)
{
  digitalWrite(ledPinGRN, HIGH);
  digitalWrite(ledPinYEL, HIGH);
  digitalWrite(ledPinRED, LOW);
  if (valA1 == HIGH && valA2 == LOW)
  {
    // change state to yellow flash
    block1State = ST_YELLOWFLASH;
  }
}
void block1Red1(int valA1, int valA2)
{
  digitalWrite(ledPinGRN, HIGH);
  digitalWrite(ledPinYEL, HIGH);
  digitalWrite(ledPinRED, LOW);
  if (valA1 == LOW && valA2 == HIGH)
  {
    // change state to yellow flash
    block1State = ST_YELLOWFLASH;
  }

}

Comments

Similar projects you might like

How to control your light switch from your smartphone?

Project in progress by Mahmoud Ahmed

  • 22,609 views
  • 3 comments
  • 15 respects

Light Control Using Arduino and Amazon Alexa

Project tutorial by Rajesh

  • 12,225 views
  • 1 comment
  • 14 respects

Control your light with Arduino

Project tutorial by GiorgioTraverso

  • 1,810 views
  • 0 comments
  • 2 respects

WIZnet S2E Light Control

Project tutorial by Team S2ELighting

  • 1,448 views
  • 0 comments
  • 7 respects

Servo Control with TV Remote Control

Project showcase by eldo85

  • 5,594 views
  • 5 comments
  • 17 respects
Add projectSign up / Login