Traffic Light Cross Intersection Help

Hello, first time poster, I have a project I need some initial guidance on.

I have a project to implement a traffic cross intersection using digital logic. It was initially to be done on a PLD chip with VHDL coding however that has since changed to being able to use an arduino.

My priority for the light exchange goes as follows:

Priority review of the light sequence: Highest priority is given to the default state which is Green for North-South & Red for E-W with all Left lanes not green. The next most priority is given to the E-W Left Turn lanes followed by a Green light for traffic traveling straight on Miller Parkway. Before returning to the default state, the Left Lanes for N-S have priority if a sufficient number of vehicles are waiting to turn (ie. 2 or more).

I have drawn up a preliminary state diagram to help my logic. I have attached this.

My question is more or less where to begin. My experience with arduino and C/C++ is pretty small. I began to test my general logic with some very simple general code.

int NSG = 13;         // N-S green light
int EWG = 12;         // E-W green light
int NSR = 11;         // N-S red light
int EWR = 10;         // E-W red light
int NST = 9;          // N-S turn light
int EWT = 8;          // E-W turn light
int incomingByte;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  pinMode(NSG, OUTPUT);
  pinMode(EWG, OUTPUT);
  pinMode(NSR, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (Serial.available()>0)
  {
    incomingByte = Serial.read();
    
    if (incomingByte == 'Z') {
      digitalWrite(NSG, LOW);
      digitalWrite(EWG, HIGH);
      digitalWrite(NSR, HIGH);
      digitalWrite(NST, LOW);
      digitalWrite(EWR, LOW);
      digitalWrite(EWT, LOW);
    }
    else if  (incomingByte == 'W') {
      digitalWrite(NSG, LOW);
      digitalWrite(EWG, HIGH);
      digitalWrite(NSR, HIGH);
      digitalWrite(EWR, HIGH);
      digitalWrite(NST, HIGH);
      digitalWrite(EWT, LOW);
    }
    else if (incomingByte == 'Y'){
      digitalWrite(NSG, LOW);
      digitalWrite(EWG, LOW);
      digitalWrite(NSR, HIGH);
      digitalWrite(EWR, HIGH);
      digitalWrite(NST, LOW);
      digitalWrite(EWT, HIGH);
      
    }
  }
}

Obviously when I input for example a 'Z' into my console it changes the LEDs to reflect a different state, and from there the logic changes. However, my code is not able to reflect that.

What techniques can I use to make this work? Is there some sort of way to store a collection of the LED states into one state and call that in my if statements to change the logic as it progresses from "state" to "state"?

Please let me know if my questions are unclear.

Thank you for any help.

Pillowe: Obviously when I input for example a 'Z' into my console it changes the LEDs to reflect a different state, and from there the logic changes. However, my code is not able to reflect that.

I don't understand the above quote. Do the LEDs change when you enter characters?

Pillowe: Is there some sort of way to store a collection of the LED states into one state and call that in my if statements to change the logic as it progresses from "state" to "state"?

Yes, there is way to do this.

I don't have any examples handy but it's very common to keep track of a number of states within a program.

Do you need to time how long various states are active?

When does a non-default state change back to the default state?

Once I understand things a bit better, I'll try to help with an example for one of the states you need to monitor.

Can you change the LED states by entering characters?

DuaneDegn: I don't understand the above quote. Do the LEDs change when you enter characters?

Can you change the LED states by entering characters?

Yes, right now I just have it changing the LEDs whenever I enter a character (Z,Y,W)

I'm just using W,X,Y,Z as my "inputs" for now. W corresponds to 2 cars in the N-S turn lane, X - 4 cars in the N-S straight lane, Y - 2 cars in the E-W turn lane, Z - 4 cars in the E-W straight lane

Pillowe: Yes, right now I just have it changing the LEDs whenever I enter a character (Z,Y,W)

I'm just using W,X,Y,Z as my "inputs" for now. W corresponds to 2 cars in the N-S turn lane, X - 4 cars in the N-S straight lane, Y - 2 cars in the E-W turn lane, Z - 4 cars in the E-W straight lane

That helps.

So what do you want to happen after you press W? The LEDs will light as you already have programmed, but do you want some sort of timer?

I certainly don't want to write your program but I'm willing to write part of it to get you started but I don't really understand what you want the program to do.

Absolutely, I wouldn't want you to write the program for me either I just need some help getting started.

So the logic of it is almost purely driven by the input W,X,Y, and Z. I want the default state of the LEDs to be N-S Green and everything else red or off so,

digitalWrite(NSG, HIGH); digitalWrite(EWG, LOW); digitalWrite(NSR, LOW); digitalWrite(NST, LOW); digitalWrite(EWR, HIGH); digitalWrite(EWT, LOW);

When I enter Z for example, it's inputting there is 4 cars waiting in the E-W straight lane.

So the LEDs change to,

digitalWrite(NSG, LOW); digitalWrite(EWG, HIGH); digitalWrite(NSR, HIGH); digitalWrite(NST, LOW); digitalWrite(EWR, LOW); digitalWrite(EWT, LOW);

that is the E-W green LED is turned on. and the N-S red light is also on.

However I want the state of the LEDs now to act as a different state and I want it to either change based on the input W,X,Y, or Z. OR go back to the default of N-S green if 24 seconds have elapsed and no inputs have been entered.

I hope I'm not too confusing.

Hi, What side of the road are you driving and in what country.

In the USA drive on RH side you can do RH turn against the traffic lights. Here in Australia drive on LH side, its illegal to do LH turn against the lights.

Tom... :)

TomGeorge: In the USA drive on RH side you can do RH turn against the traffic lights. Here in Australia drive on LH side, its illegal to do LH turn against the lights.

I'm USA so drive on RH side however I'm not going to incorporate RH turns against lights.

Gonna have some pissed off drivers behind you then! Stay off the road in rush hour 8)

CrossRoads: Gonna have some pissed off drivers behind you then! Stay off the road in rush hour 8)

Haha! As long as it's simpler for me I'll take a few pissed off drivers

I often find it hard to write "a little" of a program.

This certainly isn't the entire program and there's still a lot of work to do but it's also more code than I had intended to write.

There's a flag "timerActiveFlag" which indicates when a light timer is active. While this flag is set, the lights won't change state.

Once the interval being timed is complete, the "timerActiveFlag" will be zero and the function "checkFlags" will be called which will set a new timer interval and set the (hopefully) appropriate lights on and off.

The input no longer directly sets the lights. Instead the input sets flags.

const byte NSG = 13;         // N-S green light
const byte EWG = 12;         // E-W green light
const byte NSR = 11;         // N-S red light
const byte EWR = 10;         // E-W red light
const byte NST = 9;          // N-S turn light
const byte EWT = 8;          // E-W turn light

const unsigned long TWENTY_FOUR_SECONDS = 24000;
const unsigned long TEST_TIME = 10000;
//const unsigned long DEFAULT_TIME = TWENTY_FOUR_SECONDS; // Use as default when testing is done
const unsigned long DEFAULT_TIME = TEST_TIME; // Use while testing
const unsigned long TWO_NS_TURN_TIME = DEFAULT_TIME;
const unsigned long FOUR_NS_STRAIGHT_TIME = DEFAULT_TIME;
const unsigned long TWO_EW_TURN_TIME = DEFAULT_TIME;
const unsigned long FOUR_EW_STRAIGHT_TIME = DEFAULT_TIME;
const unsigned long NO_CARS_DEFAULT_TIME = DEFAULT_TIME / 2; // use a shorter time when there aren't cars waiting?
unsigned long activeInterval;
unsigned long systemTimer;

boolean twoNsTurnFlag = 0;
boolean fourNsStraightFlag = 0;
boolean twoEwTurnFlag = 0;
boolean fourEwStraightFlag = 0;

boolean timerActiveFlag = 0;

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(9600);

  pinMode(NSG, OUTPUT);
  pinMode(EWG, OUTPUT);
  pinMode(NSR, OUTPUT);
  pinMode(EWR, OUTPUT);
  pinMode(NST, OUTPUT);
  pinMode(EWT, OUTPUT);
}

void loop()
{
  if (timerActiveFlag)
  {
    checkTime();
  }
  else
  {
    checkFlags();
  }
  checkInput();
}

void checkTime()
{
  if (millis() - systemTimer >= activeInterval)
  {
    timerActiveFlag = 0;
  }
}

void checkInput()
{
  if (Serial.available() > 0)
  {
    byte incomingByte = Serial.read();

    if (incomingByte == 'Z')
    {
      fourEwStraightFlag = 1;
      Serial.println("fourEwStraightFlag set");
    }
    else if  (incomingByte == 'W')
    {
      twoNsTurnFlag = 1;
      Serial.println("twoNsTurnFlag set");
    }
    else if (incomingByte == 'Y')
    {
      twoEwTurnFlag = 1;
      Serial.println("twoEwTurnFlag set");
    }
    else if (incomingByte == 'X')
    {
      fourNsStraightFlag = 1;
      Serial.println("fourNsStraightFlag set");
    }
  }
}

void checkFlags()
// Only call this function when "timerActiveFlag"
// is zero.
{
  timerActiveFlag = 0; // not really needed
  if (fourEwStraightFlag)
  {
    digitalWrite(NSG, LOW);
    digitalWrite(EWG, HIGH);
    digitalWrite(NSR, HIGH);
    digitalWrite(NST, LOW);
    digitalWrite(EWR, LOW);
    digitalWrite(EWT, LOW);
    activeInterval = FOUR_EW_STRAIGHT_TIME;
    fourEwStraightFlag = 0;
    timerActiveFlag = 1;
    Serial.println("East/West Green");
  }
  else if (twoNsTurnFlag)
  {
    digitalWrite(NSG, LOW);
    digitalWrite(EWG, HIGH);
    digitalWrite(NSR, HIGH);
    digitalWrite(EWR, HIGH);
    digitalWrite(NST, HIGH);
    digitalWrite(EWT, LOW);
    activeInterval = TWO_NS_TURN_TIME;
    twoNsTurnFlag = 0;
    timerActiveFlag = 1;
    Serial.println("North/South Turn");
  }
  else if (twoEwTurnFlag)
  {
    digitalWrite(NSG, LOW);
    digitalWrite(EWG, LOW);
    digitalWrite(NSR, HIGH);
    digitalWrite(EWR, HIGH);
    digitalWrite(NST, LOW);
    digitalWrite(EWT, HIGH);
    activeInterval = TWO_EW_TURN_TIME;
    twoEwTurnFlag = 0;
    timerActiveFlag = 1; 
    Serial.println("East/West Turn");
  }
  else if (fourNsStraightFlag)
  {
    //set lights
    activeInterval = FOUR_NS_STRAIGHT_TIME;
    fourNsStraightFlag = 0;
    timerActiveFlag = 1;
    Serial.println("North/South Green");
  }
  else
  {
    // set default light states
    timerActiveFlag = 1;
    activeInterval = NO_CARS_DEFAULT_TIME;
    Serial.println("no active flags, default state");
  }
  if (timerActiveFlag)
  {
    systemTimer = millis();
  }
}

I didn't attempt to set any priorities. The priorities can be set by the order the "if" statements in the "checkFlags" method.

I'm hoping others will critique what I wrote.

There are definitely things I'd do differently if I were writing this for myself but I think the changes I'd make would make the code harder to follow.

Hopefully this will be enough to give you the idea of how to check states and to check inputs even when the inputs won't be acted on immediately.

TomGeorge: Here in Australia drive on LH side, its illegal to do LH turn against the lights.

So on important junctions, they have |375x500

and

Unfortunately, we strongly suspect local councillors receive kick-backs from whoever manufactures traffic lights. :roll_eyes:

Hi,

Unfortunately, we strongly suspect local councillors receive kick-backs from whoever manufactures traffic lights. :roll_eyes:

And roadside signs.

Tom… :slight_smile:

DuaneDegn: There are definitely things I'd do differently if I were writing this for myself but I think the changes I'd make would make the code harder to follow.

Hopefully this will be enough to give you the idea of how to check states and to check inputs even when the inputs won't be acted on immediately.

This is incredibly helpful! I've gone through and made a few changes to the priorities like you said and added a another state to it.

Now I'm trying to test the same code but with tact switches/push-buttons. I know the basic code for using a push button

const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
}

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
  } else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}

However I'm having trouble implementing a push button into the code for the project itself. I wish to change the input to change the state from entering a byte in the serial monitor to pushing a button on the board. I tried the following but it's having no effect at all when I press the push button.

const byte NSG = 13;         // N-S green light
const byte EWG = 12;         // E-W green light
const byte NSR = 11;         // N-S red light
const byte EWR = 10;         // E-W red light
const byte NST = 9;          // N-S turn light
const byte EWT = 8;          // E-W turn light
const byte TRAIN = 7;        // Train incoming light
const byte PUSHBUTTON = 2;   // Push button for testing input
int buttonState = 0;         // Variable for reading the pusbutton status

const unsigned long TWENTY_FOUR_SECONDS = 24000;
const unsigned long TEST_TIME = 10000;
//const unsigned long DEFAULT_TIME = TWENTY_FOUR_SECONDS; // Use as default when testing is done
const unsigned long DEFAULT_TIME = TEST_TIME; // Use while testing
const unsigned long TWO_NS_TURN_TIME = DEFAULT_TIME;
const unsigned long FOUR_NS_STRAIGHT_TIME = DEFAULT_TIME;
const unsigned long TWO_EW_TURN_TIME = DEFAULT_TIME;
const unsigned long FOUR_EW_STRAIGHT_TIME = DEFAULT_TIME;
const unsigned long TRAIN_INCOMING_TIME = DEFAULT_TIME;
const unsigned long NO_CARS_DEFAULT_TIME = DEFAULT_TIME / 2; // use a shorter time when there aren't cars waiting?
unsigned long activeInterval;
unsigned long systemTimer;

boolean twoNsTurnFlag = 0;
boolean fourNsStraightFlag = 0;
boolean twoEwTurnFlag = 0;
boolean fourEwStraightFlag = 0;
boolean trainincomingFlag = 0;

boolean timerActiveFlag = 0;

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(9600);

  pinMode(NSG, OUTPUT);
  pinMode(EWG, OUTPUT);
  pinMode(NSR, OUTPUT);
  pinMode(EWR, OUTPUT);
  pinMode(NST, OUTPUT);
  pinMode(EWT, OUTPUT);
  pinMode(PUSHBUTTON, INPUT);
}

void loop()
{
   if (timerActiveFlag)
  {
    checkTime();
  }
  else
  {
    checkFlags();
  }
  checkInput();
}

void checkTime()
{
  if (millis() - systemTimer >= activeInterval)
  {
    timerActiveFlag = 0;
  }
}

void checkInput()
{
   buttonState = digitalRead(PUSHBUTTON);
   if (Serial.available()>0)
      {
      byte incomingByte = Serial.read();
      
    if (buttonState = HIGH)
    {
      fourEwStraightFlag = 1;
      Serial.println("fourEwStraightFlag set");
    }
    /*else if  (incomingByte == 'W')
    {
      twoNsTurnFlag = 1;
      Serial.println("twoNsTurnFlag set");
    }
    //else if (incomingByte == 'Y')
    {
      twoEwTurnFlag = 1;
      Serial.println("twoEwTurnFlag set");
    }
    else if (incomingByte == 'X')
    {
      fourNsStraightFlag = 1;
      Serial.println("fourNsStraightFlag set");
    }
    else if (incomingByte == 'T')
    {
      trainincomingFlag = 1;
      Serial.println("Train incoming set");
    }*/
  }
}

void checkFlags()
// Only call this function when "timerActiveFlag"
// is zero.
{
  timerActiveFlag = 0; // not really needed
  if (fourEwStraightFlag)
  {
    digitalWrite(NSG, LOW);
    digitalWrite(EWG, HIGH);
    digitalWrite(NSR, HIGH);
    digitalWrite(NST, LOW);
    digitalWrite(EWR, LOW);
    digitalWrite(EWT, LOW);
    activeInterval = FOUR_EW_STRAIGHT_TIME;
    fourEwStraightFlag = 0;
    timerActiveFlag = 1;
    Serial.println("East/West Green");
  }
  else if (twoNsTurnFlag)
  {
    digitalWrite(NSG, LOW);
    digitalWrite(EWG, LOW);
    digitalWrite(NSR, HIGH);
    digitalWrite(EWR, HIGH);
    digitalWrite(NST, HIGH);
    digitalWrite(EWT, LOW);
    activeInterval = TWO_NS_TURN_TIME;
    twoNsTurnFlag = 0;
    timerActiveFlag = 1;
    Serial.println("North/South Turn");
  }
  else if (twoEwTurnFlag)
  {
    digitalWrite(NSG, LOW);
    digitalWrite(EWG, LOW);
    digitalWrite(NSR, HIGH);
    digitalWrite(EWR, HIGH);
    digitalWrite(NST, LOW);
    digitalWrite(EWT, HIGH);
    activeInterval = TWO_EW_TURN_TIME;
    twoEwTurnFlag = 0;
    timerActiveFlag = 1;
    Serial.println("East/West Turn");
  }
  else if (fourNsStraightFlag)
  {
    digitalWrite(NSG, HIGH);
    digitalWrite(EWG, LOW);
    digitalWrite(NSR, LOW);
    digitalWrite(EWR, HIGH);
    digitalWrite(NST, LOW);
    digitalWrite(EWT, LOW);
    activeInterval = FOUR_NS_STRAIGHT_TIME;
    fourNsStraightFlag = 0;
    timerActiveFlag = 1;
    Serial.println("North/South Green");
  }
  else if (trainincomingFlag)
  {
    digitalWrite(NSG, LOW);
    digitalWrite(EWG, LOW);
    digitalWrite(NST, LOW);
    digitalWrite(EWT, LOW);
    digitalWrite(NSR, HIGH);
    digitalWrite(EWR, HIGH);
    delay (2000);
    digitalWrite(NSR, LOW);
    digitalWrite(EWR, LOW);
    delay (2000);
    digitalWrite(NSR, HIGH);
    digitalWrite(EWR, HIGH);
    delay (2000);
    digitalWrite(NSR, LOW);
    digitalWrite(EWR, LOW);
    delay (2000);
    digitalWrite(NSR, HIGH);
    digitalWrite(EWR, HIGH);
    activeInterval = TRAIN_INCOMING_TIME;
    trainincomingFlag = 0;
    timerActiveFlag = 1;
    Serial.println("Train is incoming");
  }
  else
  {
    digitalWrite(NSG, HIGH);
    digitalWrite(EWG, LOW);
    digitalWrite(NSR, LOW);
    digitalWrite(EWR, HIGH);
    digitalWrite(NST, LOW);
    digitalWrite(EWT, LOW);
    timerActiveFlag = 1;
    activeInterval = NO_CARS_DEFAULT_TIME;
    Serial.println("no active flags, default state");
  }
  if (timerActiveFlag)
  {
    systemTimer = millis();
  }
}

Any advice on how to implement a pushbutton input would be great.

buttonState = digitalRead(PUSHBUTTON);
   if (Serial.available()>0)
      {
      byte incomingByte = Serial.read();
      
    if (buttonState = HIGH)

The code above only checks if "buttonState" is high if there is serial data available.

If you use "autoformat" under "tools" the code will be easier to read and you'll see how the code to check the button state doesn't execute unless there's data.

Do you want to use both button input and keyboard input?

DuaneDegn: The code above only checks if "buttonState" is high if there is serial data available.

Do you want to use both button input and keyboard input?

Oh, interesting. I want to use strictly button input now. I was originally using the keyboard input and I'm trying to transition to button input.

Pillowe: Oh, interesting. I want to use strictly button input now. I was originally using the keyboard input and I'm trying to transition to button input.

As the code is currently written, the button isn't checked without serial input.

I suggest changing the code to check the button(s) rather than serial input.

DuaneDegn: As the code is currently written, the button isn't checked without serial input.

I suggest changing the code to check the button(s) rather than serial input.

Well i did originally remove the serial check

void checkInput()
{
  buttonState = digitalRead(PUSHBUTTON);

  if (buttonState = HIGH)
  {
    fourEwStraightFlag = 1;
    Serial.println("fourEwStraightFlag set");
  }

However removing the

 if (Serial.available()>0)
    {
      byte incomingByte = Serial.read();

Removing this gives me an error when I try to verify and compile:

In function 'void loop()': Push_button_full_test:54: error: 'checkFlags' was not declared in this scope checkFlags(); ^

relating to the portion of the code:

void loop()
{
  if (timerActiveFlag)
  {
    checkTime();
  }
  else
  {
    checkFlags();
  }
  checkInput();
}

Any idea why it would give me this error?

Pillowe: Any idea why it would give me this error?

My guess is it's a problem with matching opening brackets with closing brackets.

Post the whole code and we can check.

const byte NSG = 13;         // N-S green light
const byte EWG = 12;         // E-W green light
const byte NSR = 11;         // N-S red light
const byte EWR = 10;         // E-W red light
const byte NST = 9;          // N-S turn light
const byte EWT = 8;          // E-W turn light
const byte TRAIN = 7;        // Train incoming light
const byte PUSHBUTTON = 2;   // Push button for testing input
int buttonState = 0;         // Variable for reading the pusbutton status

const unsigned long TWENTY_FOUR_SECONDS = 24000;
const unsigned long TEST_TIME = 10000;
//const unsigned long DEFAULT_TIME = TWENTY_FOUR_SECONDS; // Use as default when testing is done
const unsigned long DEFAULT_TIME = TEST_TIME; // Use while testing
const unsigned long TWO_NS_TURN_TIME = DEFAULT_TIME;
const unsigned long FOUR_NS_STRAIGHT_TIME = DEFAULT_TIME;
const unsigned long TWO_EW_TURN_TIME = DEFAULT_TIME;
const unsigned long FOUR_EW_STRAIGHT_TIME = DEFAULT_TIME;
const unsigned long TRAIN_INCOMING_TIME = DEFAULT_TIME;
const unsigned long NO_CARS_DEFAULT_TIME = DEFAULT_TIME / 2; // use a shorter time when there aren't cars waiting?
unsigned long activeInterval;
unsigned long systemTimer;

boolean twoNsTurnFlag = 0;
boolean fourNsStraightFlag = 0;
boolean twoEwTurnFlag = 0;
boolean fourEwStraightFlag = 0;
boolean trainincomingFlag = 0;

boolean timerActiveFlag = 0;

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(9600);

  pinMode(NSG, OUTPUT);
  pinMode(EWG, OUTPUT);
  pinMode(NSR, OUTPUT);
  pinMode(EWR, OUTPUT);
  pinMode(NST, OUTPUT);
  pinMode(EWT, OUTPUT);
  pinMode(PUSHBUTTON, INPUT);
}

void loop()
{
  if (timerActiveFlag)
  {
    checkTime();
  }
  else
  {
    checkFlags();
  }
  checkInput();
}

void checkTime()
{
  if (millis() - systemTimer >= activeInterval)
  {
    timerActiveFlag = 0;
  }
}

void checkInput()
{
  buttonState = digitalRead(PUSHBUTTON);

  if (buttonState = HIGH)
  {
    fourEwStraightFlag = 1;
    Serial.println("fourEwStraightFlag set");
  }
  /*else if  (incomingByte == 'W')
    {
    twoNsTurnFlag = 1;
    Serial.println("twoNsTurnFlag set");
    }
    //else if (incomingByte == 'Y')
    {
    twoEwTurnFlag = 1;
    Serial.println("twoEwTurnFlag set");
    }
    else if (incomingByte == 'X')
    {
    fourNsStraightFlag = 1;
    Serial.println("fourNsStraightFlag set");
    }
    else if (incomingByte == 'T')
    {
    trainincomingFlag = 1;
    Serial.println("Train incoming set");
    }*/
}
}

void checkFlags()
// Only call this function when "timerActiveFlag"
// is zero.
{
  timerActiveFlag = 0; // not really needed
  if (fourEwStraightFlag)
  {
    digitalWrite(NSG, LOW);
    digitalWrite(EWG, HIGH);
    digitalWrite(NSR, HIGH);
    digitalWrite(NST, LOW);
    digitalWrite(EWR, LOW);
    digitalWrite(EWT, LOW);
    activeInterval = FOUR_EW_STRAIGHT_TIME;
    fourEwStraightFlag = 0;
    timerActiveFlag = 1;
    Serial.println("East/West Green");
  }
  else if (twoNsTurnFlag)
  {
    digitalWrite(NSG, LOW);
    digitalWrite(EWG, LOW);
    digitalWrite(NSR, HIGH);
    digitalWrite(EWR, HIGH);
    digitalWrite(NST, HIGH);
    digitalWrite(EWT, LOW);
    activeInterval = TWO_NS_TURN_TIME;
    twoNsTurnFlag = 0;
    timerActiveFlag = 1;
    Serial.println("North/South Turn");
  }
  else if (twoEwTurnFlag)
  {
    digitalWrite(NSG, LOW);
    digitalWrite(EWG, LOW);
    digitalWrite(NSR, HIGH);
    digitalWrite(EWR, HIGH);
    digitalWrite(NST, LOW);
    digitalWrite(EWT, HIGH);
    activeInterval = TWO_EW_TURN_TIME;
    twoEwTurnFlag = 0;
    timerActiveFlag = 1;
    Serial.println("East/West Turn");
  }
  else if (fourNsStraightFlag)
  {
    digitalWrite(NSG, HIGH);
    digitalWrite(EWG, LOW);
    digitalWrite(NSR, LOW);
    digitalWrite(EWR, HIGH);
    digitalWrite(NST, LOW);
    digitalWrite(EWT, LOW);
    activeInterval = FOUR_NS_STRAIGHT_TIME;
    fourNsStraightFlag = 0;
    timerActiveFlag = 1;
    Serial.println("North/South Green");
  }
  else if (trainincomingFlag)
  {
    digitalWrite(NSG, LOW);
    digitalWrite(EWG, LOW);
    digitalWrite(NST, LOW);
    digitalWrite(EWT, LOW);
    digitalWrite(NSR, HIGH);
    digitalWrite(EWR, HIGH);
    delay (2000);
    digitalWrite(NSR, LOW);
    digitalWrite(EWR, LOW);
    delay (2000);
    digitalWrite(NSR, HIGH);
    digitalWrite(EWR, HIGH);
    delay (2000);
    digitalWrite(NSR, LOW);
    digitalWrite(EWR, LOW);
    delay (2000);
    digitalWrite(NSR, HIGH);
    digitalWrite(EWR, HIGH);
    activeInterval = TRAIN_INCOMING_TIME;
    trainincomingFlag = 0;
    timerActiveFlag = 1;
    Serial.println("Train is incoming");
  }
  else
  {
    digitalWrite(NSG, HIGH);
    digitalWrite(EWG, LOW);
    digitalWrite(NSR, LOW);
    digitalWrite(EWR, HIGH);
    digitalWrite(NST, LOW);
    digitalWrite(EWT, LOW);
    timerActiveFlag = 1;
    activeInterval = NO_CARS_DEFAULT_TIME;
    Serial.println("no active flags, default state");
  }
  if (timerActiveFlag)
  {
    systemTimer = millis();
  }
}

I commented out that portion of the check_inputs so that I could test just a single state with a single pushbutton.

DuaneDegn: My guess is it's a problem with matching opening brackets with closing brackets.

This is where I say "I told you so".

You have an extra closing bracket at the end of "checkInput".