Railroad Crossing Gate issue

Hello everyone, Newbie at this whole thing. I watched a youtube video on how to put together the electronics on a Railroad Crossing Gate with flashing lights.

I got all the wires in the correct place, and the sketch does work. However, the servos go back to their original state within half a second or so, instead of slowly like they do coming down.

Enclosed is the sketch I am using... Can anyone tell me what I need to change to fix the issue? Like I said, I am new to this whole thing so if someone could tell me which lines I need to change that would help, or even just type the lines of code I need to change would be even better. Thank you for your help... Daniel Edwards

int sensePin1 = A0; //declares A0 as our sensor1 input
int sensePin2 = A1; //declares A1 as our sensor2 input
int Flash = 6; //control for our flasher board
#include<Servo.h>//adds servo control library
int flashcount;//count of flash cycles
int pos = 90; //start position for servos
Servo myservo;//names servo control

void setup() {
  Serial.begin(9600);//enables serial monitoring
  pinMode(Flash, OUTPUT);//establishing pin 6 as an output pin
  myservo.attach(9);//sets up pin 9 as our servo control
}

enum CROSSINGSTATES
{
  ST_OFF,
  ST_FLASHING1,
  ST_FLASHING2,
  ST_FLASHING3,
  ST_FLASHING4,
  ST_ON1,
  ST_ON2,
}; //Identifies our 7 crossing states

CROSSINGSTATES crossingState = ST_OFF;// default crossing state

void loop() {
  int valA1 = analogRead(sensePin1);//reads sensor 1
  int valA2 = analogRead(sensePin2);//reads sensor 2
  Serial.println(valA1);
  Serial.println(valA2);//prints values in serial monitor
  delay(200);

  switch (crossingState)
  {
    case ST_OFF:
      crossingoff(valA1, valA2);
      break;
    case ST_FLASHING1:
      crossingflashing1(valA1, valA2);
      break;
    case ST_FLASHING2:
      crossingflashing2(valA1, valA2);
      break;
    case ST_FLASHING3:
      crossingflashing3(valA1, valA2);
      break;
    case ST_FLASHING4:
      crossingflashing4(valA1, valA2);
      break;
    case ST_ON1:
      crossingon1(valA1, valA2);
      break;
    case ST_ON2:
      crossingon2(valA1, valA2);
      break;
  }
}

void crossingoff(int valA1, int valA2) {
  digitalWrite(Flash, LOW);//keeps power down on flasher board
  delay(200);
  flashcount = 0; //resets flashcounter
  if (valA1 > 200 && valA2 < 200) {
    crossingState = ST_FLASHING1;
  }//if sensePin1 is triggered
  if (valA1 < 200 && valA2 > 200) {
    crossingState = ST_FLASHING2;
  }//if sensePin2 is triggered
}

void crossingflashing1(int valA1, int valA2) {
  digitalWrite(Flash, HIGH);//turns on flasher board
  for (pos = 90; pos <= 180; pos += 1) //the servo goes from 90 to 180 degreesin steps of 1 degree
  {
    myservo.write(pos);//controls the servo
    delay(15);
    crossingState = ST_ON1;
  }
}

void crossingflashing2(int valA1, int valA2) {
  digitalWrite(Flash, HIGH);//turns on flasher board
  for (pos = 90; pos <= 180; pos += 1) //the servo goes from 90 to 180 degreesin steps of 1 degree
  {
    myservo.write(pos);//controls the servo
    delay(15);
    crossingState = ST_ON2;
  }
}

void crossingon1(int valA1, int valA2) {
  digitalWrite(Flash, HIGH); // keeps the flasher on
  delay(1000); //1 second delay
  flashcount++;//adds 1 to the flashcount
  if (valA1 < 200 && valA2 > 200) {
    flashcount = 0;
    crossingState = ST_FLASHING3; //switches to flashing 3 if the exit sensor is tripped
  }
  else if (valA1 > 200 && valA2 > 200 && flashcount > 5) {
    crossingState = ST_FLASHING4; //if the train is shorter than the distance between the crossing sensors or is sitting in between the sensors
  }
}

void crossingon2(int valA1, int valA2) {
  digitalWrite(Flash, HIGH); // keeps the flasher on
  delay(1000); //1 second delay
  flashcount++;//adds 1 to the flashcount
  if (valA1 > 200 && valA2 < 200) {
    flashcount = 0;
    crossingState = ST_FLASHING3; //switches to flashing 3 if the exit sensor is tripped
  }
  else if (valA1 > 200 && valA2 > 200 && flashcount > 5) {
    crossingState = ST_FLASHING4; //if the train is shorter than the distance between the crossing sensors or is sitting in between the sensors
  }
}

void crossingflashing3(int valA1, int valA2) {
  digitalWrite(Flash, HIGH); // keeps the flasher on
  delay(1000); //1 second delay
  flashcount++;//adds 1 to the flashcount
  if (valA1 > 200 && valA2 > 200 && flashcount > 5) {
    {
      for (pos = 180; pos >= 90; pos -= 1) // goes from 180 to 90 in increments of 1 degree
        myservo.write(pos);
      delay(15);
    }
    delay(1000);
    crossingState = ST_OFF;
  }
}

void crossingflashing4(int valA1, int valA2) {
  digitalWrite(Flash, HIGH); // keeps the flasher on
  delay(1000); //1 second delay
  flashcount++;//adds 1 to the flashcount
  if (valA1 < 200 || valA2 < 200) {
    flashcount = 0;
    crossingState = ST_FLASHING3;
  }
  else if (flashcount > 120) {
    {
    for (pos = 180; pos >= 90; pos -= 1) // goes from 180 to 90 in increments of 1 degree
      myservo.write(pos);
    delay(15);
  }
    crossingState = ST_OFF;
  }
}

Hello amelia2011

Welcome to the best Aruino forum ever :slight_smile:

For debugging the programme, I recommend using Serial.println(‘What is wants to know’); at points in the programme that may be of interest.

hth

Please, show your wiring diagram, including power supply.
Your code works (enough). Two analog input at some point allow the servo to move.

This code will delay for 15ms after each 1 degree step

for (pos = 90; pos <= 180; pos += 1) //the servo goes from 90 to 180 degreesin steps of 1 degree
  {
    myservo.write(pos);//controls the servo
    delay(15);
    crossingState = ST_ON2;
  }

This code will not delay 15ms after each 1 degree step. It will only delay for 15ms once after all the 1 degree steps have completed as fast as possible.

    for (pos = 180; pos >= 90; pos -= 1) // goes from 180 to 90 in increments of 1 degree
      myservo.write(pos);
    delay(15)

are the braces for the for loop including the delay correct in the following and in other places?

should it be

    {
    for (pos = 180; pos >= 90; pos -= 1)  {
        myservo.write(pos);
        delay(15);
     }
  }

Thank you so much for your help... I do not have a wiring diagram to share, Here is the link I got for the project... Adding Crossing gates to the Arduino Grade Crossing Sketch (youtube.com)

Here's a pic. Maybe a schematic can be drawn from this and the sketch.

         +---|EXT|--------|USB|---+
         |    PWR          A5/SCL |
         |                 A4/SDA |
         |          UNO      AREF |
         |                    GND |-------------------+
         | IOREF          SCK/D13 |                   |
         | RST             DI/D12 |                   |
         | 3V3             DO/D11~|                   |
         | +5V                D10~|                   |
         | GND                 D9~|-------------------|-+
     +---| GND                 D8 |     +---------+   | |
     |   | Vin                 D7 |     |  FLASH  |   | |
     |   |                     D6~|-----| +V   -V |---+ |
+----|---| A0                  D5~|     +---------+   | |
| +--|---| A1                  D4 |                   | |
| |  |   | A2             INT1/D3 |     +---------+   | |
| |  |   | A3             INT0/D2~|     | SERVO_1 |   | |
| |  |   | A4/DA  RS CK DI  TX>D1 |     |     GND |---+ |
| |  |   | A5/CL  GD D0 5V  RX<D0 |  +--| VCC SIG |---|-+
| |  |   +------------------------+  |  +---------+   | |
| |  |   +-----------+               |  +---------+   | |
| |  |   | 5VDC P.S. |               |  | SERVO_2 |   | |
| |  |   |           |               |  |     GND |---+ |
| |  +---| GND   VCC |--+------------+--| VCC SIG |-----+
| |  |   +-----------+  |               +---------+
| |  |   +-----------+  |
| |  |   |  sense_2  |  |
| |  +---| GND   VCC |--+
| +--|---| SIG       |  |
|    |   +-----------+  |
|    |   +-----------+  |
|    |   |  sense_1  |  |
|    +---| GND   VCC |--+
+--------| SIG       |
         +-----------+

Thank you very much.

Could you help me figure out how to make the crossing gates raise at the same rate they went down? I wounder if it is in the code maybe?? Could that be what is causing the issue?

Are the gates raising/lowering "first one, then the other" or one zooms up and the other lags?

The servos (crossing gates?) are attached to one pin (9). If you attached each servo to its own pin, you could measure the speed of each from "down" to "up" and again from "up" to "down" then find the proportional movement (if one move twice as fast, give it commands half as often, or give it half as big a step at the same time) to raise them at the same rate.

SEE POST #5... I think you missed an open brace "{" that might make the UP different from DOWN.

I tried that but here is the error message I got...

C:\Users\train\Documents\Arduino\Crossinggates2024\Crossinggates2024.ino: In function 'void crossingflashing4(int, int)':
C:\Users\train\Documents\Arduino\Crossinggates2024\Crossinggates2024.ino:150:27: error: expected '}' at end of input
crossingState = ST_OFF; }
^

exit status 1

Compilation error: expected '}' at end of input

Do you know what that stuff means? I have no idea. Thank you so much for your help
Can you tell me which line of code that would be at? I was down at the last section where I made those changes

Please, post your new program code for a look.

We will show you what is misplaced.

If this was a spelling error, the problem would be on line 150, character 27, but I suspect the movement or placement of the "brace" is in the wrong spot, creating an error after the new "brace" (so the line number is not true, rather indicating where the error effected the program next)

may be easier to understand the following

#include <Servo.h>

const byte PinServo    = 9;
const byte PinOut     =  6;
const byte PinSensorE = A1;
const byte PinSensorW = A0;

Servo servo;

bool sE,     sW;
bool sEprev, sWprev;

enum { Off = HIGH, On = LOW };
enum { Init, Open, West, East };
int state = Init;

char s [90];

// -----------------------------------------------------------------------------
const byte Thresh = 200;

bool
getSensor (
    bool st,
    byte pin )
{
    if (false == st)  {
        if (Thresh - 2 > analogRead (pin))  {
            st = true;          // active LOW
            sprintf (s, "getSensor: pin %d - active", pin);
            Serial.println (s);
        }
    }
    else if (Thresh + 2 < analogRead (pin))  {
            st = false;;
            sprintf (s, "getSensor: pin %d - deactive", pin);
            Serial.println (s);
        }

    return st;
}

// -----------------------------------------------------------------------------
const int GatePosDown = 90;
const int GatePosUp   = 180;
int gatePos = 0;

// -------------------------------------
void
closeGate ()
{

    if (GatePosDown != gatePos)  {
        servo.write (--gatePos);

        if (! (gatePos % 10))  {
            sprintf (s, "closeGate: gatePos %d", gatePos);
            Serial.println (s);
        }

        delay (50);
    }

    digitalWrite (PinOut, On);
}

// -------------------------------------
void
openGate ()
{
    if (GatePosUp != gatePos)  {
        servo.write (++gatePos);
        digitalWrite (PinOut, On);

        if (! (gatePos % 10))  {
            sprintf (s, "openGate: gatePos %d", gatePos);
            Serial.println (s);
        }

        delay (50);
    }
    else
        digitalWrite (PinOut, Off);
}

// -----------------------------------------------------------------------------
void
loop (void)
{
    sE = getSensor (sE, PinSensorE);
    sW = getSensor (sW, PinSensorW);

    switch (state) {
    case Init:
        servo.write (gatePos = GatePosUp);
        digitalWrite (PinOut, Off);
        state = Open;
        break;

    case Open:
        openGate ();

        if (sE)  {
            Serial.println ("loop: east sensor active, state = East");
            state = East;
        }
        else if (sW)  {
            Serial.println ("loop: west sensor active, state = West");
            state = West;
        }
        break;

    case East:
        closeGate ();

        if (sWprev && ! sW)     // wait for sensor falling edge
            state = Open;
        break;

    case West:
        closeGate ();

        if (sEprev && ! sE)     // wait for sensor falling edge
            state = Open;
        break;
    }

    sEprev = sE;
    sWprev = sW;

}

// -----------------------------------------------------------------------------
void
setup (void)
{
    Serial.begin (9600);

    pinMode (PinOut,     OUTPUT);
    pinMode (PinSensorE, INPUT_PULLUP);     // enable pullup
    pinMode (PinSensorW, INPUT_PULLUP);     // enable pullup

    servo.attach (PinServo);

    sEprev = getSensor (sE, PinSensorE);
    sWprev = getSensor (sW, PinSensorW);
}

It's a misplaced brace.

yes. as i pointed out. but i was lucky to notice at after tyying to clean up the code and remove many redunant comments.

i'll guess that the OP is having a hard time reading the code and fixing a problem, even after the error was pointed out. I think code that's a little less redundant may be easier to follow.

I forgot that part this time (got it right last time when I striked-out the windy part of my post).

That happens. I typeo, too. Another try and guidance might prove just right.

Again thank you as always. So If I copy and paste this code here, as in make a new sketch, that should take care of it? I apologize for not understanding any of this. I am a model railroader who wants to make my own stuff. I can handle a 75 foot long G scale train with no problem.. but this stuff I don't yet understand.

where would the misplaced brace go?

Post your code.

THANK YOU THANK YOU THANK YOU AND THANK YOU to all who have helped. This is perfect!!!!! So nice to know there are people out here to help a stranger. God bless you all.

This works perfect for the gate speeds on the servos... Is there a way to get the lights to begin to flash while the servos are in motion, and stay on until they stop moving up or down?