Noob learning, first time setting up FSM for a traffic light simulation

Hey Guys!

Looking for some help on the next part of setting up FSM to simulate a traffic light with a common anode RGB LED

Here is the code I have so far (which im not sure is 100% because I have to to create to states of operation)

int redLedPin = 10; //common anode RGB LED
int greenLedPin = 9; //common anode RGB LED
int normSwitchPin = 6; //when pressed button will start normal operation of a simulated traffic light
int failSwitchPin = 5; //when pressed button will start simulated failure loop

void setup(){
  pinMode(redLEDPin, OUTPUT);
  pinMode(greenLEDPin, OUTPUT);
  pinMode(normSwitchPin, INPUT_PULLUP);
  pinMode(failSwitchPin, INPUT_PULLUP);
}

void loop(){

Essentially what I want to do is when the normSwitchPin is pressed a state is achieved where the RGB will preform

state "n"

digitalWrite (greenLedPin, LOW) //for 5 seconds
digitalWrite (redLedPin, LOW) //for 5 seconds
digitalwrite (greenLedPin, HIGH) // for 10 seconds and the loop repeats

when failSwitchPin is pressed its moves to a state of "failure" (assuming the traffic light has failed) where this happens

state "f"

digitalWrite (redLedPin, LOW) //for one second
digitalWrite (redLedPin, HIGH)//for one second
//this loop continues indefinitely until state "n" is triggered by normSwitchPin

In my coding so far i've set the int and setup, but not sure where to start with creating the states of operation. I've read grumpy Mike's and a few others tutorials, but my brain doesn't want to make sense of it and neither of the tutorials show me how to create an infinite loop. I also took heliBob's advise and mapped out the states, the time they run for, and the method needed to exit. Still no go on making the code make sense to me. Been playing with this for three days now and I get compile error after error because none of my code is right.

Any advice on the next steps or improving the code I already have?

Love your help!!

Scan (or take a picture) of your state diagram and post it.

my brain doesn't want to make sense of it

Have you looked at my turnstile?

Jiggy-Ninja:
Scan (or take a picture) of your state diagram and post it.

For some reason I cant link the picture I have on my desktop. (comes up as a dead link)

anyways, the diagram is simple

State "n" which is normal and triggered by a tactile button (normSwitchPin) produces

greenLedPin LOW for 5 seconds

greenLedPin and redLedPin LOW for 5 Seconds

redLedPin Low for 10 seconds

this repeats indefinitely until exit is triggered by failSwitchPin or state "f"

in which

redLedPin runs LOW for 1 second and HIGH for 1 second, repeats indefinitely until state "n" is called for with normSwitchPin

that's the best way I can explain it.

JimboZA:

my brain doesn't want to make sense of it

Have you looked at my turnstile?

I took a look at it and it looks awesome, I'm just not sure how to translate that into what i'm doing, but I deff appreciate the direction!

For some reason I cant link the picture I have on my desktop. (comes up as a dead link)

I think you can only link to pix on a server: the interwebz don't know about your c drive. Rather go to Additional Options... under the text entry box and attach it.

edit:

Also I find it helpful then to turn the state diagram into a table like in my turnstile post and code, which shows the states you need to cater for, and the events that may occur. (Basically the diagram in a text form.)

Then I used ifs to look for combinations of "this state" coupled with "that event" and have transition code for each.

Not for a moment suggesting it's the only way, but it worked for me.

Here is the state diagram

I should have added, and size it to a few hundred k so it fits on the screen, not a few megs.....

Hopefully this is better

you can try something like this:

int redLedPin = 10; //common anode RGB LED
int greenLedPin = 9; //common anode RGB LED
int normSwitchPin = 6; //when pressed button will start normal operation of a simulated traffic light
int failSwitchPin = 5; //when pressed button will start simulated failure loop
int oldNormState;
int oldFailState;
int state;

void setup()
{
  Serial.begin(9600);
  pinMode(redLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT);
  pinMode(normSwitchPin, INPUT_PULLUP);
  pinMode(failSwitchPin, INPUT_PULLUP);
}

void loop()
{
  int normButtonState = digitalRead(normSwitchPin);
  {
    if (normButtonState)
    {
      if (normButtonState != oldNormState)
      {
        state = 0;
      }
    }
  }
  oldNormState = normButtonState;
  int failButtonState = digitalRead(failSwitchPin);
  {
    if (failButtonState)
    {
      if (failButtonState != oldFailState)
      {
        state = 1;
      }
    }
  }
  oldFailState = failButtonState;
  if (state == 0)
  {
    normFunction();
  }
  else if (state == 1)
  {
    failFunction();
  }
}

void normFunction()
{
  Serial.println(F("Normal State"));
}

void failFunction()
{
  Serial.println(F("Fail State"));
}

look at the BlinkWithoutDelay example in your IDE to manipulate your LEDs in the functions.

added: Serial.begin

mgttrottier:
Hopefully this is better

Yep...

Maybe you should look at this. On page 4 it shows a machine with 2 super-states: in your traffic light that would be your Normal and Fail super-states. Inside each of those super-states, you would have states of G, Y, R with transitions in between. That would basically be a graphical depiction of what you have written there.

Then for each of those N and F, extract a table showing the currentstate, event, transition and newstate like I did.

BTW it just struck me that you don't need 2 switches do you? 2 switches gives 4 possibilities, you only need 2 super states so 1 switch is enough. With the switch in one position (its normal position) you have Normal operation; press the switch for Fail.

WOW! I must have read over that five or six times before some of the code started to make sense.

I'm guessing setting an oldNormState and an oldFailState in the int part of the code gives it an idea of when it needs to terminate? or come back to it???

I'm also guessing that by creating int = state; later on in the code can indicate which state the program is actually in? I.E. in your code you have state = 0 and state = 1

Can the states be replaced by letters? It wouldn't matter it just makes it less taxing on my brain when I see state = f to indicate that it is running the failure state.

Also, im not sure in the code what the indicator for each state to run indefinitely is? is it the "!" before the "="?

Amazing info sir!!! I just have to compare the blink without code side by side and figure out how to command my LED

mgttrottier:
WOW! I must have read over that five or six times before some of the code started to make sense.

I'm guessing setting an oldNormState and an oldFailState in the int part of the code gives it an idea of when it needs to terminate? or come back to it???

no, it is a STATE CHANGE tool to determine if the pushbuttons were just pushed, not just pushed

I'm also guessing that by creating int = state; later on in the code can indicate which state the program is actually in? I.E. in your code you have state = 0 and state = 1

you got it

Can the states be replaced by letters? It wouldn't matter it just makes it less taxing on my brain when I see state = f to indicate that it is running the failure state.

try that...

Also, im not sure in the code what the indicator for each state to run indefinitely is? is it the "!" before the "="?

!= means "not equal"

Amazing info sir!!! I just have to compare the blink without code side by side and figure out how to command my LED

we can help with that too.

play with this for a while...

JimboZA:

BTW it just struck me that you don't need 2 switches do you? 2 switches gives 4 possibilities, you only need 2 super states so 1 switch is enough. With the switch in one position (its normal position) you have Normal operation; press the switch for Fail.

I wanted to use two switches one set for normal and one set for fail just because i'm difficult like that. It just always seemed a bit more organized to me when you can have a switch that does one function instead of one switch cycling through many functions.

I'm sure that adds to difficulty and some projects in the future will have its place for one button can do many, but for this one, I felt it was good to have two instead of one.

Mike

Fair enough except you have 2 states that your state machine doesn't cater for, but which could actually occur.

The states you want are these:

N true, F false: normal operation
N false, F true: failed operation

But what about these two, which are "nonsense" states in the logical scheme of things, but physically possible:

N false, F false
N true, F true.

With only one switch you get only these:

N true: normal operation
N false: failed operation

not to contradict but in my example, two buttons toggle only two possible 'states'

state changes often come from different inputs, this is an example of that.

Its my fault i'm mixing words.

I have two tactile buttons, not a switch. A switch would only require one for sure.

Once I get the code working on two tactile buttons I'll have to play with it and code in a switch instead of the buttons

I'd have gone for a spst switch: open = normal, close for fail

JimboZA:
I'd have gone for a spst switch: open = normal, close for fail

I definitely will try it!

Right now I'm having trouble comparing the code for blinkwithoutdelay in the IDE to the example BullDogLowell was so kind to provide as to where in the sequence I have to inject what my LED is doing since there is no delay().

I'm so used to writing a delay function in, but i'm not getting where to write a something Led LOW or HIGH,

why am I so slow to pick this up

mgttrottier:
why am I so slow to pick this up

You're not: part of the problem is that everyone starts off with blinking with delay, and so when we try to move away from that, to blink without delay, it's so difficult to get the blinkers off.

If you haven't watched this video yet, now might be the time.

FWIW the attached is my take on the state diagram with only 1 switch.