]> git.piffa.net Git - sketchbook_andrea/blob - advanced_projects/state_machine/semaforo_4_doppio/semaforo_4_doppio.ino
State machines
[sketchbook_andrea] / advanced_projects / state_machine / semaforo_4_doppio / semaforo_4_doppio.ino
1 /*
2    Semaforo RGB
3
4
5    Doppio semaforo, una via prinicipale (led) e una secondaria (secondary):
6    la via secondaria ottiene la precedenza alla pressione di un bottone.
7
8    Implementata con millis() invece che con delay(),
9    sono stati aggiuntu due stati per gestire lo stato yellow 
10    del semafor secondario.
11
12    Lo sketch e' stato implementato con una sola FSM in cui si incrociano
13    gli stati dei due semafori.
14
15    */
16
17 #include <common.h>
18 const byte input = 2; // PIN del bottone
19 int pausa = 3000;
20 long timer ;
21 enum states_available { // Stati della FMS
22     turn_green,    // Dinamico, transizione
23     green,         // Statico
24     wait_button,   // Evento - Stimolo
25     turn_yellow,      // Dinamico, transizione
26     yellow,            // Statico
27     turn_red,      // Dinamico, transizione
28     turn_sec_yellow,  // Yellow per semaforo secondario
29     sec_yellow,
30     red            // Statico
31 };
32
33 states_available state  ;
34
35
36 void setup() {
37   pinMode(input, INPUT_PULLUP);
38   Serial.begin(9600);
39   timer = millis();
40 }
41
42 RGBLed led(11, 10, 9);      // Semaforo principale
43 RGBLed secondary(8,7,6);    // Semaforo secondario
44                        
45
46 void loop() {
47 switch (state) {
48     case turn_green :
49     led.Green();
50     secondary.Red() ;
51     state = green ; // Setta il prossimo state
52     break;
53
54     case green:
55     if (millis() > timer + pausa * 2/3) {
56     state = wait_button ;
57     timer = millis(); 
58     }
59     break;
60
61     case wait_button:
62     if (digitalRead(input) == LOW) { 
63     state = turn_yellow ; // Il passaggio di stato avviene alla pressione di un bottone
64     delay(20); // Debouncing, si potrebbe fare con millis()
65     timer = millis();
66     };
67
68     break;
69
70     case turn_yellow :
71     led.Yellow();
72     state = yellow ;
73     break;
74
75     case yellow :
76     if (millis() > timer + pausa / 3) {
77     state = turn_red ;
78     timer = millis(); 
79     }
80     break;
81
82     case turn_red :
83     led.Red();
84     secondary.Green();
85     state = red ;
86     break;
87
88     case red :
89     if (millis() > timer + pausa /3) {
90     state = turn_sec_yellow ;
91     timer = millis(); 
92     }
93     break;
94
95     case turn_sec_yellow :
96     secondary.Yellow();
97     state = sec_yellow ;
98     break;
99
100     case sec_yellow :
101     if (millis() > timer + pausa / 3) {
102     state = turn_green ;
103     timer = millis(); 
104     }
105     break;
106
107     default:    // In caso di default si fa giallo lampeggiante
108     led.Yellow();
109     secondary.Yellow();
110     delay(pausa/3);
111     led.Off();
112     secondary.Off();
113     delay(pausa/3);
114     break;
115
116 }
117 Serial.print(millis()); 
118 Serial.print(" \t Stato attuale ");
119 Serial.println(state);
120
121 }
122
123 /* Domande:
124  1. E' agevole inserire degli altri semafori?
125  2. Provare a inserire un altro semafori implementando una FSM
126     separata.
127 .
128 .
129 .
130 .
131 .
132 .
133 .
134 .
135 .
136 .
137   Soluzioni
138 1. Be' bisogna ragionare sul loro comportamente in rapporto alla FSM principale,   diciamo che non e' un approccio plug and play.
139 2. Vedi esercizio successivo.
140  */