]> git.piffa.net Git - sketchbook_andrea/blob - advanced_projects/state_machine/semaforo_4_doppio_single_FSM/semaforo_4_doppio_single_FSM.ino
be9bb0482cac8210850a25cf695dc17e4ebebf04
[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 enum states_available { // Stati della FMS
24     turn_green,    // Dinamico, transizione
25     green,         // Statico
26     wait_button,   // Evento - Stimolo
27     turn_yellow,      // Dinamico, transizione
28     yellow,            // Statico
29     turn_red,      // Dinamico, transizione
30     turn_sec_yellow,  // Yellow per semaforo secondario
31     sec_yellow,
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     if (millis() - timer => pausa * 2/3) {
58     state = wait_button ;
59     timer += pausa * 2/3 ;
60     }
61     break;
62
63     case wait_button:
64     if (digitalRead(input) == LOW) { 
65     delay(20); // Debouncing, si potrebbe fare con millis()
66     state = turn_yellow ; // Il passaggio di stato avviene alla pressione di un bottone
67     timer = millis();
68     };
69
70     break;
71
72     case turn_yellow :
73     led.Yellow();
74     state = yellow ;
75     break;
76
77     case yellow :
78     if (millis() - timer >= pausa / 3) {
79     state = turn_red ;
80     timer += pausa / 3;
81     }
82     break;
83
84     case turn_red :
85     led.Red();
86     secondary.Green();
87     state = red ;
88     break;
89
90     case red :
91     if (millis() - timer >= pausa /3) {
92     state = turn_sec_yellow ;
93     timer += pausa /3 ;
94     }
95     break;
96
97     case turn_sec_yellow :
98     secondary.Yellow();
99     state = sec_yellow ;
100     break;
101
102     case sec_yellow :
103     if (millis() - timer >= pausa / 3) {
104     state = turn_green ;
105     timer += pausa /3;
106     }
107     break;
108
109     default:    // In caso di default si fa giallo lampeggiante
110     led.Yellow();
111     secondary.Yellow();
112     delay(pausa/3);
113     led.Off();
114     secondary.Off();
115     delay(pausa/3);
116     break;
117
118 }
119 Serial.print(millis()); 
120 Serial.print(" \t Stato attuale ");
121 Serial.println(state);
122
123 }
124
125 /* Domande:
126  1. E' agevole inserire degli altri semafori?
127  2. Provare a inserire un altro semafori implementando una FSM
128     separata.
129 .
130 .
131 .
132 .
133 .
134 .
135 .
136 .
137 .
138 .
139   Soluzioni
140 1. Be' bisogna ragionare sul loro comportamente in rapporto alla FSM principale,   diciamo che non e' un approccio plug and play.
141 2. Vedi esercizio successivo.
142  */