]> git.piffa.net Git - sketchbook_andrea/blobdiff - advanced_projects/state_machine/semaforo_3_millis/semaforo_3_millis.ino
FSM reorder
[sketchbook_andrea] / advanced_projects / state_machine / semaforo_3_millis / semaforo_3_millis.ino
index 68825a6515005c130fccd3d48b47e403ce6b471c..4cc7dcbb650d4972f7d571413c937239f5821eca 100644 (file)
@@ -10,6 +10,8 @@
    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>
@@ -17,7 +19,6 @@ 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 +31,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 += 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
-    delay(20); // Debouncing, si potrebbe fare con millis()
-    timer = millis();
+case wait_button:
+    if (digitalRead(input) == LOW) {
+        state = turn_yellow ; // Il passaggio di stato avviene alla pressione di un bottone
+        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 += pausa * 2/3;
+    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 += 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 +90,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 +112,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
  */