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.....
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.