]> git.piffa.net Git - sketchbook_andrea/blob - advanced_projects/state_machine/semaforo_4_doppio_single_FSM/semaforo_4_doppio_single_FSM.ino
de798b35e0d1751dffbaa74e54d4adb8e776e974
[sketchbook_andrea] / advanced_projects / state_machine / semaforo_4_doppio_single_FSM / semaforo_4_doppio_single_FSM.ino
1 /*
2    Semaforo RGB single FSM
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 - Schema per un led RGB: https://lab.piffa.net/schemi/rgb.jpg
16 - Schema per un bottone: https://www.arduino.cc/en/uploads/Tutorial/inputPullupButton.png
17    */
18
19 #include <common.h>
20 const byte input = 2; // PIN del bottone
21 int pausa = 3000;
22 long timer ;
23 boolean wait = 0; // Memoria bottone
24
25 enum states_available { // Stati della FMS
26     turn_green,    // Dinamico, transizione
27     green,         // Statico
28     yellow,        // Statico
29     turn_red,      // Dinamico, transizione
30     turn_sec_yellow,// Yellow per semaforo secondario
31     sec_yellow,     // Statico
32     red            // Statico
33 };
34
35 states_available state ;
36
37
38 void setup() {
39   pinMode(input, INPUT_PULLUP);
40   Serial.begin(9600);
41   timer = millis();
42 }
43
44 RGBLed led(11, 10, 9);      // Semaforo principale
45 RGBLed secondary(8,7,6);    // Semaforo secondario
46                        
47
48 void loop() {
49 switch (state) {
50     case turn_green :
51     led.Green();
52     secondary.Red() ;
53     state = green ; // Setta il prossimo state
54     break;
55
56     case green:
57         led.Green();
58         if (wait && (millis() - timer >= pausa * 2/3)) {
59             state = yellow;
60             timer = millis();
61         }
62
63         if (digitalRead(input) == LOW) {
64             wait = 1;
65         }
66         break;
67
68     case yellow :
69     led.Yellow();
70     if (millis() - timer >= pausa / 3) {
71     state = turn_red ;
72     wait = 0; 
73     timer += pausa / 3;
74     }
75     break;
76
77     case turn_red :
78     led.Red();
79     secondary.Green();
80     state = red ;
81     break;
82
83     case red :
84     if (millis() - timer >= pausa /3) {
85     state = turn_sec_yellow ;
86     timer += pausa /3 ;
87     }
88     break;
89
90     case turn_sec_yellow :
91     secondary.Yellow();
92     state = sec_yellow ;
93     break;
94
95     case sec_yellow :
96     if (millis() - timer >= pausa / 3) {
97     state = turn_green ;
98     timer += pausa /3;
99     }
100     break;
101
102     default:    // In caso di default si fa giallo lampeggiante
103     led.Yellow();
104     secondary.Yellow();
105     delay(pausa/3);
106     led.Off();
107     secondary.Off();
108     delay(pausa/3);
109     break;
110
111 }
112 Serial.print(millis()); 
113 Serial.print(" \t Stato attuale ");
114 Serial.println(state);
115
116 }
117
118 /* Domande:
119  1. E' agevole inserire degli altri semafori?
120  2. Provare a inserire un altro semafori implementando una FSM
121     separata.
122 .
123 .
124 .
125 .
126 .
127 .
128 .
129 .
130 .
131 .
132   Soluzioni
133 1. Be' bisogna ragionare sul loro comportamente in rapporto alla FSM principale,   diciamo che non e' un approccio plug and play.
134 2. Vedi esercizio successivo.
135  */