Clean up multitasking, bottoni con pooling e interrupts
authorAndrea Manni <andrea@piffa.net>
Wed, 19 Apr 2017 17:16:05 +0000 (19:16 +0200)
committerAndrea Manni <andrea@piffa.net>
Wed, 19 Apr 2017 17:16:05 +0000 (19:16 +0200)
14 files changed:
basic/blinks/millis/millis.ino
basic/buttons/blink_5_pooling/blink_5_pooling.ino [new file with mode: 0644]
basic/buttons/blink_6_interrupt/blink_6_interrupt.ino [new file with mode: 0644]
multitasking/BlinkWithoutDelay_1/BlinkWithoutDelay_1.ino
multitasking/BlinkWithoutDelay_2_led/BlinkWithoutDelay_2_led.ino
multitasking/BlinkWithoutDelay_2_led_cleanup/BlinkWithoutDelay_2_led_cleanup.ino
multitasking/BlinkWithoutDelay_3_funzione/BlinkWithoutDelay_3_funzione.ino
multitasking/BlinkWithoutDelay_5_cleanup/BlinkWithoutDelay_5_cleanup.ino
multitasking/BlinkWithoutDelay_7_struct/BlinkWithoutDelay_7_struct.ino
multitasking/BlinkWithoutDelay_8_struct_pointer/BlinkWithoutDelay_8_struct_pointer.ino
multitasking/blink_0_soluzione/blink_0_soluzione.ino
piezo/piezo_2_keyboard/piezo_2_keyboard.ino
piezo/piezo_4_mario_tune/piezo_4_mario_tune.ino
programming/structured_data_types/struct_risposta/struct_risposta.ino

index 90f0c43..e0f5577 100644 (file)
@@ -11,7 +11,7 @@ Schema: https://lab.piffa.net/schemi/circuito_led_bb.png
 
 const int led = 13;      // Primo LED
               
-unsigned long previousMillis = 0;        // Ultimo agiornamento
+unsigned long previousMillis = 0;        // Ultimo aggiornamento
 unsigned long interval = 1000;           // Pausa tra i lampeggi
 
 void setup() {
diff --git a/basic/buttons/blink_5_pooling/blink_5_pooling.ino b/basic/buttons/blink_5_pooling/blink_5_pooling.ino
new file mode 100644 (file)
index 0000000..334ae39
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+  Blink v1
+
+  Accensione e spegnimanto di due LED utilizzando la tecnica del pooling:
+  un ciclo if nel loop verifica periodicamente tramite digitalRead
+  se un bottone e' premuto.
+
+  Il codice e' blocking a causa dell'uso della funziona delay
+  di conseguenza il pool del del bottone puo' avvenire solo quando
+  il microcontroller non e' in delay.
+
+  Nell'esercizio successivo (blink_interrupt) viene usato un interrupt
+  per intercettare la pressione del bottone.
+
+ */
+
+// Pin 13 ha un LED collegato di default
+const int ledA = 13;
+const int ledB = 12; //Secondo LED, con resistenza
+const int pausa = 2000; 
+
+void setup() {
+  // Inizializziamo il PIN 13 come OUTPUT
+  pinMode(ledA, OUTPUT);
+  pinMode(ledB, OUTPUT);
+
+  pinMode(2, INPUT_PULLUP);
+}
+
+void loop() {
+  digitalWrite(ledA, HIGH);
+  delay(pausa);
+  digitalWrite(ledA, LOW);
+  delay(pausa);
+
+  if (!digitalRead(2)) {
+     digitalWrite(ledB, !digitalRead(ledB));
+  }
+
+}
+
diff --git a/basic/buttons/blink_6_interrupt/blink_6_interrupt.ino b/basic/buttons/blink_6_interrupt/blink_6_interrupt.ino
new file mode 100644 (file)
index 0000000..7ddf386
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+  Blink v1
+
+  Accensione e spegnimanto di due LED utilizzando un interrupt:
+  un interrupt associato al PIN del bottone sollecita una ISR routine
+  che puo' essere richiamata in ogni momento a prescindere
+  da cosa il microprocessore sta facendo nel loop.
+
+  Nota: per togliere l'effetto bouncing del bottone:
+  - https://www.arduino.cc/en/tutorial/debounce
+  vedi esercizio: sketchbook_andrea/advanced_projects/interrupts/debounce/debounce.ino
+- https://lab.piffa.net/sketchbook_andrea/advanced_projects/interrupts/debounce/debounce.ino
+ */
+
+// Pin 13 ha un LED collegato di default
+const int ledA = 13;
+const int ledB = 12; //Secondo LED, con resistenza
+const int pausa = 5000; 
+
+void setup() {
+  // Inizializziamo il PIN 13 come OUTPUT
+  pinMode(ledA, OUTPUT);
+  pinMode(ledB, OUTPUT);
+
+  pinMode(2, INPUT_PULLUP);
+  attachInterrupt(0, reazioneISR, FALLING); // 0 e' l'interrupt numero 0
+  // connesso al PIN D2, l'interrupt 1 e' connesso al PIN D3
+  // eventoAttivo : nome della funzione da richiamare
+  // per un ISRs e' sempre VOID
+  // LOW | RISING | FALLIN | CHANGE | HIGH
+}
+
+void loop() {
+  digitalWrite(ledA, HIGH);
+  delay(pausa);
+  digitalWrite(ledA, LOW);
+  delay(pausa);
+}
+
+void reazioneISR() // Sempre VOID
+{
+  digitalWrite(ledB, !digitalRead(ledB));
+}
+
index 408fd16..cd1a4cf 100644 (file)
@@ -1,5 +1,5 @@
 /* Blink without Delay
+
  Utilizziamo la funzione millis() al posto di delay()
  per poter gestire il lampeggio di un LED senza bloccare
  il processore.
@@ -8,69 +8,54 @@
  nei quali una versione minimale si evolve per introdurre
  programmazione ad oggetti, interrupts, pointers.
 
- Turns on and off a light emitting diode(LED) connected to a digital  
- pin, without using the delay() function.  This means that other code
- can run at the same time without being interrupted by the LED code.
- The circuit:
- * LED attached from pin 13 to ground.
- * Note: on most Arduinos, there is already an LED on the board
- that's attached to pin 13, so no hardware is needed for this example.
- created 2005
- by David A. Mellis
- modified 8 Feb 2010
- by Paul Stoffregen
- 2015 modified by Andrea Manni
- This example code is in the public domain.
+Per vedere direttamente un esempio succinto:
+- https://lab.piffa.net/sketchbook_andrea/basic/blinks/millis/millis.ino
 
- http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
- */
+Schema: https://lab.piffa.net/schemi/millis_bb.png
 
-// constants won't change. Used here to 
-// set pin numbers:
-const int ledPin =  13;      
+Tutorial:
+- http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
+ */
 
-// Variables will change:
-int ledState = LOW;             // ledState used to set the LED
-long previousMillis = 0;        // will store last time LED was updated
+const int ledPin =  13;
 
-// the follow variables is a long because the time, measured in miliseconds,
-// will quickly become a bigger number than can be stored in an int.
-const long interval = 1000;           // interval at which to blink (milliseconds)
+// Variabili
+boolean ledState = LOW;    // Variabile associata allo stato del LED
+unsigned long previousMillis = 0;  // Timestamp dell'ultimo aggiornamento,
+// previousMillis dovra' essere di tipo long in quanto deve contenere numeri grandi
+// e sara' sempre positiva quindi unsigned.
+const unsigned long interval = 1000;  // Intervallo tra un blink e l'altro (milliseconds)
+// Dato che dovra' essere aggiunta ad altre variabili long e unsigned tanto vale
+// fare anche interval come quelle
 
 void setup() {
-  // set the digital pin as output:
-  pinMode(ledPin, OUTPUT);      
+  pinMode(ledPin, OUTPUT);
 }
 
 void loop()
 {
-  // here is where you'd put code that needs to be running all the time.
+  // Verifichiamo se e' il momento di modificare lo variabile
+  // associata allo stato del LED.
+
+  if (millis() - previousMillis >= interval) {
+    // Timestamp + timestamp = delta temporale
 
-  // check to see if it's time to blink the LED; that is, if the 
-  // difference between the current time and last time you blinked 
-  // the LED is bigger than the interval at which you want to 
-  // blink the LED.
-  if (millis() >= previousMillis + interval) {
+    previousMillis = previousMillis + interval ;
     // Aggiorniamo il contatore previousMillis
-    previousMillis += interval ; 
-    // previousMillis = millis(); // 3) Cosa succederebbe se fosse
-    // passato piu' di 1ms dall'evento all'azione?
 
-    // if the LED is off turn it on and vice-versa:
+    // Se il LED e' spento accendiamolo e vice-versa:
     if (ledState == LOW)
+    {
       ledState = HIGH;
+    }
     else
+    {
       ledState = LOW;
+    }
     // e' possibile semplificare questa operazione?
     // Hint: lo stato del LED e' binario: ha solo due stati possibili.
 
-    // set the LED with the ledState of the variable:
+    // Aggiorniamo lo stato del LED
     digitalWrite(ledPin, ledState);
   }
 }
@@ -79,11 +64,19 @@ void loop()
    1. Aggioungere un LED che brilli ogni 500ms: iniziare pensando
       a quali variabili gestiscono l'attuale LED e a quali si
       dovranno aggiungere.
-   2. E' ora agevole cambiare gli intervalli dei due LED? 
+   2. E' ora agevole cambiare gli intervalli dei due LED?
       Modificare gli intervalli dei due led (es 500ms - 320ms)
-
-
-
+.
+.
+.
+.
+.
+.
+.
+.
+.
+.
+.
    Risposta
    3. Si sarebbe introdotto uno slip (ritardo) nei tempi dello sketch
 
index fb411e9..8270177 100644 (file)
@@ -1,28 +1,19 @@
 /* Blink without Delay - due led
- Turns on and off a light emitting diode(LED) connected to a digital  
- pin, without using the delay() function.  This means that other code
- can run at the same time without being interrupted by the LED code.
- The circuit:
- * LED attached from pin 13 to ground.
- * Note: on most Arduinos, there is already an LED on the board
- that's attached to pin 13, so no hardware is needed for this example.
- created 2005
- by David A. Mellis
- modified 8 Feb 2010
- by Paul Stoffregen
- modified by Andrea Manni
- This example code is in the public domain.
+
+ Utilizziamo la funzione millis() al posto di delay()
+ per poter gestire il lampeggio di un LED senza bloccare
+ il processore.
+
+ Questo esercizio e' strutturato in una serie di passaggi incrementali
+ nei quali una versione minimale si evolve per introdurre
+ programmazione ad oggetti, interrupts, pointers.
+
+Schema: https://lab.piffa.net/schemi/millis_bb.png
+
  http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
  */
 
-// constants won't change. Used here to 
+// constants won't change. Used here to
 // set pin numbers:
 const int ledA = 13;      // Primo LED
 const int ledB = 12;      // Secondo LED
@@ -30,58 +21,52 @@ const int ledB = 12;      // Secondo LED
 // Variabbili di stato
 int ledStateA = LOW;             // ledState used to set the LED
 int ledStateB = LOW;             // ledState used to set the LED
-              
-long previousMillisA = 0;        // will store last time LED was updated
-long previousMillisB = 0;        // will store last time LED was updated
 
-// the follow variables is a long because the time, measured in miliseconds,
-// will quickly become a bigger number than can be stored in an int.
+unsigned long previousMillisA = 0;        // Timestamp dell'ultimo aggiornamento
+unsigned long previousMillisB = 0;        // Timestamp dell'ultimo aggiornamento
+
 long intervalA = 1000;           // interval at which to blink (milliseconds)
 long intervalB = 500;            // interval at which to blink (milliseconds)
 
 void setup() {
-  // set the digital pin as output:
-  pinMode(ledA, OUTPUT);      
-  pinMode(ledB, OUTPUT);  
+  pinMode(ledA, OUTPUT);
+  pinMode(ledB, OUTPUT);
 }
 
 void loop()
 {
-// Primo LED
-  if (millis() >= previousMillisA + intervalA) {
+  // Primo LED
+  if (millis() - previousMillisA >= intervalA) {
     // Aggiornimo il riferimento temporale
     previousMillisA += intervalA;
 
-    // if the LED is off turn it on and vice-versa:
+    // Se il LED e' spento accendiamolo e vice-versa:
     if (ledStateA == LOW)
       ledStateA = HIGH;
     else
       ledStateA = LOW;
-    // set the LED with the ledState of the variable:
     digitalWrite(ledA, ledStateA);
   }
-  
-// Secondo LED
-    if (millis() >= previousMillisB + intervalB) {
-    // save the last time you blinked the LED 
-    previousMillisB += intervalB;
 
-    // if the LED is off turn it on and vice-versa:
+  // Secondo LED
+  if (millis() >= previousMillisB + intervalB) {
+    // save the last time you blinked the LED
+    previousMillisB += intervalB;
+    // Se il LED e' spento accendiamolo e vice-versa:
     if (ledStateB == LOW)
       ledStateB = HIGH;
     else
       ledStateB = LOW;
-    // set the LED with the ledState of the variable:
+    // e' possibile semplificare questa operazione?
+    // Hint: lo stato del LED e' binario: ha solo due stati possibili.
+    
     digitalWrite(ledB, ledStateB);
   }
 }
 
 /* Domande
- 1. Provare a isolare il codice per accendere ogni singolo led in una funzione:
-    - Quali variabili determinano il comportamento del LED?
-    - Come cambiano durante il corso dello script?
-    - Sono globali o locali? 
-    - Quali parti vanno eseguite una sola volta e quali a ogni esecuzione?
+ 1. Cercare di semplificare / ripulire il codice.
  */
 
 
index 7f338a9..6da70a1 100644 (file)
@@ -49,7 +49,7 @@ void loop()
 {
 // Primo LED
   if (millis() - previousMillisA >= intervalA) {
-    // Timestamp + timestamp = delta temporale
+    
     previousMillisA += intervalA ;
 
     // if the LED is off turn it on and vice-versa:
index db0ed89..098b501 100644 (file)
@@ -15,19 +15,15 @@ Variabili: http://www.maffucci.it/2011/12/15/appunti-di-programmazione-su-arduin
 /////////////
 // First LED
 const int ledA =  13;       // the number of the LED pin
-// Variables will change:
 int ledStateA = LOW;        // ledState used to set the LED
 long previousMillisA = 0;   // will store last time LED was updated
-// the follow variables is a long because the time, measured in miliseconds,
-// will quickly become a bigger number than can be stored in an int.
 long intervalA = 1000;      // interval at which to blink (milliseconds)
 void lightLedA () ;
 
 //////////////
 //  Second LED
-// Now with less global variables thanks to static (see function body)
+// Ora con meno variabili globali utilizzando static (vedi corpo della funzione)
 const int ledB = 12; //Secondo LED
-                     // ledState used to set the LED
 long previousMillisB = 0;    // will store last time LED was updated
                              // interval at which to blink (milliseconds)
 void lightLedB () ;
index b0ba86e..b11154e 100644 (file)
@@ -61,8 +61,31 @@ void lightLedB (int interval) {
 /* Domande:
  1. E' possibile avere una sola funzione che permetta di gestire 
     qualunque LED io voglia aggiungere?
+
+.
+.
+.
+.
+.
+.
+.
+.
+.
+.
+.
+.
+  Risposte:
+
+  1. Allo stato attuale la funzione lightLed deve avere una variabile univoca
+     previousMillis per ogni LED che gestisce. Servirebbe un costrutto che permetta
+     di raggruppare le proprieta' di ogni LED (es. struct) da associare poi alla
+     unziona che aggiorna il LED.
+
+     Ancora meglio un costrutto (oggetto) che associ sia le proprita' che le azioni
+     in un unico oggetto.
+         
     
-/* Approfondimenti
+/* Ulteriori approfondimenti
  - integrazione tra funzioni e dati: programmazione a oggetti
  - Uso di pointers per modificare dati esterni allo scope della funzione, static
  - Uso di forme di dati strutturate (array, struct) per scambiare dati tra funzioni e programma
index 8b55527..6f7517d 100644 (file)
@@ -1,7 +1,17 @@
 /* Blink without Delay
- Soluzione
  
- Introdotto un argomento per la funzione che nodifica l'intervallo di lampeggio 
+Raggruppamento delle proprieta' dell'oggetto in uno struct.
+Una funzione accetta e restituisce uno struct di questo tipo
+facendo una "copy by value" (vedi esercizio con i pointers per
+una "copy by reference").
+
+Questo e' un esercizio avanzato: propedeutico a capire le basi
+della programmazione a oggetti (suggerimento: 
+https://lab.piffa.net/sketchbook_andrea/RGB_LED/
+
+e' piu' semplice dato che non usa pointers e references
+non dovendo modificare in modo permanente nessuna variabile
+dello struct).
  */
 
 struct blinkLed {
index d5cd783..9e36670 100644 (file)
@@ -40,7 +40,10 @@ void loop()
 ////////////////
 // Funzioni
 
-void lightLed(struct blinkLed *temp) { // temp ora e' un pointer e non una struttura autonoma: pass by reference (not by value)
+void lightLed(struct blinkLed *temp) { // temp ora e' un pointer e non una copia autonoma: pass by reference (not by value)
+// Si noti che la funzione e' ora void dato che non deve tornare a passare nulla al loop: molto
+piu' semplice (una sorta di polimorfismo).
+  
   // Illumina il ledA secondo un intervallo passato come argomento
 
   if(millis() - (*temp).previousMillis >= (*temp).interval) { // l'operatore punto ha priorita' maggiore rispetto al pointer asterisco
index 8c302d9..2077b6b 100644 (file)
@@ -7,6 +7,7 @@
  Massimo comun denominatore 1000 MCD 500 = 500ms
  Durata Periodo = 500ms
  
+ Schema: https://lab.piffa.net/schemi/millis_bb.png
  
  Stati: 
  
@@ -56,26 +57,6 @@ void loop() {
 }
 
 /* Domande
- 1. Altro scenartio: fare brillare un LED ogni 300ms mentre il secondo brilla ogni 400m
+ 1. Altro scenario: fare brillare un LED ogni 300ms mentre il secondo brilla ogni 400m
  2. ...valutare come aggiungere un terzo LED, gestire altri intevalli.
  */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
index 2df467f..8d09d08 100644 (file)
@@ -44,7 +44,7 @@ void loop() {
         if (sensorReading == LOW) {
             Serial.print("Sensore: ");
             Serial.print(thisSensor);
-            tone(piezo_pin, notes[thisSensor ], 50); // Notes array is translated
+            tone(piezo_pin, notes[thisSensor], 50); // Notes array is translated
             Serial.print("\t Nota: ");
             Serial.println(notes[thisSensor]);
         }
index 12dc602..e73aab1 100644 (file)
@@ -4,9 +4,9 @@
   by: Dipto Pratyaksa
   last updated: 31/3/13
 */
-#include <pitches.h>
+#include "pitches.h"
 //#include "/home/utente/sketchbook-andrea/piezo/piezo_mario_tune/pitches.h";
-#define melodyPin 3
+#define melodyPin 9
 //Mario main theme melody
 int melody[] = {
   NOTE_E7, NOTE_E7, 0, NOTE_E7, 
@@ -111,7 +111,7 @@ int underworld_tempo[] = {
 
 void setup(void)
 {
-   pinMode(3, OUTPUT);//buzzer
+   pinMode(melodyPin, OUTPUT);//buzzer
    pinMode(13, OUTPUT);//led indicator when singing a note
 
 }