From: Andrea Manni Date: Wed, 19 Apr 2017 17:16:05 +0000 (+0200) Subject: Clean up multitasking, bottoni con pooling e interrupts X-Git-Url: http://git.piffa.net/web?a=commitdiff_plain;h=e4de8b95aa9b8019b3fff9416918a4840aae46b5;p=sketchbook_andrea Clean up multitasking, bottoni con pooling e interrupts --- diff --git a/basic/blinks/millis/millis.ino b/basic/blinks/millis/millis.ino index 90f0c43..e0f5577 100644 --- a/basic/blinks/millis/millis.ino +++ b/basic/blinks/millis/millis.ino @@ -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 index 0000000..334ae39 --- /dev/null +++ b/basic/buttons/blink_5_pooling/blink_5_pooling.ino @@ -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 index 0000000..7ddf386 --- /dev/null +++ b/basic/buttons/blink_6_interrupt/blink_6_interrupt.ino @@ -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)); +} + diff --git a/multitasking/BlinkWithoutDelay_1/BlinkWithoutDelay_1.ino b/multitasking/BlinkWithoutDelay_1/BlinkWithoutDelay_1.ino index 408fd16..cd1a4cf 100644 --- a/multitasking/BlinkWithoutDelay_1/BlinkWithoutDelay_1.ino +++ b/multitasking/BlinkWithoutDelay_1/BlinkWithoutDelay_1.ino @@ -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 diff --git a/multitasking/BlinkWithoutDelay_2_led/BlinkWithoutDelay_2_led.ino b/multitasking/BlinkWithoutDelay_2_led/BlinkWithoutDelay_2_led.ino index fb411e9..8270177 100644 --- a/multitasking/BlinkWithoutDelay_2_led/BlinkWithoutDelay_2_led.ino +++ b/multitasking/BlinkWithoutDelay_2_led/BlinkWithoutDelay_2_led.ino @@ -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. + */ diff --git a/multitasking/BlinkWithoutDelay_2_led_cleanup/BlinkWithoutDelay_2_led_cleanup.ino b/multitasking/BlinkWithoutDelay_2_led_cleanup/BlinkWithoutDelay_2_led_cleanup.ino index 7f338a9..6da70a1 100644 --- a/multitasking/BlinkWithoutDelay_2_led_cleanup/BlinkWithoutDelay_2_led_cleanup.ino +++ b/multitasking/BlinkWithoutDelay_2_led_cleanup/BlinkWithoutDelay_2_led_cleanup.ino @@ -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: diff --git a/multitasking/BlinkWithoutDelay_3_funzione/BlinkWithoutDelay_3_funzione.ino b/multitasking/BlinkWithoutDelay_3_funzione/BlinkWithoutDelay_3_funzione.ino index db0ed89..098b501 100644 --- a/multitasking/BlinkWithoutDelay_3_funzione/BlinkWithoutDelay_3_funzione.ino +++ b/multitasking/BlinkWithoutDelay_3_funzione/BlinkWithoutDelay_3_funzione.ino @@ -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 () ; diff --git a/multitasking/BlinkWithoutDelay_5_cleanup/BlinkWithoutDelay_5_cleanup.ino b/multitasking/BlinkWithoutDelay_5_cleanup/BlinkWithoutDelay_5_cleanup.ino index b0ba86e..b11154e 100644 --- a/multitasking/BlinkWithoutDelay_5_cleanup/BlinkWithoutDelay_5_cleanup.ino +++ b/multitasking/BlinkWithoutDelay_5_cleanup/BlinkWithoutDelay_5_cleanup.ino @@ -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 diff --git a/multitasking/BlinkWithoutDelay_7_struct/BlinkWithoutDelay_7_struct.ino b/multitasking/BlinkWithoutDelay_7_struct/BlinkWithoutDelay_7_struct.ino index 8b55527..6f7517d 100644 --- a/multitasking/BlinkWithoutDelay_7_struct/BlinkWithoutDelay_7_struct.ino +++ b/multitasking/BlinkWithoutDelay_7_struct/BlinkWithoutDelay_7_struct.ino @@ -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 { diff --git a/multitasking/BlinkWithoutDelay_8_struct_pointer/BlinkWithoutDelay_8_struct_pointer.ino b/multitasking/BlinkWithoutDelay_8_struct_pointer/BlinkWithoutDelay_8_struct_pointer.ino index d5cd783..9e36670 100644 --- a/multitasking/BlinkWithoutDelay_8_struct_pointer/BlinkWithoutDelay_8_struct_pointer.ino +++ b/multitasking/BlinkWithoutDelay_8_struct_pointer/BlinkWithoutDelay_8_struct_pointer.ino @@ -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 diff --git a/multitasking/blink_0_soluzione/blink_0_soluzione.ino b/multitasking/blink_0_soluzione/blink_0_soluzione.ino index 8c302d9..2077b6b 100644 --- a/multitasking/blink_0_soluzione/blink_0_soluzione.ino +++ b/multitasking/blink_0_soluzione/blink_0_soluzione.ino @@ -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. */ - - - - - - - - - - - - - - - - - - - - diff --git a/piezo/piezo_2_keyboard/piezo_2_keyboard.ino b/piezo/piezo_2_keyboard/piezo_2_keyboard.ino index 2df467f..8d09d08 100644 --- a/piezo/piezo_2_keyboard/piezo_2_keyboard.ino +++ b/piezo/piezo_2_keyboard/piezo_2_keyboard.ino @@ -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]); } diff --git a/piezo/piezo_4_mario_tune/piezo_4_mario_tune.ino b/piezo/piezo_4_mario_tune/piezo_4_mario_tune.ino index 12dc602..e73aab1 100644 --- a/piezo/piezo_4_mario_tune/piezo_4_mario_tune.ino +++ b/piezo/piezo_4_mario_tune/piezo_4_mario_tune.ino @@ -4,9 +4,9 @@ by: Dipto Pratyaksa last updated: 31/3/13 */ -#include +#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 } diff --git a/programming/structured_data_types/struct_risposta/struct_risposta.ino b/programming/structured_data_types/struct_risposta/struct_risposta.ino index 25b1c48..1b3588d 100644 --- a/programming/structured_data_types/struct_risposta/struct_risposta.ino +++ b/programming/structured_data_types/struct_risposta/struct_risposta.ino @@ -27,5 +27,3 @@ void loop() // Utilizziamo un lampeggiatore lampeggia(rosso); } - -