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