Durante la progettazione di un sistema di automazione accade frequentemente di avere la necessità di ripetere, sequenzialmente e in modo continuo, l’attivazione di apparati (ad es. motori) oppure la lettura continua dei dati provenienti da più sensori. Come attività di ripasso per i miei studenti ho deciso di riprendere alcuni argomenti affrontati nelle scorse settimane con specifiche esperienze di laboratorio:
- automi a stati finiti;
- utilizzo degli array;
- input valori interi da serial monitor;
- marcia, arresto, pausa di sequenze;
- controllo uscite digitali mediante ingressi analogici;
- realizzazione di commutatori con pulsanti con uno o più pulsanti;
- utilizzo corretto dei tipi di dati per risparmiare memoria;
- e molto altro
Di seguito 9 sketch in cui vengono ripresi gli argomenti sopra elencati e che potranno essere utilizzati nei prossimi mesi per sviluppare ulteriori sperimentazioni.
Come sempre all’interno degli sketch proposti trovate le spiegazioni di ogni parte del codice ed in alcuni casi trovate link di approfondimento che rimandano a questo sito.
Per ripercorrere gli argomenti svolti partirò dal classico sketch che permette di realizza l’accensione sequenziale di LED, come quello che potete trovare nelle mie slice: Alfabeto Arduino – Lezione 2 a pagina 66.
I LED nel circuito identificano gli apparati da attivare sequenzialmente, realizzando così il classico effetto “super car” (i diversamente giovani 🙂 sanno perché si chiama così).
Circuito e sketch verranno poi modificati per rispondere alle specifiche indicate ad inizio di ogni esempio.
Sketch 01
Sequenza di accensione e spegnimento da destra e sinistra e viceversa di 8 LED con tempo di accensione di 100 millisecondi.
/* Prof. Michele Maffucci 30.12.2020 Lezione di riferimento: https://wp.me/p4kwmk-4D3 Versione 01 Sequenza di accensione e spegnimento alternato da destra e sinistra e viceversa di 8 LED con tempo di accensione di 100 millisecondi. Questo codice è di dominio pubblico */ // creazione di un array di 8 pin a cui vanno collegati i LED // per ulteriori informazioni sull'uso degli array si consulti il seguente link: // http://wp.me/p4kwmk-26e byte ledPin[] = {3, 4, 5, 6, 7, 8, 9, 10}; // per approfondimenti sull'uso dei tipi di dati // si consultino i link: // https://wp.me/p4kwmk-4As // https://wp.me/p4kwmk-1zF // intervallo di accensione/spegnimento byte ritardoLed = 100; // indicatore di direzione di accensione byte direzione = 1; // indice dell'array per l'accensione del LED byte ledCorrente = 0; // variabile in cui memorizzare il tempo di accensione di Arduino // per ulteriori informazioni sui tipi unsigned long si consulti il seguente link: // http://wp.me/p4kwmk-1zF unsigned long tempoTrascorso; void setup() { // impostiamo tutti i pin ad output for (byte x=0; x<8; x++) { pinMode(ledPin[x], OUTPUT); } // Memorizzazione del tempo trascorso // dal momento in cui avviamo Arduino // Per ulteriori informazioni sull'uso di millis() si consulti il seguente link: // http://wp.me/p4kwmk-1QG tempoTrascorso = millis(); } void loop() { // Se sono passati "ritardoLed" millisecondi dall'ultimo cambiamento if ((millis() - tempoTrascorso) > ritardoLed) { cambiaStatoLed(); tempoTrascorso = millis(); } } // la funzione cambiaStatoLed() permette di controllare // la sequenza di accensione dei LED void cambiaStatoLed() { // spegne tutti i LED for (byte x=0; x<8; x++) { digitalWrite(ledPin[x], LOW); } // accende il LED corrente digitalWrite(ledPin[ledCorrente], HIGH); // incrementa la variabile direzione ledCorrente += direzione; // cambia la direzione se si arriva alla fine if (ledCorrente == 7) { direzione = -1; } if (ledCorrente == 0) { direzione = 1; } }
Sketch 02
Sequenza di accensione e spegnimento da destra e sinistra e viceversa di 8 LED. Con un trimmer è possibile variare il tempo di accensione nell’intervallo da 50 millisecondi a 1000 millisecondi (1 secondo).
/* Prof. Michele Maffucci 30.12.2020 Lezione di riferimento: https://wp.me/p4kwmk-4D3 Versione 02 Sequenza di accensione e spegnimento alternato da destra e sinistra e viceversa di 8 LED controllato da un trimmer che permetterà di variare il tempo di accensione da 50 millisecondi a 1000 millisecondi (1 secondo). Questo codice è di dominio pubblico */ // creazione di un array di 8 pin a cui vanno collegati i LED // per ulteriori informazioni sull'uso degli array si consulti il seguente link: // http://wp.me/p4kwmk-26e byte ledPin[] = {3, 4, 5, 6, 7, 8, 9, 10}; // per approfondimenti sull'uso dei tipi di dati // si consultino i link: // https://wp.me/p4kwmk-4As // https://wp.me/p4kwmk-1zF // intervallo di accensione/spegnimento int ritardoLed; // variabile in cui memorizzare il valore restituito dall'analogRead int val = 0; // indicatore di direzione di accensione byte direzione = 1; // indice dell'array per l'accensione del LED byte ledCorrente = 0; // variabile in cui memorizzare il tempo di accensione di Arduino // per ulteriori informazioni sui tipi unsigned long si consulti il seguente link: // http://wp.me/p4kwmk-1zF unsigned long tempoTrascorso; void setup() { Serial.begin(9600); // impostiamo tutti i pin ad output for (byte x=0; x<8; x++) { pinMode(ledPin[x], OUTPUT); } // Memorizzazione del tempo trascorso // dal momento in cui avviamo Arduino // Per ulteriori informazioni sull'uso di millis() si consulti il seguente link: // http://wp.me/p4kwmk-1QG tempoTrascorso = millis(); } void loop() { // valore analogico letto su A0 inserito con il trimmer val = analogRead(A0); // Togliere il commento per valutare // valore massimo/minimo del valore restituito // dall'analogRead in questo modo si potranno // inserire nella map i valori massimi e minimi // dell'intervallo di partenza // Serial.println(val); // delay(1000); // ValMax = 285, ValMin = 719 // riconvertiti nell'intervallo 50, 1000 ritardoLed = map(val, 285, 719, 50, 1000); // Se sono passati "ritardoLed" millisecondi dall'ultimo cambiamento if ((millis() - tempoTrascorso) > ritardoLed) { cambiaStatoLed(); tempoTrascorso = millis(); } } // la funzione cambiaStatoLed() permette di controllare // la sequenza di accensione dei LED void cambiaStatoLed() { // spegne tutti i LED for (byte x=0; x<8; x++) { digitalWrite(ledPin[x], LOW); } // accende il LED corrente digitalWrite(ledPin[ledCorrente], HIGH); // incrementa la variabile direzione ledCorrente += direzione; // cambia la direzione se si arriva alla fine if (ledCorrente == 7) { direzione = -1; } if (ledCorrente == 0) { direzione = 1; } }
Sketch 03
Sequenza di accensione e spegnimento alternato da destra e sinistra e viceversa di 8 LED. L’accensione di ogni LED è fissato in partenza a 100 millisecondi. Con un messaggio sulle Serial Monitor viene richiesto di inserire un nuovo tempo di accensione e spegnimento di ogni LED (delay), tempo che può essere scelto a piacimento.
Lo schema di collegamento è analogo a quello utilizzato per lo sketch 01.
/* Prof. Michele Maffucci 30.12.2020 Lezione di riferimento: https://wp.me/p4kwmk-4D3 Versione 03 Sequenza di accensione e spegnimento alternato da destra e sinistra e viceversa di 8 LED. Partenza sequenza con 100 millisecondi e messaggio sulla Serial Monitor per modificare il tempo di accensione e spegnimento del singolo LED (delay) Questo codice è di dominio pubblico */ // creazione di un array di 8 pin a cui vanno collegati i LED // per ulteriori informazioni sull'uso degli array si consulti il seguente link: // http://wp.me/p4kwmk-26e byte ledPin[] = {3, 4, 5, 6, 7, 8, 9, 10}; // per approfondimenti sull'uso dei tipi di dati // si consultino i link: // https://wp.me/p4kwmk-4As // https://wp.me/p4kwmk-1zF // intervallo di accensione/spegnimento int ritardoLed = 100; // indicatore di direzione di accensione byte direzione = 1; // indice dell'array per l'accensione del LED byte ledCorrente = 0; // variabile in cui memorizzare il tempo di accensione di Arduino // per ulteriori informazioni sui tipi unsigned long si consulti il seguente link: // http://wp.me/p4kwmk-1zF unsigned long tempoTrascorso; // per stampare una sola volta il messaggio sulla Serial Monitor bool abilitaMessaggio = 0; void setup() { // inizializzazione della serial monitor Serial.begin(9600); // impostiamo tutti i pin ad output for (byte x=0; x<8; x++) { pinMode(ledPin[x], OUTPUT); } // Memorizzazione del tempo trascorso // dal momento in cui avviamo Arduino // Per ulteriori informazioni sull'uso di millis() si consulti il seguente link: // http://wp.me/p4kwmk-1QG tempoTrascorso = millis(); } void loop() { // consente di visualizzare sulla Serial Monitor // una sola stampa delle stringa if (abilitaMessaggio == 0) { // ritardo che evita la doppia stampa del messaggio delay(200); Serial.print("Inserisci il ritardo in millisecondi: "); abilitaMessaggio = 1; } // Controlla se è disponibile almeno un carattere sulla seriale // La Serial.available() restituisce // 1 se presente un cattere, // 0 se non è presente un carattere // per maggior informazioni sull'uso di parseInt() consultare il link: // https://wp.me/p4kwmk-4Ah if (Serial.available()) { // in r viene memorizzato il valore inserito // attraverso la Serial Monitor int r = Serial.parseInt(); if (r != 0) { ritardoLed = r; Serial.println(ritardoLed); // abilita alla stampa di una nuova stringa: // "Inserisci il ritardo in millisecondi: " abilitaMessaggio = 0; } } // funzione che fa lampeggiare il LED su Arduino lampeggio(); } void lampeggio() { // Se sono passati "ritardoLed" millisecondi dall'ultimo cambiamento if ((millis() - tempoTrascorso) > ritardoLed) { cambiaStatoLed(); tempoTrascorso = millis(); } } // la funzione cambiaStatoLed() permette di controllare // la sequenza di accensione dei LED void cambiaStatoLed() { // spegne tutti i LED for (byte x = 0; x < 8; x++) { digitalWrite(ledPin[x], LOW); } // accende il LED corrente digitalWrite(ledPin[ledCorrente], HIGH); // incrementa la variabile direzione ledCorrente += direzione; // cambia la direzione se si arriva alla fine if (ledCorrente == 7) { direzione = -1; } if (ledCorrente == 0) { direzione = 1; } }