]> git.piffa.net Git - sketchbook_andrea/blob - advanced_projects/state_machine/semaforo_3_millis/semaforo_3_millis.ino
4cc7dcbb650d4972f7d571413c937239f5821eca
[sketchbook_andrea] / advanced_projects / state_machine / semaforo_3_millis / semaforo_3_millis.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 - Schema per un led RGB: https://lab.piffa.net/schemi/rgb.jpg
14 - Schema per un bottone: https://www.arduino.cc/en/uploads/Tutorial/inputPullupButton.png
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     green,         // Statico
23     wait_button,   // Evento - Stimolo
24     turn_yellow,      // Dinamico, transizione
25     yellow,            // Statico
26     turn_red,      // Dinamico, transizione
27     red            // Statico
28 };
29
30 states_available state  ;
31
32
33 void setup() {
34     pinMode(input, INPUT_PULLUP);
35     Serial.begin(9600);
36     timer = millis();
37 }
38
39 RGBLed led(11, 10, 9); //Istanziamo un oggetto led facente parte
40 // della classe RGBLed
41
42 void loop() {
43 switch (state) {
44
45 case green:
46     led.Green();
47     if (millis() - timer >= pausa * 2/3) {
48         state = wait_button ;
49         timer += pausa * 2/3 ;
50     }
51     break;
52
53 case wait_button:
54     if (digitalRead(input) == LOW) {
55         state = turn_yellow ; // Il passaggio di stato avviene alla pressione di un bottone
56         delay(20); // Debouncing, si potrebbe fare con millis()
57         timer = millis();
58     };
59     break;
60
61 case turn_yellow :
62     state = yellow ;
63     break;
64
65 case yellow :
66     led.Yellow();
67     if (millis() - timer >= pausa / 3) {
68         state = turn_red ;
69         timer += pausa  / 3;
70     }
71     break;
72
73 case turn_red :
74     state = red ;
75     break;
76
77 case red :
78     led.Red();
79     if (millis() - timer >= pausa) {
80         state = green ;
81         timer += pausa ;
82     }
83     break;
84
85 default:    // In caso di default si fa giallo lampeggiante
86     led.Yellow();
87     delay(pausa/3);
88     led.Off();
89     delay(pausa/3);
90     break;
91
92 }
93 // Debug:
94 Serial.print(millis());
95 Serial.print(" \t Stato attuale ");
96 Serial.println(state);
97
98 }
99
100 /* Domande:
101  1. Fare in modo che nello stato verde venga recepito un'eventuale pressione
102  del bottone, venga comunque garantito un periodo minimo per il verde ma nel caso
103  sia stato premuto il bottone durante questo si passi poi direttamente al giallo.
104 .
105 .
106 .
107 .
108 .
109 .
110 .
111 .
112 .
113 .
114   Soluzioni
115 1. Vedi esercizio: semaforo_rgb
116  */