2 A traffic light for an intersection of a
3 highway and a country road. Normally, the light
4 should be green for the highway and red for the
5 country road, but when traffic approaches on
6 the country road, the highway gets a red light
7 and the country road gets a green light.
9 When a light turns red it transitions from green to
10 red it goes through yellow, but a red light changing
11 to green transitions directly to green.
13 A pushbutton represents a car approaching on
16 Implement the solution with a Finite State
19 Following the excellent description at
20 http://hacking.majenko.co.uk/finite-state-machine
21 first break down the problem into states.
23 Identify which states are Transitional (T) and
24 which are Static (S). A Static state is one in
25 which the FSM is waiting for stimulus, and is
26 taking no actions. A Transitional State is a
27 state which causes actions, but doesn't look
30 A Transitional State runs once and immediately
31 moves on to a Static State.
33 State 0: highway = green, country = red; (T)
34 State 1: wait for car on country road (S)
35 State 2: highway = yellow, make note of current time (T)
36 State 3: wait for yellow time to pass (S)
37 State 4: highway = red, country = green, make note of current time (T)
38 State 5: wait for highway red time to pass (S)
39 State 6: country = yellow, make note of current time (T)
40 state 7: wait for yellow time to pass (S) then go to 0
43 // Use names for states so it's easier to
44 // understand what the code is doing
45 const int S_HIGHWAYGREEN = 0;
46 const int S_WAITCARCOUNTRY = 1;
47 const int S_HIGHWAYYELLOW = 2;
48 const int S_WAITHIGHWAYYELLOW = 3;
49 const int S_HIGHWAYRED = 4;
50 const int S_WAITHIGHWAYRED = 5;
51 const int S_COUNTRYYELLOW = 6;
52 const int S_WAITCOUNTRYYELLOW = 7;
55 const int countrySensorPin = 2;
57 const int highwayGreenLEDPin = 3;
58 const int highwayYellowLEDPin = 4;
59 const int highwayRedLEDPin = 5;
61 const int countryGreenLEDPin = 6;
62 const int countryYellowLEDPin = 7;
63 const int countryRedLEDPin = 8;
67 pinMode(highwayGreenLEDPin, OUTPUT);
68 pinMode(highwayYellowLEDPin, OUTPUT);
69 pinMode(highwayRedLEDPin, OUTPUT);
70 pinMode(countryGreenLEDPin, OUTPUT);
71 pinMode(countryYellowLEDPin, OUTPUT);
72 pinMode(countryRedLEDPin, OUTPUT);
78 // start off with the highway getting green
79 // The keyword "static" makes sure the variable
80 // isn't destroyed after each loop
81 static int state = S_HIGHWAYGREEN ;
83 // To store the current time for delays
84 static unsigned long ts;
89 // Highway gets green, country road red
90 digitalWrite( highwayGreenLEDPin, HIGH);
91 digitalWrite( highwayYellowLEDPin, LOW);
92 digitalWrite( highwayRedLEDPin, LOW);
94 digitalWrite( countryGreenLEDPin, LOW);
95 digitalWrite( countryYellowLEDPin, LOW);
96 digitalWrite( countryRedLEDPin, HIGH);
98 state = S_WAITCARCOUNTRY;
102 case S_WAITCARCOUNTRY:
104 if ( digitalRead (countrySensorPin) == HIGH) {
105 state = S_HIGHWAYYELLOW;
110 case S_HIGHWAYYELLOW:
111 digitalWrite( highwayGreenLEDPin, LOW);
112 digitalWrite( highwayYellowLEDPin, HIGH);
113 digitalWrite( highwayRedLEDPin, LOW);
115 digitalWrite( countryGreenLEDPin, LOW);
116 digitalWrite( countryYellowLEDPin, LOW);
117 digitalWrite( countryRedLEDPin, HIGH);
119 ts = millis(); // Remember the current time
121 state = S_WAITHIGHWAYYELLOW; // Move to the next state
125 case S_WAITHIGHWAYYELLOW:
126 // If two seconds have passed, then move on to the next state.
127 if (millis() > ts + 2000)
129 state = S_HIGHWAYRED;
135 // Highway red, country road green
136 digitalWrite( highwayGreenLEDPin, LOW);
137 digitalWrite( highwayYellowLEDPin, LOW);
138 digitalWrite( highwayRedLEDPin, HIGH);
140 digitalWrite( countryGreenLEDPin, HIGH);
141 digitalWrite( countryYellowLEDPin, LOW);
142 digitalWrite( countryRedLEDPin, LOW);
144 ts = millis(); // Remember the current time
146 state = S_WAITHIGHWAYRED;
150 case S_WAITHIGHWAYRED:
152 // If five seconds have passed, then start
153 // transition to a red light for the country
155 if (millis() > ts + 5000)
157 state = S_COUNTRYYELLOW;
162 case S_COUNTRYYELLOW:
163 digitalWrite( highwayGreenLEDPin, LOW);
164 digitalWrite( highwayYellowLEDPin, LOW);
165 digitalWrite( highwayRedLEDPin, HIGH);
167 digitalWrite( countryGreenLEDPin, LOW);
168 digitalWrite( countryYellowLEDPin, HIGH);
169 digitalWrite( countryRedLEDPin, LOW);
171 ts = millis(); // Remember the current time
173 state = S_WAITCOUNTRYYELLOW;
177 case S_WAITCOUNTRYYELLOW:
179 // If two seconds have passed, then go
180 // back to the beginning with the highway
181 // getting the green light
182 if (millis() > ts + 2000)
184 state = S_HIGHWAYGREEN;
191 // other things could go on here, and they would not affect the timing
192 // of the traffic light