]> git.piffa.net Git - sketchbook_andrea/blob - advanced_projects/state_machine/semaphore/semaphore.ino
State machine e blinks con millis()
[sketchbook_andrea] / advanced_projects / state_machine / semaphore / semaphore.ino
1 /*
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.
8  
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.
12  
13 A pushbutton represents a car approaching on
14 the country road.
15  
16 Implement the solution with a Finite State
17 Machine or FSM.
18  
19 Following the excellent description at
20 http://hacking.majenko.co.uk/finite-state-machine
21 first break down the problem into states.
22  
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
28 for stimulus.
29  
30 A Transitional State runs once and immediately
31 moves on to a Static State.
32  
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
41 */
42  
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;
53  
54 // Pin numbers
55 const int countrySensorPin = 2;
56  
57 const int highwayGreenLEDPin = 3;
58 const int highwayYellowLEDPin = 4;
59 const int highwayRedLEDPin = 5;
60  
61 const int countryGreenLEDPin = 6;
62 const int countryYellowLEDPin = 7;
63 const int countryRedLEDPin = 8;
64  
65 void setup()
66 {
67   pinMode(highwayGreenLEDPin, OUTPUT);
68   pinMode(highwayYellowLEDPin, OUTPUT);
69   pinMode(highwayRedLEDPin, OUTPUT);
70   pinMode(countryGreenLEDPin, OUTPUT);
71   pinMode(countryYellowLEDPin, OUTPUT);
72   pinMode(countryRedLEDPin, OUTPUT);
73 }
74  
75 void loop()
76 {
77  
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 ;
82  
83   // To store the current time  for delays
84   static unsigned long ts;
85  
86   switch (state)
87   {
88     case S_HIGHWAYGREEN:
89       // Highway gets green, country road red
90       digitalWrite( highwayGreenLEDPin, HIGH);
91       digitalWrite( highwayYellowLEDPin, LOW);
92       digitalWrite( highwayRedLEDPin, LOW);
93  
94       digitalWrite( countryGreenLEDPin, LOW);
95       digitalWrite( countryYellowLEDPin, LOW);
96       digitalWrite( countryRedLEDPin, HIGH);
97  
98       state = S_WAITCARCOUNTRY;
99  
100       break;
101  
102     case S_WAITCARCOUNTRY:
103  
104       if ( digitalRead (countrySensorPin) == HIGH) {
105         state = S_HIGHWAYYELLOW;
106       }
107  
108       break;
109  
110     case S_HIGHWAYYELLOW:
111       digitalWrite( highwayGreenLEDPin, LOW);
112       digitalWrite( highwayYellowLEDPin, HIGH);
113       digitalWrite( highwayRedLEDPin, LOW);
114  
115       digitalWrite( countryGreenLEDPin, LOW);
116       digitalWrite( countryYellowLEDPin, LOW);
117       digitalWrite( countryRedLEDPin, HIGH);
118  
119       ts = millis();  // Remember the current time
120  
121       state = S_WAITHIGHWAYYELLOW;  // Move to the next state
122  
123       break;
124  
125     case S_WAITHIGHWAYYELLOW:
126       // If two seconds have passed, then move on to the next state.
127       if (millis() > ts + 2000)
128       {
129         state = S_HIGHWAYRED;
130       }
131  
132       break;
133  
134     case S_HIGHWAYRED:
135       // Highway red, country road green
136       digitalWrite( highwayGreenLEDPin, LOW);
137       digitalWrite( highwayYellowLEDPin, LOW);
138       digitalWrite( highwayRedLEDPin, HIGH);
139  
140       digitalWrite( countryGreenLEDPin, HIGH);
141       digitalWrite( countryYellowLEDPin, LOW);
142       digitalWrite( countryRedLEDPin, LOW);
143  
144       ts = millis();  // Remember the current time
145  
146       state = S_WAITHIGHWAYRED;
147  
148       break;
149  
150     case S_WAITHIGHWAYRED:
151  
152       // If five seconds have passed, then start
153       // transition to a red light for the country 
154       // road
155       if (millis() > ts + 5000)
156       {
157         state = S_COUNTRYYELLOW;
158       }
159  
160       break;
161  
162     case S_COUNTRYYELLOW:
163       digitalWrite( highwayGreenLEDPin, LOW);
164       digitalWrite( highwayYellowLEDPin, LOW);
165       digitalWrite( highwayRedLEDPin, HIGH);
166  
167       digitalWrite( countryGreenLEDPin, LOW);
168       digitalWrite( countryYellowLEDPin, HIGH);
169       digitalWrite( countryRedLEDPin, LOW);
170  
171       ts = millis();  // Remember the current time
172  
173       state = S_WAITCOUNTRYYELLOW;
174  
175       break;
176  
177     case S_WAITCOUNTRYYELLOW:
178  
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)
183       {
184         state = S_HIGHWAYGREEN;
185       }
186  
187       break;
188  
189   } // end of switch
190  
191   // other things could go on here, and they would not affect the timing 
192   // of the traffic light
193  
194 } // end of loop