Implementata con millis() invece che con delay(),
sono stati aggiuntu due stati per meglio gestire lo stato yellow.
+- Schema per un led RGB: https://lab.piffa.net/schemi/rgb.jpg
+- Schema per un bottone: https://www.arduino.cc/en/uploads/Tutorial/inputPullupButton.png
*/
#include <common.h>
const byte input = 2; // PIN del bottone
int pausa = 3000;
long timer ;
+
enum states_available { // Stati della FMS
- turn_green, // Dinamico, transizione
green, // Statico
wait_button, // Evento - Stimolo
turn_yellow, // Dinamico, transizione
void setup() {
- pinMode(input, INPUT_PULLUP);
- Serial.begin(9600);
- timer = millis();
+ pinMode(input, INPUT_PULLUP);
+ Serial.begin(9600);
+ timer = millis();
}
RGBLed led(11, 10, 9); //Istanziamo un oggetto led facente parte
- // della classe RGBLed
+// della classe RGBLed
void loop() {
switch (state) {
- case turn_green :
- state = green ; // Setta il prossimo state
- break;
- case green:
+case green:
led.Green();
if (millis() - timer >= pausa * 2/3) {
- state = wait_button ;
- timer = millis();
+ state = wait_button ;
+ timer += pausa * 2/3 ;
}
break;
- case wait_button:
- if (digitalRead(input) == LOW) {
- state = turn_yellow ; // Il passaggio di stato avviene alla pressione di un bottone
- timer = millis();
- delay(20); // Debouncing, si potrebbe fare con millis()
+case wait_button:
+ if (digitalRead(input) == LOW) {
+ state = turn_yellow ;
+ delay(20); // Debouncing, si potrebbe fare con millis()
+ timer = millis();
};
break;
- case turn_yellow :
+case turn_yellow :
state = yellow ;
break;
- case yellow :
+case yellow :
led.Yellow();
- if (millis() - timer >= pausa * 2/3) {
- state = turn_red ;
- timer = millis();
+ if (millis() - timer >= pausa / 3) {
+ state = turn_red ;
+ timer += pausa / 3;
}
break;
- case turn_red :
+case turn_red :
state = red ;
break;
- case red :
+case red :
led.Red();
if (millis() - timer >= pausa) {
- state = turn_green ;
- timer = millis();
+ state = green ;
+ timer += pausa ;
}
break;
- default: // In caso di default si fa giallo lampeggiante
+default: // In caso di default si fa giallo lampeggiante
led.Yellow();
delay(pausa/3);
led.Off();
break;
}
-Serial.print(millis());
+// Debug:
+Serial.print(millis());
Serial.print(" \t Stato attuale ");
Serial.println(state);
}
/* Domande:
- 1. Introdurre un secondo semaforo che cambia stato quando viene attivato
- lo stimolo.
- 2. L'uso di delay() puo' essere limitativo: come rimediare?
+ 1. Fare in modo che nello stato verde venga recepito un'eventuale pressione
+ del bottone, venga comunque garantito un periodo minimo per il verde ma nel caso
+ sia stato premuto il bottone durante questo si passi poi direttamente al giallo.
.
.
.
.
.
Soluzioni
-2. Si potrebbe utilizzare un interrupt per gli stimoli oppure millis()
- per gestire le pause.
+1. Vedi esercizio: semaforo_rgb
*/