X-Git-Url: http://git.piffa.net/web?p=sketchbook_andrea;a=blobdiff_plain;f=advanced_projects%2Fstate_machine%2Fsemaforo_4_doppio_single_FSM%2Fsemaforo_4_doppio_single_FSM.ino;fp=advanced_projects%2Fstate_machine%2Fsemaforo_4_doppio_single_FSM%2Fsemaforo_4_doppio_single_FSM.ino;h=be9bb0482cac8210850a25cf695dc17e4ebebf04;hp=0000000000000000000000000000000000000000;hb=8a90a5875d2fcf8db21835920d57f97a4bca0ade;hpb=92687f500a1e7aed1fe35540e4f4aee5f8bcf6a1 diff --git a/advanced_projects/state_machine/semaforo_4_doppio_single_FSM/semaforo_4_doppio_single_FSM.ino b/advanced_projects/state_machine/semaforo_4_doppio_single_FSM/semaforo_4_doppio_single_FSM.ino new file mode 100644 index 0000000..be9bb04 --- /dev/null +++ b/advanced_projects/state_machine/semaforo_4_doppio_single_FSM/semaforo_4_doppio_single_FSM.ino @@ -0,0 +1,142 @@ +/* + Semaforo RGB single FSM + + + Doppio semaforo, una via prinicipale (led) e una secondaria (secondary): + la via secondaria ottiene la precedenza alla pressione di un bottone. + + Implementata con millis() invece che con delay(), + sono stati aggiuntu due stati per gestire lo stato yellow + del semafor secondario. + + Lo sketch e' stato implementato con una sola FSM in cui si incrociano + gli stati dei due semafori. + +- 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 +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 + yellow, // Statico + turn_red, // Dinamico, transizione + turn_sec_yellow, // Yellow per semaforo secondario + sec_yellow, + red // Statico +}; + +states_available state ; + + +void setup() { + pinMode(input, INPUT_PULLUP); + Serial.begin(9600); + timer = millis(); +} + +RGBLed led(11, 10, 9); // Semaforo principale +RGBLed secondary(8,7,6); // Semaforo secondario + + +void loop() { +switch (state) { + case turn_green : + led.Green(); + secondary.Red() ; + state = green ; // Setta il prossimo state + break; + + case green: + if (millis() - timer => pausa * 2/3) { + state = wait_button ; + timer += pausa * 2/3 ; + } + break; + + case wait_button: + if (digitalRead(input) == LOW) { + delay(20); // Debouncing, si potrebbe fare con millis() + state = turn_yellow ; // Il passaggio di stato avviene alla pressione di un bottone + timer = millis(); + }; + + break; + + case turn_yellow : + led.Yellow(); + state = yellow ; + break; + + case yellow : + if (millis() - timer >= pausa / 3) { + state = turn_red ; + timer += pausa / 3; + } + break; + + case turn_red : + led.Red(); + secondary.Green(); + state = red ; + break; + + case red : + if (millis() - timer >= pausa /3) { + state = turn_sec_yellow ; + timer += pausa /3 ; + } + break; + + case turn_sec_yellow : + secondary.Yellow(); + state = sec_yellow ; + break; + + case sec_yellow : + if (millis() - timer >= pausa / 3) { + state = turn_green ; + timer += pausa /3; + } + break; + + default: // In caso di default si fa giallo lampeggiante + led.Yellow(); + secondary.Yellow(); + delay(pausa/3); + led.Off(); + secondary.Off(); + delay(pausa/3); + break; + +} +Serial.print(millis()); +Serial.print(" \t Stato attuale "); +Serial.println(state); + +} + +/* Domande: + 1. E' agevole inserire degli altri semafori? + 2. Provare a inserire un altro semafori implementando una FSM + separata. +. +. +. +. +. +. +. +. +. +. + Soluzioni +1. Be' bisogna ragionare sul loro comportamente in rapporto alla FSM principale, diciamo che non e' un approccio plug and play. +2. Vedi esercizio successivo. + */