X-Git-Url: http://git.piffa.net/web?a=blobdiff_plain;ds=sidebyside;f=advanced_projects%2Fstate_machine%2Fsemaforo_5_doppia_fsm%2Fsemaforo_5_doppia_fsm.ino;fp=advanced_projects%2Fstate_machine%2Fsemaforo_5_doppia_fsm%2Fsemaforo_5_doppia_fsm.ino;h=619b85e2ba20fe3dd752cb0b09e7db3fd0c2adac;hb=b15c46840c12896bd1b29dc360db4f30f8b5dfa4;hp=0000000000000000000000000000000000000000;hpb=0cf9246dae9d495f333cee506f647664bcf12234;p=sketchbook_andrea diff --git a/advanced_projects/state_machine/semaforo_5_doppia_fsm/semaforo_5_doppia_fsm.ino b/advanced_projects/state_machine/semaforo_5_doppia_fsm/semaforo_5_doppia_fsm.ino new file mode 100644 index 0000000..619b85e --- /dev/null +++ b/advanced_projects/state_machine/semaforo_5_doppia_fsm/semaforo_5_doppia_fsm.ino @@ -0,0 +1,166 @@ +/* + Semaforo RGB + + Un singolo semaforo costruito col paradigma delle macchine a stato. + Viene utilizzato un oggetto della libreria common per gestire il LED. + + Uno stimolo esterno rappresentato dalla pressione di un bottone + causa il passaggio di stato. + + Implementata con millis() invece che con delay(), + sono stati aggiuntu due stati per meglio gestire lo stato yellow. + + */ + +#include +const byte input = 2; // PIN del bottone +int pausa = 3000; +long timer ; +enum states_available { // Stati della FMS + turn_green, // Transizione + green, // Statico + wait_button, // Evento - Stimolo + turn_yellow, // transizione + yellow, // Statico + turn_red, // transizione + red // Statico +}; + +states_available FSM1 ; +states_available FSM2 ; + + +void setup() { + pinMode(input, INPUT_PULLUP); + Serial.begin(9600); + timer = millis(); +} + +RGBLed led1(11, 10, 9); //Istanziamo un oggetto led facente parte +RGBLed led2(8,7,6); //Istanziamo un oggetto led facente parte + // della classe RGBLed + +void loop() { +switch (FSM1) { + case turn_green : + led1.Green(); + FSM1 = green ; // Setta il prossimo state + FSM2 = red ; // Setta il prossimo state + break; + + case green: + if (millis() > timer + pausa * 2/3) { + FSM1 = wait_button ; + timer = millis(); + } + break; + + case wait_button: + if (digitalRead(input) == LOW) { + FSM1 = turn_yellow ; + timer = millis(); + delay(20); // Debouncing, si potrebbe fare con millis() + }; + + break; + + case turn_yellow : + led1.Yellow(); + FSM1 = yellow ; + break; + + case yellow : + if (millis() > timer + pausa * 2/3) { + FSM1 = turn_red ; + timer = millis(); + } + break; + + case turn_red : + led1.Red(); + FSM1 = red ; + FSM2 = turn_green ; + break; + + case red : + break; + + default: // In caso di default si fa giallo lampeggiante + led1.Yellow(); + delay(pausa/3); + led1.Off(); + delay(pausa/3); + break; + +} +switch (FSM2) { + case turn_green : + led2.Green(); + FSM2 = green ; // Setta il prossimo state + break; + + case green: + if (millis() > timer + pausa * 2/3) { + FSM2 = turn_yellow; + timer = millis(); + } + break; + + case turn_yellow : + led2.Yellow(); + FSM2 = yellow ; + break; + + case yellow : + if (millis() > timer + pausa / 3) { + FSM2 = turn_red ; + timer = millis(); + } + break; + + case turn_red : + FSM2 = red ; + FSM1 = turn_green; + break; + + case red : + led2.Red(); // Aggiorniamo il LED in questo stato invece che nel precedente + // per entrare nel primo ciclo di esecuzione con il LED rosso + break; + + default: // In caso di default si fa giallo lampeggiante + led2.Yellow(); + delay(pausa/3); + led2.Off(); + delay(pausa/3); + break; +} + +Serial.print(millis()); +Serial.print(" \t Stato attuale FSM1: "); +Serial.print(FSM1); +Serial.print(" - FSM2: "); +Serial.println(FSM2); +} + +/* Domande: + 1. E' piu' semplice ora inserire degli altri oggetti nello sketch? + 2. Gli eventi sono condivisi? Le varie FSM hanno modo di scambiarsi + informazioni sui relativi stati? + 3. Creare un dispatcher degli eventi al quale le varie FSM possono + riferirsi. +. +. +. +. +. +. +. +. +. +. + Soluzioni +1. Si, per quanto le 2 FSM non siano indipendenti l'una dall'altra. +2. No, c'e' un solo flusso degli eventi, il blocco di una delle FSM + puo' causare lo stop di tutto il sistema. + */