]> git.piffa.net Git - sketchbook_andrea/blob - advanced_projects/state_machine/semaforo_5_doppia_fsm/semaforo_5_doppia_fsm.ino
State machines
[sketchbook_andrea] / advanced_projects / state_machine / semaforo_5_doppia_fsm / semaforo_5_doppia_fsm.ino
1 /*
2    Semaforo RGB
3
4    Un singolo semaforo costruito col paradigma delle macchine a stato.
5    Viene utilizzato un oggetto della libreria common per gestire il LED.
6
7    Uno stimolo esterno rappresentato dalla pressione di un bottone
8    causa il passaggio di stato.
9
10    Implementata con millis() invece che con delay(),
11    sono stati aggiuntu due stati per meglio gestire lo stato yellow.
12
13    */
14
15 #include <common.h>
16 const byte input = 2; // PIN del bottone
17 int pausa = 3000;
18 long timer ;
19 enum states_available { // Stati della FMS
20     turn_green,    // Transizione
21     green,         // Statico
22     wait_button,   // Evento - Stimolo
23     turn_yellow,   // transizione
24     yellow,        // Statico
25     turn_red,      // transizione
26     red            // Statico
27 };
28
29 states_available FSM1  ;
30 states_available FSM2  ;
31
32
33 void setup() {
34   pinMode(input, INPUT_PULLUP);
35   Serial.begin(9600);
36   timer = millis();
37 }
38
39 RGBLed led1(11, 10, 9); //Istanziamo un oggetto led facente parte
40 RGBLed led2(8,7,6); //Istanziamo un oggetto led facente parte
41                        // della classe RGBLed
42
43 void loop() {
44 switch (FSM1) {
45     case turn_green :
46     led1.Green();    
47     FSM1 = green ;  // Setta il prossimo state
48     FSM2 = red ;    // Setta il prossimo state
49     break;
50
51     case green:
52     if (millis() > timer + pausa * 2/3) {
53     FSM1 = wait_button ;
54     timer = millis(); 
55     }
56     break;
57
58     case wait_button:
59     if (digitalRead(input) == LOW) { 
60     FSM1 = turn_yellow ; 
61     timer = millis();
62     delay(20); // Debouncing, si potrebbe fare con millis()
63     };
64
65     break;
66
67     case turn_yellow :
68     led1.Yellow();
69     FSM1 = yellow ;
70     break;
71
72     case yellow :
73     if (millis() > timer + pausa * 2/3) {
74         FSM1 = turn_red ;
75         timer = millis();
76     }
77     break;
78
79     case turn_red :
80     led1.Red();
81     FSM1 = red ;
82     FSM2 = turn_green ;
83     break;
84
85     case red :
86     break;
87
88     default:    // In caso di default si fa giallo lampeggiante
89     led1.Yellow();
90     delay(pausa/3);
91     led1.Off();
92     delay(pausa/3);
93     break;
94
95 }
96 switch (FSM2) {
97     case turn_green :
98     led2.Green();
99     FSM2 = green ; // Setta il prossimo state
100     break;
101
102     case green:
103     if (millis() > timer + pausa * 2/3) {
104     FSM2 = turn_yellow;
105     timer = millis(); 
106     }
107     break;
108
109     case turn_yellow :
110     led2.Yellow();
111     FSM2 = yellow ;
112     break;
113
114     case yellow :
115     if (millis() > timer + pausa / 3) {
116     FSM2 = turn_red ;
117     timer = millis(); 
118     }
119     break;
120
121     case turn_red :
122     FSM2 = red ;
123     FSM1 = turn_green;
124     break;
125
126     case red :
127     led2.Red(); // Aggiorniamo il LED in questo stato invece che nel precedente
128                 // per entrare nel primo ciclo di esecuzione con il LED rosso
129     break;
130
131     default:    // In caso di default si fa giallo lampeggiante
132     led2.Yellow();
133     delay(pausa/3);
134     led2.Off();
135     delay(pausa/3);
136     break;
137 }
138
139 Serial.print(millis()); 
140 Serial.print(" \t Stato attuale FSM1: ");
141 Serial.print(FSM1);
142 Serial.print(" - FSM2: ");
143 Serial.println(FSM2);
144 }
145
146 /* Domande:
147  1. E' piu' semplice ora inserire degli altri oggetti nello sketch?
148  2. Gli eventi sono condivisi? Le varie FSM hanno modo di scambiarsi
149     informazioni sui relativi stati?
150  3. Creare un dispatcher degli eventi al quale le varie FSM possono
151     riferirsi.
152 .
153 .
154 .
155 .
156 .
157 .
158 .
159 .
160 .
161 .
162   Soluzioni
163 1. Si, per quanto le 2 FSM non siano indipendenti l'una dall'altra.
164 2. No, c'e' un solo flusso degli eventi, il blocco di una delle FSM 
165    puo' causare lo stop di tutto il sistema.
166  */