+++ /dev/null
-/*
- 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);
-
-}
--- /dev/null
+/*
+ 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?
+ */
--- /dev/null
+/*
+ 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);
+
+}
--- /dev/null
+/*
+ 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.
+ */
--- /dev/null
+/*
+ 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.
+ */
--- /dev/null
+/*
+ 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.
+ */
--- /dev/null
+/*
+ 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.
+ */
+++ /dev/null
-/*
- 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?
- */
+++ /dev/null
-/*
- 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.
- */
--- /dev/null
+/*
+ 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.
+ */
+++ /dev/null
-/*
-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
/* 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"
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);
/*
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
void SetColor (byte r, byte g, byte b) ;
};
+/////////////////////////////////////////////
void brilla(byte pin, int velocita = 500) ;
#endif