]> git.piffa.net Git - sketchbook_andrea/commitdiff
Merge branch 'master' of git://git.andreamanni.com/sketchbook_andrea
authorAndrea Manni <andrea@piffa.net>
Wed, 26 Oct 2016 19:55:03 +0000 (21:55 +0200)
committerAndrea Manni <andrea@piffa.net>
Wed, 26 Oct 2016 19:55:03 +0000 (21:55 +0200)
14 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
libraries/common/examples/eredita/eredita.ino [new file with mode: 0644]

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..2de42e975d4bc038ec21bde50c87c5b76b3ba70d 100644 (file)
@@ -22,88 +22,175 @@ RGBLed::RGBLed(byte pinR, byte pinG, byte pinB) {
       pinMode(greenPin, OUTPUT);
 };
 
+void RGBLed::SetColor (byte r, byte g, byte b) {
+// Imposta il colore di un LED RGB
+      analogWrite(redPin,   r);
+      analogWrite(greenPin, g);
+      analogWrite(bluePin,  b);
+    };
+
 void RGBLed::Red () {
 // Accende il LED di rosso
-      analogWrite(redPin,   0);
-      analogWrite(greenPin, 255);
-      analogWrite(bluePin,  255);
+      SetColor(0,255,255);
     };
 
 void RGBLed::Green () {
 // Accende il LED di verde
-      analogWrite(redPin,   255);
-      analogWrite(greenPin, 0);
-      analogWrite(bluePin,  255);
+      SetColor(255,0,255);
     };
 
 void RGBLed::Blue () {
 // Accende il LED di blu
-      analogWrite(redPin,   255);
-      analogWrite(greenPin, 255);
-      analogWrite(bluePin,  0);
+      SetColor(255,255,0);
     };
 
 void RGBLed::Magenta () {
 // Accende il LED di magenta
-      analogWrite(redPin,   0);
-      analogWrite(greenPin, 255);
-      analogWrite(bluePin,  0);
+      SetColor(0,255,0);
     };
 
 void RGBLed::Cyano () {
 // Accende il LED di Cyano
-      analogWrite(redPin,   255);
-      analogWrite(greenPin, 0);
-      analogWrite(bluePin,  0);
+      SetColor(255,0,0);
     };
 
 void RGBLed::Yellow () {
 // Accende il LED di giallo
-      analogWrite(redPin,   0);
-      analogWrite(greenPin, 0);
-      analogWrite(bluePin,  255);
+      SetColor(0,0,255);
     };
 
 void RGBLed::White () {
 // Accende il LED 
-      analogWrite(redPin,   0);
-      analogWrite(greenPin, 0);
-      analogWrite(bluePin,  0);
+      SetColor(0,0,0);
     };
 
 void RGBLed::Off () {
 // Spegne il LED 
-      analogWrite(redPin,   255);
-      analogWrite(greenPin, 255);
-      analogWrite(bluePin,  255);
+      SetColor(255,255,255);
     };
 
-void RGBLed::SetColor (byte r, byte g, byte b) {
-      // Imposta il colore di un LED RGB
 
-      analogWrite(redPin,   r);
-      analogWrite(greenPin, g);
-      analogWrite(bluePin,  b);
+
+/////////////////////////////////////
+// Lampeggiatore
+// Constructor
+Lampeggiatore::Lampeggiatore(int pin)
+{
+    ledPin = pin;
+    pinMode(ledPin, OUTPUT);
+    ledState = LOW;
+    previousMillis = 0;
+    interval = 500;
+};
+
+
+
+
+// Una funzione facente parte di una classe prende il nome di "metodo" della stessa:
+void Lampeggiatore::Blink() {
+    // Illumina il led a 500ms
+
+    if(millis() - previousMillis > interval) {
+        // save the last time you blinked the LED
+        previousMillis = millis();
+
+        // if the LED is off turn it on and vice-versa:
+        ledState = !ledState ; // Inverti il LED
+    }
+    // set the LED with the ledState of the variable:
+    digitalWrite(ledPin, ledState);
+};
+
+void Lampeggiatore::Blink(long time) {
+    // Illumina il led secondo un intervallo passato come argomento
+
+    if(millis() - previousMillis > time) {
+        // save the last time you blinked the LED
+        previousMillis = millis();
+
+        // if the LED is off turn it on and vice-versa:
+        ledState = !ledState ; // Inverti il LED
+    }
+    // set the LED with the ledState of the variable:
+    digitalWrite(ledPin, ledState);
+};
+
+void Lampeggiatore::Blink(long up, long down) {
+    // Illumina il ledB precisando ontime e downtime
+
+    if((ledState == HIGH)&& (millis() - previousMillis > up)) {
+    // save the last time you blinked the LED
+       previousMillis = millis();
+        ledState = LOW  ;
+    }
+    else if((ledState == LOW)&& (millis() - previousMillis > down)) {
+       previousMillis = millis();
+        ledState = HIGH  ;
+    }
+
+    // set the LED with the ledState of the variable:
+    digitalWrite(ledPin, ledState);
+};
+
+/////////////////////////////////////
+// Pwm
+// Constructor
+Pwm::Pwm(int pin)
+{
+    ledPin = pin;
+    pinMode(ledPin, OUTPUT);
+    previousMillis = 0;
+    byte brightness = 0 ;
+    increment = 1;
+};
+
+void Pwm::Up(long speed) {
+    // Aumenta progressivamente la luminosita' usanndo millis()
+    // quindi senza bloccare il processore
+
+    analogWrite(ledPin, brightness);  // La funziona analogWrite utilizza il PWM
+    // a 8 bit integrato nel MCU: simula un serie di valori intermedi
+    // nell'intervallo discreto con minimo 0 (spento) e  massimo 255 (acceso).
+
+    if ((millis() - previousMillis) > speed / 256) {
+        brightness++; // Incrementiamo la luminosita'
+        previousMillis = millis();
+    };
+}
+
+void Pwm::Down(long speed ) {
+    // Riduce progressivamente la luminosita' usanndo millis()
+    // quindi senza bloccare il processore
+
+    analogWrite(ledPin, brightness);  // La funziona analogWrite utilizza il PWM
+    // a 8 bit integrato nel MCU: simula un serie di valori intermedi
+    // nell'intervallo discreto con minimo 0 (spento) e  massimo 255 (acceso).
+
+    if ((millis() - previousMillis) > speed / 256) {
+        brightness--; // Incrementiamo la luminosita'
+        previousMillis = millis();
+    };
+}
+
+void Pwm::UD(long speed ) {
+    // Aumenta e riduce in sequenza la luminosita' usanndo millis()
+    if ((millis() - previousMillis) > speed / 512) {
+        brightness = brightness + increment; // Incrementiamo la luminosita'
+        previousMillis = millis();
+        if (brightness == 0 || brightness == 255) { // Reverse direction
+            increment = -increment ;
+        };
     };
+    analogWrite(ledPin, brightness);
+}
+
 
 
 //////////////////
 // Funzioni
 
-void brilla(byte pin) {
-  // Accende e spegne il LED senza un argomento 
-  // per impostare la velocita'.
-  const int velocita = 500;
 
-pinMode(pin, OUTPUT); 
-  // sequenze di istruzione: accendere e spegnere il LED
-  digitalWrite(pin, HIGH);   // turn the LED on (HIGH is the voltage level)
-  delay(velocita);               // wait for a second
-  digitalWrite(pin, LOW);    // turn the LED off by making the voltage LOW
-  delay(velocita);               // wait for a second
-};
-
-void brilla(byte pin, int velocita) {
+void brilla(byte pin, int velocita ) { // Defalt value di velocita' solo nell'Header
   // Accende e spegne il LED accetando un argomento 
   // per impostare la velocita'.
 
@@ -114,3 +201,4 @@ pinMode(pin, OUTPUT);
   digitalWrite(pin, LOW);    // turn the LED off by making the voltage LOW
   delay(velocita);               // wait for a second
 };
+
index 71cb19a84efa0670564ff0673d9d90662e42ebba..c1cfc39636211e0da00312226b527b84b3db1544 100644 (file)
@@ -12,7 +12,7 @@
 
 class RGBLed {
   // Classe rappresentativa di un LED RGB
-  
+  protected:    // Vedi esempio Ereditarieta'
     byte redPin ;
     byte greenPin ;
     byte bluePin ;
@@ -22,6 +22,7 @@ class RGBLed {
 
   public:
     RGBLed (byte pinR, byte pinG, byte pinB) ;
+       void SetColor (byte r, byte g, byte b) ;
        void Red ();
     void Green ();
     void Blue ();
@@ -30,9 +31,53 @@ class RGBLed {
     void White ();
     void Yellow ();
     void Off ();
-       void SetColor (byte r, byte g, byte b) ;
 };
 
-void brilla(byte pin, int velocita = 500) ;
 
+
+class Lampeggiatore {
+    // Lampeggia un LED utilizzando millis()
+    // Variabili
+    int ledPin ;           // il numero del LED pin
+    int ledState ;         // stato attuale del LED
+    long interval ;        // milliseconds di intervallo nel lampeggiare
+    long previousMillis ;  // precedente cambio di stato
+
+
+    // Constructor: come viene instanziato un oggetto facente parte della classe
+public:
+    Lampeggiatore(int pin);
+    void Blink();      // Lampeggia ogni 500ms
+    void Blink(long interval); // Lampeggia inpostando l'intervallo
+    void Blink(long on, long down); // Imposta il tempo acceso e il tempo spento
+};
+
+
+
+////////////////////////////
+class Pwm {
+    /*
+       PWM per un LED: aumentare progressivamente la luminosita'.
+       Utilizza la funzione millis() invece che un delay()
+       in modo da non blocare il processore.
+    */
+    // Variabili
+    int ledPin ;           // il numero del LED pin
+    int speed ;            // velocita' del ciclo in ms
+    byte brightness  ;      // luminostia' iniziale
+    long previousMillis ;  //precedente cambio di stato
+    byte increment ;        // aumenta brighteness nel loop UD
+
+    // Constructor: come viene instanziato un oggetto facente parte della classe
+public:
+    Pwm(int pin);  // numero di pin, velocita' di ciclo
+    void Up(long speed);
+    void Down(long speed);
+    void UD(long speed);
+};
+
+//////////////////////
+// Funzioni
+
+void brilla(byte pin, int velocita = 200) ;
 #endif
diff --git a/libraries/common/examples/eredita/eredita.ino b/libraries/common/examples/eredita/eredita.ino
new file mode 100644 (file)
index 0000000..88a718b
--- /dev/null
@@ -0,0 +1,39 @@
+/* Ereditarieta'
+   
+   La classe SuperLED definita in questo sketch
+   eredita le caratteristiche di RGBLed e introduce un nuovo metodo.
+
+*/
+
+#include <common.h> // L'orine e' importante: prima l'include,
+                    // poi la dichiarazione della nuova classe (non a fondo pagina)
+                    // poi potremo usare la nuova classe
+
+class SuperLED : public RGBLed { // Ereditamo dalla classe RGBLed
+    // Nuovi colori per RGBLed
+
+  using RGBLed::RGBLed ;  // Richiamiamo il constructor del genitore
+  public:
+    void Violet () {        // Nuovo metodo
+    // Accende il LED di viola
+          analogWrite(redPin,   255 - 238);
+          analogWrite(greenPin, 255 - 130);
+          analogWrite(bluePin,  255 - 238);
+        };
+};
+
+void setup() {
+  // I PINs vengono impostati dalla dichiarazione dell'ogetto.
+}
+
+// Instanziamo un LED
+SuperLED led(11, 10, 9); //Istanziamo un oggetto led facente parte
+                         // della inuova classe SuperLed che eredita da RGBLed
+
+void loop() {
+  led.Violet(); // Nuovo metodo
+  delay(1000);
+  led.Off();
+  delay(1000);  // Vecchio metodo
+}
+