]> git.piffa.net Git - sketchbook_andrea/commitdiff
State machines
authoreaman <andrea@piffa.net>
Thu, 20 Oct 2016 23:38:18 +0000 (01:38 +0200)
committereaman <andrea@piffa.net>
Thu, 20 Oct 2016 23:38:18 +0000 (01:38 +0200)
13 files changed:
advanced_projects/state_machine/blink/blink.ino [deleted file]
advanced_projects/state_machine/semaforo_1/semaforo_1.ino [new file with mode: 0644]
advanced_projects/state_machine/semaforo_2_1_doppio/semaforo_2_1_doppio.ino [new file with mode: 0644]
advanced_projects/state_machine/semaforo_2_stimolo/semaforo_2_stimolo.ino [new file with mode: 0644]
advanced_projects/state_machine/semaforo_3_millis/semaforo_3_millis.ino [new file with mode: 0644]
advanced_projects/state_machine/semaforo_4_doppio/semaforo_4_doppio.ino [new file with mode: 0644]
advanced_projects/state_machine/semaforo_5_doppia_fsm/semaforo_5_doppia_fsm.ino [new file with mode: 0644]
advanced_projects/state_machine/semaforo_rgb/semaforo_rgb.ino [deleted file]
advanced_projects/state_machine/semaforo_rgb_stimolo/semaforo_rgb_stimolo.ino [deleted file]
advanced_projects/state_machine/semaforo_rgb_stimolo_millis/semaforo_rgb_stimolo_millis.ino [new file with mode: 0644]
advanced_projects/state_machine/semaphore/semaphore.ino [deleted file]
libraries/common/common.cpp
libraries/common/common.h

diff --git a/advanced_projects/state_machine/blink/blink.ino b/advanced_projects/state_machine/blink/blink.ino
deleted file mode 100644 (file)
index 485c2f2..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-   Blink con state machine
-
-   Introduzione alle state machine
-
-   */
-int led = 13;
-int pausa = 1000;
-enum states_available { // Stati della FMS
-    turn_on,    // Dinamico, transizione
-    on,         // Statico
-    turn_off,
-    off
-};
-
-states_available state  ;
-
-void setup() {
-  pinMode(led, OUTPUT); 
-  Serial.begin(9600);
-  Serial.flush();
-}
-
-void loop() {
-switch (state) {
-    case turn_on :
-    digitalWrite(led, HIGH);
-    state = on ; // Setta il prossimo state
-    break;
-
-    case on:
-    delay(pausa);
-    state = turn_off ;
-    break;
-
-    case turn_off :
-    digitalWrite(led, LOW);
-    state = off ;
-    break;
-
-    case off :
-    delay(pausa);
-    state = turn_on ;
-    break;
-
-    default:    // In caso di default si fa turn_off
-    digitalWrite(led, LOW);
-    state = off ;
-    break;
-
-}
-Serial.print(millis()); 
-Serial.print(" \t Stato attuale ");
-Serial.println(state);
-
-}
diff --git a/advanced_projects/state_machine/semaforo_1/semaforo_1.ino b/advanced_projects/state_machine/semaforo_1/semaforo_1.ino
new file mode 100644 (file)
index 0000000..1318a08
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+   Semaforo RGB
+
+   Un singolo semaforo costruito col paradigma delle macchine a stato.
+   Viene utilizzato un oggetto della libreria common per gestire il LED.
+
+   */
+#include <common.h>
+int pausa = 3000;
+enum states_available { // Stati della FMS
+    turn_green,    // Dinamico, transizione
+    green,         // Statico
+    turn_red,
+    red
+};
+
+states_available state  ;
+
+
+void setup() {
+  Serial.begin(9600);
+  Serial.flush();
+}
+
+RGBLed led(11, 10, 9); //Istanziamo un oggetto led facente parte
+                       // della classe RGBLed
+
+void loop() {
+switch (state) {
+    case turn_green :
+    led.Green();
+    state = green ; // Setta il prossimo state
+    break;
+
+    case green:
+    delay(pausa * 2/3);
+    state = turn_red ;
+    break;
+
+    case turn_red :
+    led.Yellow();
+    delay(pausa/3);
+    led.Red();
+    delay(pausa);
+    state = red ;
+    break;
+
+    case red :
+    delay(pausa);
+    state = turn_green ;
+    break;
+
+    default:    // In caso di default si fa giallo
+    led.Yellow();
+    delay(pausa/3);
+    led.Off();
+    delay(pausa/3);
+    break;
+
+}
+Serial.print(millis()); 
+Serial.print(" \t Stato attuale ");
+Serial.println(state);
+
+}
+
+/* Domande:
+ 1. Come legare il passaggio di stato ad un evento esterno,
+    ad es. la pressione di un bottone?
+ */
diff --git a/advanced_projects/state_machine/semaforo_2_1_doppio/semaforo_2_1_doppio.ino b/advanced_projects/state_machine/semaforo_2_1_doppio/semaforo_2_1_doppio.ino
new file mode 100644 (file)
index 0000000..412e11f
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+   Incrocio RGB
+
+   Un incrocio costituito da due strade, una principale e una secondaria.
+   La via viene concessa al secondario alla pressione di un bottone,
+   il secondario cambia automaticamente dopo una pausa.
+   Viene utilizzato un oggetto della libreria common per gestire i LED.
+
+   Uno stimolo esterno rappresentato dalla pressione di un bottone
+   causa il passaggio di stato.
+
+ */
+
+#include <common.h>
+const byte input = 2; // PIN del bottone
+int pausa = 3000;
+enum states_available { // Stati della FMS
+    turn_green,    // Dinamico, transizione
+    green,         // Statico
+    wait_button,
+    turn_red,
+    red
+};
+
+states_available FSM1  ;
+states_available FSM2 ;
+
+
+void setup() {
+  pinMode(input, INPUT_PULLUP);
+  Serial.begin(9600);
+  Serial.flush();
+}
+
+RGBLed led_main(11, 10, 9); 
+RGBLed led_secondary(8, 7, 6); 
+
+void loop() {
+switch (FSM1) {
+    case turn_green :
+    led_main.Green();
+    FSM1 = green ; // Setta il prossimo state
+    FSM2 = red ;    // Setta il prossimo state
+    break;
+
+    case green:
+    delay(pausa * 2/3);
+    FSM1 = wait_button ;
+    break;
+
+    case wait_button:
+    if (digitalRead(input) == LOW) { 
+    FSM1 = turn_red ; // Il passaggio di stato avviene alla pressione di un bottone
+    };
+    delay(20);
+    break;
+
+    case turn_red :
+    led_main.Yellow();
+    delay(pausa/3);
+    led_main.Red();
+    FSM1 = red ;
+    FSM2 = turn_green; // Stimolo al semafor secondario
+    break;
+
+    case red :
+    //delay(pausa);
+    //main = turn_green ;
+    break;
+}
+switch (FSM2) {
+    case turn_green :
+    led_secondary.Green();
+    FSM2 = green ; // Setta il prossimo state
+    break;
+
+    case green:
+    delay(pausa * 2/3);
+    FSM2 = turn_red ; // Niente stimoli
+    break;
+
+    case turn_red :
+    led_secondary.Yellow();
+    delay(pausa/3);
+    FSM1 = turn_green ;
+    FSM2 = red ;
+    break;
+
+    case red :
+    led_secondary.Red();
+    break;
+}
+
+Serial.print(millis()); 
+Serial.print(" \t Stato attuale Main: ");
+Serial.print(FSM1);
+Serial.print(", secondary: ");
+Serial.println(FSM2);
+
+}
diff --git a/advanced_projects/state_machine/semaforo_2_stimolo/semaforo_2_stimolo.ino b/advanced_projects/state_machine/semaforo_2_stimolo/semaforo_2_stimolo.ino
new file mode 100644 (file)
index 0000000..e31949f
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+   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.
+
+   */
+
+#include <common.h>
+const byte input = 2; // PIN del bottone
+int pausa = 3000;
+enum states_available { // Stati della FMS
+    turn_green,    // Dinamico, transizione
+    green,         // Statico
+    wait_button,   // Evento - Stimolo
+    turn_red,      // Dinamico, transizione
+    red            // Statico
+};
+
+states_available state  ;
+
+
+void setup() {
+  pinMode(input, INPUT_PULLUP);
+  Serial.begin(9600);
+  Serial.flush();
+}
+
+RGBLed led(11, 10, 9); //Istanziamo un oggetto led facente parte
+                       // della classe RGBLed
+
+void loop() {
+switch (state) {
+    case turn_green :
+    led.Green();
+    state = green ; // Setta il prossimo state
+    break;
+
+    case green:
+    delay(pausa * 2/3);
+    state = wait_button ;
+    break;
+
+    case wait_button:
+    if (digitalRead(input) == LOW) { 
+    state = turn_red ; // Il passaggio di stato avviene alla pressione di un bottone
+    delay(20);
+    };
+
+    break;
+
+    case turn_red :
+    led.Yellow();
+    delay(pausa/3);
+    led.Red();
+    delay(pausa);
+    state = red ;
+    break;
+
+    case red :
+    delay(pausa);
+    state = turn_green ;
+    break;
+
+    default:    // In caso di default si fa giallo lampeggiante
+    led.Yellow();
+    delay(pausa/3);
+    led.Off();
+    delay(pausa/3);
+    break;
+
+}
+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?
+.
+.
+.
+.
+.
+.
+.
+.
+.
+.
+  Soluzioni
+2. Si potrebbe utilizzare un interrupt per gli stimoli oppure millis()
+   per gestire le pause.
+ */
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
new file mode 100644 (file)
index 0000000..af151a7
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+   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 <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
+    yellow,            // Statico
+    turn_red,      // Dinamico, transizione
+    red            // Statico
+};
+
+states_available state  ;
+
+
+void setup() {
+  pinMode(input, INPUT_PULLUP);
+  Serial.begin(9600);
+  timer = millis();
+}
+
+RGBLed led(11, 10, 9); //Istanziamo un oggetto led facente parte
+                       // della classe RGBLed
+
+void loop() {
+switch (state) {
+    case turn_green :
+    state = green ; // Setta il prossimo state
+    break;
+
+    case green:
+    led.Green();
+    if (millis() > timer + pausa * 2/3) {
+    state = wait_button ;
+    timer = millis(); 
+    }
+    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()
+    };
+    break;
+
+    case turn_yellow :
+    state = yellow ;
+    break;
+
+    case yellow :
+    led.Yellow();
+    if (millis() > timer + pausa * 2/3) {
+    state = turn_red ;
+    timer = millis(); 
+    }
+    break;
+
+    case turn_red :
+    state = red ;
+    break;
+
+    case red :
+    led.Red();
+    if (millis() > timer + pausa) {
+    state = turn_green ;
+    timer = millis(); 
+    }
+    break;
+
+    default:    // In caso di default si fa giallo lampeggiante
+    led.Yellow();
+    delay(pausa/3);
+    led.Off();
+    delay(pausa/3);
+    break;
+
+}
+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?
+.
+.
+.
+.
+.
+.
+.
+.
+.
+.
+  Soluzioni
+2. Si potrebbe utilizzare un interrupt per gli stimoli oppure millis()
+   per gestire le pause.
+ */
diff --git a/advanced_projects/state_machine/semaforo_4_doppio/semaforo_4_doppio.ino b/advanced_projects/state_machine/semaforo_4_doppio/semaforo_4_doppio.ino
new file mode 100644 (file)
index 0000000..3866ad2
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+   Semaforo RGB
+
+
+   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.
+
+   */
+
+#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
+    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 = millis(); 
+    }
+    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();
+    };
+
+    break;
+
+    case turn_yellow :
+    led.Yellow();
+    state = yellow ;
+    break;
+
+    case yellow :
+    if (millis() > timer + pausa / 3) {
+    state = turn_red ;
+    timer = millis(); 
+    }
+    break;
+
+    case turn_red :
+    led.Red();
+    secondary.Green();
+    state = red ;
+    break;
+
+    case red :
+    if (millis() > timer + pausa /3) {
+    state = turn_sec_yellow ;
+    timer = millis(); 
+    }
+    break;
+
+    case turn_sec_yellow :
+    secondary.Yellow();
+    state = sec_yellow ;
+    break;
+
+    case sec_yellow :
+    if (millis() > timer + pausa / 3) {
+    state = turn_green ;
+    timer = millis(); 
+    }
+    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.
+ */
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 (file)
index 0000000..619b85e
--- /dev/null
@@ -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 <common.h>
+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.
+ */
diff --git a/advanced_projects/state_machine/semaforo_rgb/semaforo_rgb.ino b/advanced_projects/state_machine/semaforo_rgb/semaforo_rgb.ino
deleted file mode 100644 (file)
index 1318a08..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
-   Semaforo RGB
-
-   Un singolo semaforo costruito col paradigma delle macchine a stato.
-   Viene utilizzato un oggetto della libreria common per gestire il LED.
-
-   */
-#include <common.h>
-int pausa = 3000;
-enum states_available { // Stati della FMS
-    turn_green,    // Dinamico, transizione
-    green,         // Statico
-    turn_red,
-    red
-};
-
-states_available state  ;
-
-
-void setup() {
-  Serial.begin(9600);
-  Serial.flush();
-}
-
-RGBLed led(11, 10, 9); //Istanziamo un oggetto led facente parte
-                       // della classe RGBLed
-
-void loop() {
-switch (state) {
-    case turn_green :
-    led.Green();
-    state = green ; // Setta il prossimo state
-    break;
-
-    case green:
-    delay(pausa * 2/3);
-    state = turn_red ;
-    break;
-
-    case turn_red :
-    led.Yellow();
-    delay(pausa/3);
-    led.Red();
-    delay(pausa);
-    state = red ;
-    break;
-
-    case red :
-    delay(pausa);
-    state = turn_green ;
-    break;
-
-    default:    // In caso di default si fa giallo
-    led.Yellow();
-    delay(pausa/3);
-    led.Off();
-    delay(pausa/3);
-    break;
-
-}
-Serial.print(millis()); 
-Serial.print(" \t Stato attuale ");
-Serial.println(state);
-
-}
-
-/* Domande:
- 1. Come legare il passaggio di stato ad un evento esterno,
-    ad es. la pressione di un bottone?
- */
diff --git a/advanced_projects/state_machine/semaforo_rgb_stimolo/semaforo_rgb_stimolo.ino b/advanced_projects/state_machine/semaforo_rgb_stimolo/semaforo_rgb_stimolo.ino
deleted file mode 100644 (file)
index de2373b..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-   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.
-
-   */
-#include <common.h>
-const byte input = 2; // PIN del bottone
-int pausa = 3000;
-enum states_available { // Stati della FMS
-    turn_green,    // Dinamico, transizione
-    green,         // Statico
-    wait_button,
-    turn_red,
-    red
-};
-
-states_available state  ;
-
-
-void setup() {
-  pinMode(input, INPUT_PULLUP);
-  Serial.begin(9600);
-  Serial.flush();
-}
-
-RGBLed led(11, 10, 9); //Istanziamo un oggetto led facente parte
-                       // della classe RGBLed
-
-void loop() {
-switch (state) {
-    case turn_green :
-    led.Green();
-    state = green ; // Setta il prossimo state
-    break;
-
-    case green:
-    delay(pausa * 2/3);
-    state = wait_button ;
-    break;
-
-    case wait_button:
-    if (digitalRead(input) == LOW) { 
-    state = turn_red ; // Il passaggio di stato avviene alla pressione di un bottone
-    delay(20);
-    };
-
-    break;
-
-    case turn_red :
-    led.Yellow();
-    delay(pausa/3);
-    led.Red();
-    delay(pausa);
-    state = red ;
-    break;
-
-    case red :
-    delay(pausa);
-    state = turn_green ;
-    break;
-
-    default:    // In caso di default si fa giallo lampeggiante
-    led.Yellow();
-    delay(pausa/3);
-    led.Off();
-    delay(pausa/3);
-    break;
-
-}
-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?
-.
-.
-.
-.
-.
-.
-.
-.
-.
-.
-  Soluzioni
-2. Si potrebbe utilizzare un interrupt per gli stimoli oppure millis()
-   per gestire le pause.
- */
diff --git a/advanced_projects/state_machine/semaforo_rgb_stimolo_millis/semaforo_rgb_stimolo_millis.ino b/advanced_projects/state_machine/semaforo_rgb_stimolo_millis/semaforo_rgb_stimolo_millis.ino
new file mode 100644 (file)
index 0000000..af151a7
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+   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 <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
+    yellow,            // Statico
+    turn_red,      // Dinamico, transizione
+    red            // Statico
+};
+
+states_available state  ;
+
+
+void setup() {
+  pinMode(input, INPUT_PULLUP);
+  Serial.begin(9600);
+  timer = millis();
+}
+
+RGBLed led(11, 10, 9); //Istanziamo un oggetto led facente parte
+                       // della classe RGBLed
+
+void loop() {
+switch (state) {
+    case turn_green :
+    state = green ; // Setta il prossimo state
+    break;
+
+    case green:
+    led.Green();
+    if (millis() > timer + pausa * 2/3) {
+    state = wait_button ;
+    timer = millis(); 
+    }
+    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()
+    };
+    break;
+
+    case turn_yellow :
+    state = yellow ;
+    break;
+
+    case yellow :
+    led.Yellow();
+    if (millis() > timer + pausa * 2/3) {
+    state = turn_red ;
+    timer = millis(); 
+    }
+    break;
+
+    case turn_red :
+    state = red ;
+    break;
+
+    case red :
+    led.Red();
+    if (millis() > timer + pausa) {
+    state = turn_green ;
+    timer = millis(); 
+    }
+    break;
+
+    default:    // In caso di default si fa giallo lampeggiante
+    led.Yellow();
+    delay(pausa/3);
+    led.Off();
+    delay(pausa/3);
+    break;
+
+}
+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?
+.
+.
+.
+.
+.
+.
+.
+.
+.
+.
+  Soluzioni
+2. Si potrebbe utilizzare un interrupt per gli stimoli oppure millis()
+   per gestire le pause.
+ */
diff --git a/advanced_projects/state_machine/semaphore/semaphore.ino b/advanced_projects/state_machine/semaphore/semaphore.ino
deleted file mode 100644 (file)
index f309a6a..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
-A traffic light for an intersection of a
-highway and a country road. Normally, the light
-should be green for the highway and red for the
-country road, but when traffic approaches on
-the country road, the highway gets a red light
-and the country road gets a green light.
-When a light turns red it transitions from green to
-red it goes through yellow, but a red light changing
-to green transitions directly to green.
-A pushbutton represents a car approaching on
-the country road.
-Implement the solution with a Finite State
-Machine or FSM.
-Following the excellent description at
-http://hacking.majenko.co.uk/finite-state-machine
-first break down the problem into states.
-Identify which states are Transitional (T) and
-which are Static (S). A Static state is one in
-which the FSM is waiting for stimulus, and is
-taking no actions. A Transitional State is a
-state which causes actions, but doesn't look
-for stimulus.
-A Transitional State runs once and immediately
-moves on to a Static State.
-State 0: highway = green, country = red; (T)
-State 1: wait for car on country road (S)
-State 2: highway = yellow, make note of current time (T)
-State 3: wait for yellow time to pass (S)
-State 4: highway = red, country =  green, make note of current time (T)
-State 5: wait for highway red time to pass (S)
-State 6: country = yellow, make note of current time (T)
-state 7: wait for yellow time to pass (S) then go to 0
-*/
-// Use names for states so it's easier to
-// understand what the code is doing
-const int S_HIGHWAYGREEN = 0;
-const int S_WAITCARCOUNTRY = 1;
-const int S_HIGHWAYYELLOW = 2;
-const int S_WAITHIGHWAYYELLOW = 3;
-const int S_HIGHWAYRED = 4;
-const int S_WAITHIGHWAYRED = 5;
-const int S_COUNTRYYELLOW = 6;
-const int S_WAITCOUNTRYYELLOW = 7;
-// Pin numbers
-const int countrySensorPin = 2;
-const int highwayGreenLEDPin = 3;
-const int highwayYellowLEDPin = 4;
-const int highwayRedLEDPin = 5;
-const int countryGreenLEDPin = 6;
-const int countryYellowLEDPin = 7;
-const int countryRedLEDPin = 8;
-void setup()
-{
-  pinMode(highwayGreenLEDPin, OUTPUT);
-  pinMode(highwayYellowLEDPin, OUTPUT);
-  pinMode(highwayRedLEDPin, OUTPUT);
-  pinMode(countryGreenLEDPin, OUTPUT);
-  pinMode(countryYellowLEDPin, OUTPUT);
-  pinMode(countryRedLEDPin, OUTPUT);
-}
-void loop()
-{
-  // start off with the highway getting green
-  // The keyword "static" makes sure the variable
-  // isn't destroyed after each loop
-  static int state = S_HIGHWAYGREEN ;
-  // To store the current time  for delays
-  static unsigned long ts;
-  switch (state)
-  {
-    case S_HIGHWAYGREEN:
-      // Highway gets green, country road red
-      digitalWrite( highwayGreenLEDPin, HIGH);
-      digitalWrite( highwayYellowLEDPin, LOW);
-      digitalWrite( highwayRedLEDPin, LOW);
-      digitalWrite( countryGreenLEDPin, LOW);
-      digitalWrite( countryYellowLEDPin, LOW);
-      digitalWrite( countryRedLEDPin, HIGH);
-      state = S_WAITCARCOUNTRY;
-      break;
-    case S_WAITCARCOUNTRY:
-      if ( digitalRead (countrySensorPin) == HIGH) {
-        state = S_HIGHWAYYELLOW;
-      }
-      break;
-    case S_HIGHWAYYELLOW:
-      digitalWrite( highwayGreenLEDPin, LOW);
-      digitalWrite( highwayYellowLEDPin, HIGH);
-      digitalWrite( highwayRedLEDPin, LOW);
-      digitalWrite( countryGreenLEDPin, LOW);
-      digitalWrite( countryYellowLEDPin, LOW);
-      digitalWrite( countryRedLEDPin, HIGH);
-      ts = millis();  // Remember the current time
-      state = S_WAITHIGHWAYYELLOW;  // Move to the next state
-      break;
-    case S_WAITHIGHWAYYELLOW:
-      // If two seconds have passed, then move on to the next state.
-      if (millis() > ts + 2000)
-      {
-        state = S_HIGHWAYRED;
-      }
-      break;
-    case S_HIGHWAYRED:
-      // Highway red, country road green
-      digitalWrite( highwayGreenLEDPin, LOW);
-      digitalWrite( highwayYellowLEDPin, LOW);
-      digitalWrite( highwayRedLEDPin, HIGH);
-      digitalWrite( countryGreenLEDPin, HIGH);
-      digitalWrite( countryYellowLEDPin, LOW);
-      digitalWrite( countryRedLEDPin, LOW);
-      ts = millis();  // Remember the current time
-      state = S_WAITHIGHWAYRED;
-      break;
-    case S_WAITHIGHWAYRED:
-      // If five seconds have passed, then start
-      // transition to a red light for the country 
-      // road
-      if (millis() > ts + 5000)
-      {
-        state = S_COUNTRYYELLOW;
-      }
-      break;
-    case S_COUNTRYYELLOW:
-      digitalWrite( highwayGreenLEDPin, LOW);
-      digitalWrite( highwayYellowLEDPin, LOW);
-      digitalWrite( highwayRedLEDPin, HIGH);
-      digitalWrite( countryGreenLEDPin, LOW);
-      digitalWrite( countryYellowLEDPin, HIGH);
-      digitalWrite( countryRedLEDPin, LOW);
-      ts = millis();  // Remember the current time
-      state = S_WAITCOUNTRYYELLOW;
-      break;
-    case S_WAITCOUNTRYYELLOW:
-      // If two seconds have passed, then go
-      // back to the beginning with the highway 
-      // getting the green light
-      if (millis() > ts + 2000)
-      {
-        state = S_HIGHWAYGREEN;
-      }
-      break;
-  } // end of switch
-  // other things could go on here, and they would not affect the timing 
-  // of the traffic light
-} // end of loop
index 94657ae6cf967b6404fb5ce9f460299757ad0832..1eed6a2c3a7353115bed2e0c033e09ce0ffe0628 100644 (file)
@@ -1,6 +1,11 @@
 /*  Common
- *
- *  Oggetti di uso comune
+  Collezione di funzioni e oggetti comuni incontrati durante
+  i vari esercizi.
+
+  Source file
+  Contiene il codice C++ delle funzioni e degli oggetti,
+  nel file common.h ci sono gli headers: prototipi.
+
  */
 
 #include "Arduino.h"
@@ -92,7 +97,7 @@ void RGBLed::SetColor (byte r, byte g, byte b) {
 
 void brilla(byte pin) {
   // Accende e spegne il LED senza un argomento 
-  // per impostare la velocita'.
+  // per impostare la velocita' con delay().
   const int velocita = 500;
 
 pinMode(pin, OUTPUT); 
index 71cb19a84efa0670564ff0673d9d90662e42ebba..e1b0cf061a58dfca12b9a95e063b7dbf1f0185e9 100644 (file)
@@ -1,15 +1,21 @@
 /*
   Common Class
 
-  Oggetti comuni
+  Collezione di funzioni e oggetti comuni incontrati durante
+  i vari esercizi.
+
+  Header file
+  Contiene i prototipi delle funzioni e degli oggetti,
+  il codice e' nel fine *.cpp
 
 */
 
 #include "Arduino.h"
-#ifndef common_h
-#define common_h
+#ifndef common_h // Questi cicli IF, gestiti come macro da preprocessor
+#define common_h // fanno si che questo file non venga incluso piu' volte
 
 
+/////////////////////////////////////////////
 class RGBLed {
   // Classe rappresentativa di un LED RGB
   
@@ -33,6 +39,7 @@ class RGBLed {
        void SetColor (byte r, byte g, byte b) ;
 };
 
+/////////////////////////////////////////////
 void brilla(byte pin, int velocita = 500) ;
 
 #endif