]> git.piffa.net Git - sketchbook_andrea/commitdiff
State machine e blinks con millis()
authoreaman <andrea@piffa.net>
Wed, 19 Oct 2016 01:32:24 +0000 (03:32 +0200)
committereaman <andrea@piffa.net>
Wed, 19 Oct 2016 01:32:24 +0000 (03:32 +0200)
13 files changed:
advanced_projects/state_machine/blink/blink.ino [new file with mode: 0644]
advanced_projects/state_machine/semaforo_rgb/semaforo_rgb.ino [new file with mode: 0644]
advanced_projects/state_machine/semaforo_rgb_stimolo/semaforo_rgb_stimolo.ino [new file with mode: 0644]
advanced_projects/state_machine/semaphore/semaphore.ino [new file with mode: 0644]
multitasking/BlinkWithoutDelay_1/BlinkWithoutDelay_1.ino
multitasking/BlinkWithoutDelay_2_led/BlinkWithoutDelay_2_led.ino
multitasking/BlinkWithoutDelay_3_funzione/BlinkWithoutDelay_3_funzione.ino
multitasking/BlinkWithoutDelay_4_argomento/BlinkWithoutDelay_4_argomento.ino
multitasking/BlinkWithoutDelay_5_cleanup/BlinkWithoutDelay_5_cleanup.ino
multitasking/BlinkWithoutDelay_6_1_interrupt/BlinkWithoutDelay_6_1_interrupt.ino
multitasking/BlinkWithoutDelay_6_class/BlinkWithoutDelay_6_class.ino
multitasking/BlinkWithoutDelay_7_struct/BlinkWithoutDelay_7_struct.ino
multitasking/BlinkWithoutDelay_8_struct_pointer/BlinkWithoutDelay_8_struct_pointer.ino

diff --git a/advanced_projects/state_machine/blink/blink.ino b/advanced_projects/state_machine/blink/blink.ino
new file mode 100644 (file)
index 0000000..485c2f2
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+   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_rgb/semaforo_rgb.ino b/advanced_projects/state_machine/semaforo_rgb/semaforo_rgb.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_rgb_stimolo/semaforo_rgb_stimolo.ino b/advanced_projects/state_machine/semaforo_rgb_stimolo/semaforo_rgb_stimolo.ino
new file mode 100644 (file)
index 0000000..de2373b
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+   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/semaphore/semaphore.ino b/advanced_projects/state_machine/semaphore/semaphore.ino
new file mode 100644 (file)
index 0000000..f309a6a
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+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 f7fee43e2b2d63d4f75d69ccc47ae5e54180c4ca..72a9694039bd500a5f25961f2c5390b428bf7ed9 100644 (file)
@@ -48,7 +48,7 @@ void loop()
   // the LED is bigger than the interval at which you want to 
   // blink the LED.
  
-  if(millis() - previousMillis > interval) {
+  if (millis() > previousMillis + interval) {
     // Aggiorniamo il contatore previousMillis
     previousMillis = millis();   
 
index 02833391a3f1d6fdee3a939c0a2a7e32c9a40170..2100ead96aaba26397c4f252881e6c134b79eac6 100644 (file)
@@ -48,7 +48,7 @@ void setup() {
 void loop()
 {
 // Primo LED
-  if(millis() - previousMillisA > intervalA) {
+  if (millis() > previousMillisA + intervalA) {
     // save the last time you blinked the LED 
     previousMillisA = millis();   
 
@@ -62,7 +62,7 @@ void loop()
   }
   
 // Secondo LED
-    if(millis() - previousMillisB > intervalB) {
+    if (millis() > previousMillisB + intervalB) {
     // save the last time you blinked the LED 
     previousMillisB = millis();   
 
index 93387bd7d4d174efdad86c442670b01dc1f028bd..e27cf55d8c4e1de6ff5e67fa5022d7826c6b6198 100644 (file)
@@ -47,7 +47,7 @@ void loop()
 // Funzioni:
 
 void lightLedA () {
-  if(millis() - previousMillisA > intervalA) {
+  if (millis() > previousMillisA + intervalA) {
     // save the last time you blinked the LED 
     previousMillisA = millis();   
 
@@ -65,7 +65,7 @@ void lightLedA () {
 void lightLedB () {
   long intervalB = 500;
    static int ledStateB ;  // https://www.arduino.cc/en/Reference/Static
-  if(millis() - previousMillisB > intervalB) {
+  if (millis() > previousMillisB + intervalB) {
     // save the last time you blinked the LED 
     previousMillisB = millis();   
 
index ae2205af4810eb34e9af2359503cd1bfcef8e3e8..e2b28a94d3523ad83f078074dddbc0e7ab50f797 100644 (file)
@@ -34,7 +34,7 @@ void loop()
 void lightLedA (int interval) {
   // Illumina il ledA secondo un intervallo passato come argomento
 
-  if(millis() - previousMillisA > interval) {
+  if (millis() > previousMillisA + interval) {
     // save the last time you blinked the LED 
     previousMillisA = millis();   
 
@@ -52,7 +52,7 @@ void lightLedA (int interval) {
 void lightLedB (int interval) {
   // Illumina il ledB secondo un intervallo passato come argomento
 
-  if(millis() - previousMillisB > interval) {
+  if (millis() > previousMillisB + interval) {
     // save the last time you blinked the LED 
     previousMillisB = millis();   
 
index 2a74c5c6364d1a3e302b629a85cda3763e71c405..824c53f276e319ad11441e137ea80d1f997d27c1 100644 (file)
@@ -38,7 +38,7 @@ void loop()
 void lightLedA (int interval) {
   // Illumina il ledA secondo un intervallo passato come argomento
 
-  if(millis() - previousMillisA > interval) {
+  if (millis() > previousMillisA + interval) {
     // save the last time you blinked the LED 
     previousMillisA = millis();   
 
@@ -51,7 +51,7 @@ void lightLedA (int interval) {
 void lightLedB (int interval) {
   // Illumina il ledB secondo un intervallo passato come argomento
 
-  if(millis() - previousMillisB > interval) {   
+  if (millis() > previousMillisB + interval) {   
     previousMillisB = millis(); 
   digitalWrite(ledB, !digitalRead(ledB));
   // Leggiamo direttamente il registro di ledB e scriviamo il suo opposto,
index 60181955071809027aed327a792ee2361632c05a..175f70567a420a94be0253115318a7f037ba100e 100644 (file)
@@ -28,7 +28,7 @@ public:
   void Update () {
     // Illumina il ledB secondo un intervallo passato come argomento
 
-    if(millis() - previousMillis > interval) {
+    if (millis() > previousMillis + interval) {
       // save the last time you blinked the LED 
       previousMillis = millis();   
 
index 7a1f27e3363469c4a83b1166032a29d1d4bf2ce7..9ce5e9bf01e24b380a6cc01d4e7f63b296c36e71 100644 (file)
@@ -28,7 +28,7 @@ public:
   void Update () {
     // Illumina il ledB secondo un intervallo passato come argomento
 
-    if(millis() - previousMillis > interval) {
+    if (millis() > previousMillis + interval) {
       // save the last time you blinked the LED 
       previousMillis = millis();   
 
index 61a53b5b587dfa93160f11f616e5d62f89d93745..e72666285569423af9762ee8e6c6b2cc2966c32c 100644 (file)
@@ -37,7 +37,7 @@ void loop()
 struct blinkLed lightLed(struct blinkLed temp) { // dataType tipo_di_struct nome_funzione(argomenti)
   // Illumina il ledA secondo un intervallo passato come argomento
 
-  if(millis() - temp.previousMillis > temp.interval) { // gli elementi dello struct sono accessibili tramite l'operatore [punto]
+  if (millis() > temp.previousMillis + temp.interval) { // gli elementi dello struct sono accessibili tramite l'operatore [punto]
     // save the last time you blinked the LED 
     temp.previousMillis = millis();   
 
index 635642d50afe9f299189304c9ac547add9affa55..f038199e6d1743ff516441a5bc56ac83209e6f96 100644 (file)
@@ -20,7 +20,7 @@ struct blinkLed {
   long interval ;        // milliseconds di intervallo nel lampeggiare
   long previousMillis ;  //precedente cambio di stato  
 };
-// Instanziamo i due led dalla struttur 
+// Instanziamo i due led dalla struttura
 blinkLed ledA = {
   13 , LOW , 1000, 0 };
 blinkLed ledB = {