X-Git-Url: http://git.piffa.net/web?a=blobdiff_plain;f=advanced_projects%2Fstate_machine%2Fsemaforo_3_millis%2Fsemaforo_3_millis.ino;h=0b3c41563d7a8650d2c3de11f57f4e9506ef47b2;hb=98f12e9ba20d5b505b1b6506569e31af9ac3ba89;hp=af151a7e98b801c047fc24d4797084959107251b;hpb=b15c46840c12896bd1b29dc360db4f30f8b5dfa4;p=sketchbook_andrea diff --git a/advanced_projects/state_machine/semaforo_3_millis/semaforo_3_millis.ino b/advanced_projects/state_machine/semaforo_3_millis/semaforo_3_millis.ino index af151a7..0b3c415 100644 --- a/advanced_projects/state_machine/semaforo_3_millis/semaforo_3_millis.ino +++ b/advanced_projects/state_machine/semaforo_3_millis/semaforo_3_millis.ino @@ -10,14 +10,16 @@ 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 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 @@ -30,61 +32,58 @@ states_available state ; 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(); + if (millis() - timer >= pausa * 2/3) { + 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(); + if (millis() - timer >= pausa) { + 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(); @@ -92,16 +91,17 @@ switch (state) { 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. . . . @@ -113,6 +113,5 @@ Serial.println(state); . . Soluzioni -2. Si potrebbe utilizzare un interrupt per gli stimoli oppure millis() - per gestire le pause. +1. Vedi esercizio: semaforo_rgb */