Archivi tag: led

Raspberry Pi Pico – controllare lo stato di un pin digitale

Propongo in questa breve lezione due esempi di base sull’uso del Raspberry Pi Pico: identificare lo stato di un pulsante e realizzazione di un interruttore mediante un pulsante.

Per questo esempio utilizzeremo il pin 14 a cui connetteremo un pin del pulsante, così come rappresentato nell’immagine che segue. Come sapete molti dei pulsanti disponibili nei kit elettronici sono costituiti da 4 pin, connessi frontalmente a due a due.
Proseguiamo connettendo il secondo pin del pulsante al positivo sulla breadboard (3,3V). Ricordiamoci inoltre la connessione del 3,3V del PiPico al positivo della breadboard.

E’ molto importante ricordare che una simile connessione del pulsante con il PiPico potrebbe causare problemi di cortocircuito alla pressione del pulsante, perché non presente una resistore di PULL-UP o di PULL-DOWN fisico. Per evitare di utilizzare un resistore, attiviamo la resistenza di PULL-DOWN sul pin 14, ATTENZIONE ricordate di fare questa operazione altrimenti rischiate di distruggere irrimediabilmente  il vostro microcontrollore.

Aprite l’editor Thonny e digitate il seguente programma:

# Prof. Maffucci Michele
# Controllo dello stato sul pin 14 (una sola volta)
# 18.09.2021

# libreria che permette di utilizzare MicroPython con il RaspyMicro
import machine

# creazione dell'oggetto pulsante che include il pin 14 impostato come input
# su cui viene attivata il resistore di PULL-DOWN
pulsante = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_DOWN)

# la lettura del pulante viene fatta usando l'API machine
# usando la funzione value

print(button.value())

Salvate il programma sulla vostra scheda, assegnate ad esempio il nome pulsante1.py
Se mandate in esecuzione il programma lo stato del pin verrà mostrato immediatamente sulla Shell una sola volta.

Se non premete il pulsante verrà mostrato sulla Shell il valore logico 0 in quanto abbiamo utilizzato una resistenza di PULL-DOWN, nel momento in cui, all’avvio premete il pulsante lo stato logico visualizzato sulla Shell sarà 1.

Per leggere lo stato del pulsante in modo continuo bisognerà aggiungere un loop all’interno del programma che segue che chiameremo pulsante2.py

# Prof. Maffucci Michele
# Controllo dello stato sul pin 14 (in modo continuo)
# 18.09.2021

# libreria che permette di utilizzare MicroPython con il RaspyMicro
import machine

# per la gestione del tempo
import utime

# creazione dell'oggetto pulsante che include il pin 14 impostato come input
# su cui viene attivata il resistore di PULL-DOWN
pulsante = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_DOWN)

# la lettura del pulante viene fatta usando l'API machine
# usando la funzione value

# while True definisce un loop infinito al cui interno
# troviamo il controllo dello stato del pulsante
while True:
    # se la condizione è vera viene stampato
    # il messaggio mediante la print
    # e fermato il programma per 1 secondi
    if pulsante.value() == 1:
        print("Hai premuto il pulsante")
        utime.sleep(1)

Premete sul pulsante di Run nell’IDE, vedrete che fino a quando non premete il pulsante non accade nulla. Non appena il pulsante viene premuto viene stampata sulla Shell la strina “Hai premuto il pulsante”.

Attenzione che senza la brevissima pausa di 1 secondo verrebbe stampato continuamente il messaggio “Hai premuto il pulsante”.

Vedrete quindi la stampa del messaggio ogni secondo. Se mantenete premuto il pulsante per un tempo superiore a 1 secondi verrà stampato nuovamente il messaggio e ciò si ripeterà ogni secondo fino a quando non rilasciamo il pulsante.

Vediamo ora un programma che, oltre ad inviare un messaggio sulla Shell, accende un LED esterno connesso al pin 15 ogni volta che premiamo il pulsante, chiamiamo il programma pulsante3.py.

# Prof. Maffucci Michele
# Controllo dello stato sul pin 14 (in modo continuo)
# eaccensione di un led alla pressione del pulsante
# 18.09.2021

# libreria che permette di utilizzare MicroPython con il RaspyMicro
import machine

# per la gestione del tempo
import utime

# creazione dell'oggetto pulsante che include il pin 14 impostato come input
# su cui viene attivata il resistore di PULL-DOWN
pulsante = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_DOWN)

#pin 15 dichiarato come OUTPUT
ledEsterno = machine.Pin(15, machine.Pin.OUT)

# while True definisce un loop infinito al cui interno
# troviamo il controllo dello stato del pulsante
while True:
    # se la condizione è vera viene stampato
    # il messaggio mediante la print
    # e fermato il programma per 1 secondi
    if pulsante.value() == 1:
        ledEsterno.value(1)    # imposta il livello logico 1 sul pin 15
        print("Hai premuto il pulsante")
        utime.sleep(0.5)       # imposta una pausa di mezzo secondo
        ledEsterno.value(0)    # imposta il livello logico 0 sul pin 15

Vediamo ora come realizzare un programma che realizza la funzione di un interruttore, cioè il mantenimento dello stato al rilascio del pulsante. Chiamiamo il programma interruttore1.py. Il circuito è il medesimo dell’esempio al passo precedente.

# Prof. Maffucci Michele
# realizzazione di un interruttore
# mediante pulsante connesso al Pin 14 con antirimbalzo software
# con accensione di un LED connesso al pin 15
# 18.09.2021

# libreria che permette di utilizzare MicroPython con il RaspyMicro
import machine

# per la gestione del tempo
import utime

# creazione dell'oggetto pulsante che include il pin 14 impostato come input
# su cui viene attivata il resistore di PULL-DOWN
pulsante = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_DOWN)

#pin 15 dichiarato come OUTPUT
ledEsterno = machine.Pin(15, machine.Pin.OUT)

# val usato per conservare lo stato del pulsante
val = 0

# vecchio_val per conservare lo stato del pulsante al passo precedente
vecchio_val = 0

# ricorda lo stato in cui si trova il LED,
# stato = 0 led spento, stato = 1 led acceso
stato = 0

# while True definisce un loop infinito al cui interno
# troviamo il controllo dello stato del pulsante
while True:
    val = pulsante.value()                   # legge il valore del pulsante e lo conserva
    if (val == 1) and (vecchio_val == 0):    # controlla se è accaduto qualcosa
        stato = 1 - stato
        utime.sleep(0.15)	             # attesa di 15 millisecondi
    vecchio_val = val;
    if (stato == 1):
        ledEsterno.value(1)    # imposta il livello logico 1 sul pin 15
    else:
        ledEsterno.value(0)    # imposta il livello logico 0 sul pin 15

Modifichiamo ora il programma precedente inviando sulla Shell il messaggio che indica lo stato del LED, chiamiamo il programma interruttire2.py. Il circuito è il medesimo dell’esempio al passo precedente.

# Prof. Maffucci Michele
# realizzazione di un interruttore
# mediante pulsante connesso al Pin 14 con antirimbalzo software
# con accensione di un LED connesso al pin 15
# e stampa dello stato del LED sulla Shell
# 18.09.2021

# libreria che permette di utilizzare MicroPython con il RaspyMicro
import machine

# per la gestione del tempo
import utime

# creazione dell'oggetto pulsante che include il pin 14 impostato come input
# su cui viene attivata il resistore di PULL-DOWN
pulsante = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_DOWN)

#pin 15 dichiarato come OUTPUT
ledEsterno = machine.Pin(15, machine.Pin.OUT)

# val usato per conservare lo stato del pulsante
val = 0

# vecchio_val per conservare lo stato del pulsante al passo precedente
vecchio_val = 0

# ricorda lo stato in cui si trova il LED,
# stato = 0 led spento, stato = 1 led acceso
stato = 0

# stampare una sola volta il messaggio 'LED acceso' o 'LED spento' sulla Shell
abilitaMessaggio = 0

# while True definisce un loop infinito al cui interno
# troviamo il controllo dello stato del pulsante
while True:
    val = pulsante.value()                    # legge il valore del pulsante e lo conserva
    if (val == 1) and (vecchio_val == 0):     # controlla se è accaduto qualcosa
        stato = 1 - stato
        utime.sleep(0.15)		      # attesa di 15 millisecondi
    vecchio_val = val;
    if (stato == 1) and (abilitaMessaggio == 0):
        ledEsterno.value(1)                   # imposta il livello logico 1 sul pin 15
        abilitaMessaggio = 1
        print("LED acceso")                   # stampa il messaggio
        utime.sleep(1)
    elif (stato == 0) and (abilitaMessaggio == 1):
        ledEsterno.value(0)                   # imposta il livello logico 0 sul pin 15
        abilitaMessaggio = 0
        print("LED spento")                   # stampa il messaggio
        utime.sleep(1)

Buon Coding a tutti 🙂

Arduino – realizzare un sensore di seduta a pressione con un tubo di gomma

Questa mattina, durante la realizzazione e l’analisi dei problemi per il progetto di PCTO: “misura di sedentarietà delle persone sedute alla scrivania” che stanno realizzando i miei studenti di 3′ Elettronica, è nata l’esigenza di associare un doppio controllo per la valutazione della presenza della persona seduta alla scrivania, un controllo effettuato con PIR HC-SR501 ed un sensore di forza resistivo (FSR) inserito all’interno del cuscino della seduta.

Per evitare l’acquisto di un sensore di forza resistivo e non pesare sulle finanze dei ragazzi le modalità sono tre:

  • richiesta alla scuola
  • compra il Prof.
  • farlo costruire ai ragazzi

l’acquisto da parte della scuola o mia non è un problema, ma la terza soluzione è quella che in questo momento prediligo, perché può essere realizzata in 5 minuti, credo che possa gratificare di più lo studente Maker in erba 🙂 , inoltre ritengo importante che gli allievi assumano la capacità di costruire il sensore perché ne dovranno ottimizzare l’uso, scontrandosi inevitabilmente con una serie di variabili fisiche che dovranno gestire.

Ma come si costruisce il sensore?

E’ indispensabile piccolo tubo cilindrico non trasparente, preferibilmente nero che possa essere compresso e al termine della compressioni ritorni abbastanza velocemente nella sua posizione di riposo. Possiamo ricavare il tubo sguainando un cavo elettrico o cavo di rete, oppure come ho fatto in questo tutorial, prendendo una guaina termorestingente.

Inserire un diodo LED ad un’estremità del cilindro e dalla parte opposta inserire un LDR.
Collegare il sistema nella solita modalità, inserendo in serie al LED un resistore da 220 Ohm e creando un partitore di tensione tra l’LDR e un resistore da 10KOhm, così come indicato nel circuito indicato di seguito.

Come test di funzionamento utilizzare il semplice sketch che trovate di seguito, nei commenti la spiegazione di tutte le parti del codice.

Aprite la Serial Monitor e premete e rilasciate il tubo

/*
 * Prof. Michele Maffucci
 * Data 01.03.2021
 *
 * Oggetto: sensore di seduta a pressione
 *
*/

// variabile in cui verrà memorizzato il valore presente sul pin A0
const int misura = A0;

// valore restituito dall'analogRead
int val = 0;

// pin a cui è connesso il LED del sensore di seduta
int pinLed = 2;

// LED che segnala la seduta della persona
int pinLedAlert = 13;

void setup() {
  // Inizializzazione della Serial Monitor
  Serial.begin(9600);

  // ledPin è il pin a cui è connesso il LED del sensore di seduta
  pinMode(pinLed, OUTPUT);

  // pinLedAlert è il pin a cui è connesso il LED che segnala la seduta della persona
  pinMode(pinLedAlert, OUTPUT);

  // Attivazione del LED del sensore di seduta
  digitalWrite(pinLed, HIGH);

  // Messaggio di avvio
  Serial.println("Sistema di rilevazione seduta");
  Serial.println("-----------------------------");
  Serial.println("");
  delay(1000);
}

void loop() {
  // analogRead leggerà il valore su A0 restituendo un valore tra 0 e 1023
  val = analogRead(misura);

  // il valore di controllo nell'if deve essere sperimentato in funzione
  // delle necessità costruttive (ad es. la lunghezza del tubo)

  // se vero la persona è seduta
  if (val >= 100) {
    digitalWrite(pinLedAlert, HIGH);                      // accensione del LED di avviso
    Serial.println("Persona NON seduta alla scrivania");  // segnalazione di assenza persona
    Serial.print("Valore letto dal sensore = ");          // Stringa di stampa
    Serial.println(val);                                  // Valore restituito dall'AnalogRead
    Serial.println("");                                   // Stampa linea vuota di separazione
    delay(1000);                                          // Intervallo di 1 secondo tra ogni stampa
  }
  else
  {
    digitalWrite(pinLedAlert, LOW);                       // spegnimento del LED di avviso
    Serial.println("Persona seduta alla scrivania");      // segnalazione di presenza persona
    Serial.print("Valore letto dal sensore = ");          // Stringa di stampa
    Serial.println(val);                                  // Valore restituito dall'AnalogRead
    Serial.println("");                                   // Stampa linea vuota di separazione
    delay(1000);                                          // Intervallo di 1 secondo tra ogni stampa
  }
}

Il risultato sulla Serial Monitor è il seguente

Il valore di soglia scelto deve essere ricavato sperimentalmente in funzione della lunghezza e della trasparenza del tubo.

Buon Making a tutti 🙂

Arduino – Uso di LED RGB – approfondimento

Scrivo questa lezione come approfondimento della guida realizzata tempo fa: Arduino – lezione 09: uso di LED RGB in cui mostravo come funzionano e come si gestiscono i LED RGB con Arduino. Negli esercizi proposti utilizzavo un LED ad ANODO comune. In questa nuova lezione utilizzerò un diodo a CATODO comune e mostrerò tre esempi, nel primo ripropongo in una modalità diversa l’esercizio della prima lezione in cui faccio alcuni approfondimenti sull’uso della direttiva #define, mentre nel secondo e terzo esercizio viene mostrato come impostare il colore emesso dal LED RGB mediante input da tastiera su Serial Monitor richiamando con questi esempi l’uso del qualificatore const per una variabile e l’utilizzo della funzione parseInt(). Come sempre nei commenti, all’interno del codice, trovate la spiegazione del funzionamento di ogni parte dello sketch.

Esempio 01

Variazione colore continuo di un LED RGB secondo lo schema:

ROSSO > VERDE, VERDE > BLU, BLU > ROSSO

Scema di collegamento

/*  Prof. Maffucci Michele
    06.01.2021

    Esempio 01
    Variazione colore continuo
    di un LED RGB secondo lo schema:

    ROSSO > VERDE, VERDE > BLU, BLU > ROSSO

*/

/* Utilizzo della direttiva #define per definire una costante
   La direttiva viene utilizzata per definire una MACRO ovvero
   un simbolo.

   La sintassi per la definizione di una macro è:
   #define nome-MACRO  valore_MACRO

   Per convenzione il nome della macro viene scritta in maiuscolo.

   Il preprocessore legge la definizione di ogni MACRO e ogni volta che
   ne incontra il nome all'interno del programma (file sorgente) sostituisce
   al simbolo il valore corrispondente, senza che venga effettuata la verifica
   della correttezza sintattica dell'espressione risultante.
*/

#define VERDE 9
#define BLU 10
#define ROSSO 11

// tempo di dissolvenza tra i colori
#define tempoRitardo 10

void setup()
{
  // impostazione ad OUTPUT dei pin
  pinMode(ROSSO, OUTPUT);
  pinMode(VERDE, OUTPUT);
  pinMode(BLU, OUTPUT);

  // all'avvio viene emesso il colorore ROSSO
  digitalWrite(BLU, LOW);
  digitalWrite(VERDE, LOW);
  digitalWrite(ROSSO, HIGH);
}

// definizione di variabili
int valoreRosso;
int valoreVerde;
int valoreBlu;

void loop()
{
  // Impostazioni variabili per avere partire con LED:
  // ROSSO accesso, VERDE spento, BLU spento.
  valoreRosso = 255;
  valoreVerde = 0;
  valoreBlu = 0;

  // partendo dal ROSSO si sfuma al VERDE pieno quando i = 255
  for (int i = 0; i < 255; i += 1)
  {
    valoreRosso -= 1;
    valoreVerde += 1;

    // L'intensità del ROSSO viene diminuita ad ogni ciclo, mentre
    // l'intensità del VERDE viene aumentata ad ogni ciclo
    analogWrite(ROSSO, valoreRosso);
    analogWrite(VERDE, valoreVerde);
    delay(tempoRitardo);
  }

  // Impostazioni variabili per avere partire con LED:
  // ROSSO spento, VERDE acceso, BLU spento.
  valoreRosso = 0;
  valoreVerde = 255;
  valoreBlu = 0;

  // partendo dal VERDE si sfuma al BLU pieno quando i = 255
  for (int i = 0; i < 255; i += 1)
  {
    valoreVerde -= 1;
    valoreBlu += 1;

    // L'intensità del VERDE viene diminuita ad ogni ciclo, mentre
    // l'intensità del BLU viene aumentata ad ogni ciclo
    analogWrite(VERDE, valoreVerde);
    analogWrite(BLU, valoreBlu);
    delay(tempoRitardo);
  }

  // Impostazioni variabili per avere partire con LED:
  // ROSSO spento, VERDE spento, BLU acceso.
  valoreRosso = 0;
  valoreVerde = 0;
  valoreBlu = 255;

  // partendo dal BLU si sfuma al ROSSO pieno quando i = 255
  for (int i = 0; i < 255; i += 1)
  {
    valoreBlu -= 1;
    valoreRosso += 1;

    // L'intensità del BLU viene diminuita ad ogni ciclo, mentre
    // l'intensità del ROSSO viene aumentata ad ogni ciclo
    analogWrite(BLU, valoreBlu);
    analogWrite(ROSSO, valoreRosso);
    delay(tempoRitardo);
  }
}

Esempio 02

Inserimento da Serial Monitor dei valori di intensità del colore. La stringa di richiesta inserimento dei valori RGB viene ripetuta una sola volta e ad ogni nuovo inserimento non viene stampato sulla serial monitor il valore inserito.

Lo schema di collegamento è il medesimo dell’esempio 01.

/*  Prof. Maffucci Michele
    06.01.2021

    Esempio 02
    Inserimento da Serial Monitor dei valori
    di intensità del colore.
    La stringa di richiesta inserimento viene ripetuta una sola volta.
    Ad ogni nuovo inserimento non viene stampato sulla serial monitor
    il valore inserito.

    L'inserimento dei tre valori potrà essere effettuato
    in una delle due modalità:
    1. separando i tre numeri con spazio
    2. separando i tre numeri con la virgola
*/

/*
   Una variabile const indica al compilatore che il valore della
   variabile non può essere modificato durante l'esecuzione del programma.
   Una variabile const viene inizializzata nel momento della dichiarazione,
   se ciò viene fatto in un momento successivo il compilatore rileverà un
   errore che segnalerà anche errore in ogni operazione che comportano la
   modifica del valore dell avariabile definita come const
*/

const byte pinRosso = 11;
const byte pinBlu = 10;
const byte pinVerde = 9;

void setup() {
  // Inizializzazione della comunicazione seriale
  Serial.begin(9600);

  // Impostazione dei pin come OUTPUT
  pinMode(pinRosso, OUTPUT);
  pinMode(pinBlu, OUTPUT);
  pinMode(pinVerde, OUTPUT);

  // Messaggio sulla serial monitor
  Serial.println("Inserisci i valori R G B (es. 125, 50, 255)");
  Serial.println("-------------------------------------------");
  delay(1000);
}

void loop() {

  // 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()) {
    // memorizzazione dei colori nelle variabili
    int rosso = Serial.parseInt();
    int verde = Serial.parseInt();
    int blu = Serial.parseInt();

    // impostazione del PWM
    analogWrite(pinRosso, rosso);
    analogWrite(pinVerde, verde);
    analogWrite(pinBlu, blu);
  }
}

Esempio 3

Inserimento da Serial Monitor dei valori di intensità del colore.
Il valore inserito verrà stampato sulla Serial Monitor e ad ogni invio verrà richiesto di inserire un nuovo valore.

Lo schema di collegamento è il medesimo dell’esempio 01.

/*  Prof. Maffucci Michele
    06.01.2021

    Esempio 03
    Inserimento da Serial Monitor dei valori
    di intensità del colore.
    Il valore inserito verrà stampato sulla Serial Monitor e ad ogni
    invio verrà richiesto di inserire un nuovo valore.

    L'inserimento dei tre valori potrà essere effettuato
    in una delle due modalità:
    1. separando i tre numeri con spazio
    2. separando i tre numeri con la virgola
*/

/*
   Una variabile const indica al compilatore che il valore della
   variabile non può essere modificato durante l'esecuzione del programma.
   Una variabile const viene inizializzata nel momento della dichiarazione,
   se ciò viene fatto in un momento successivo il compilatore rileverà un
   errore che segnalerà anche errore in ogni operazione che comportano la
   modifica del valore dell avariabile definita come const
*/

const byte pinRosso = 11;
const byte pinBlu = 10;
const byte pinVerde = 9;

// per stampare una sola volta il messaggio sulla Serial Monitor
bool abilitaMessaggio = 0;

void setup() {
  // Inizializzazione della comunicazione seriale
  Serial.begin(9600);

  // Impostazione dei pin come OUTPUT
  pinMode(pinRosso, OUTPUT);
  pinMode(pinBlu, OUTPUT);
  pinMode(pinVerde, OUTPUT);
}

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 i valori R G B (es. 125, 50, 255): ");
    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()) {
    // memorizzazione dei colori nelle variabili
    int rosso = Serial.parseInt();
    int verde = Serial.parseInt();
    int blu = Serial.parseInt();
    Serial.print(rosso);
    Serial.print(", ");
    Serial.print(verde);
    Serial.print(", ");
    Serial.println(blu);
    Serial.println("-------------------------------------------");

    // impostazione del PWM
    analogWrite(pinRosso, rosso);
    analogWrite(pinVerde, verde);
    analogWrite(pinBlu, blu);

    // abilita alla stampa di una nuova stringa:
    // "Inserisci il ritardo in millisecondi: "
    abilitaMessaggio = 0;
  }
}

Esercizi per i miei studenti

Esercizio 1

Utilizzare tre pulsanti che funzionino come interruttori che permettono di accendere e spegnere un solo LED alla volta:

  • pulsante 1: LED ROSSO
  • pulsante 2: LED VERDE
  • pulsante 3: LED BLU

Ogni cambiamento di stato deve essere segnalato sulla Serial Monitor.

Esercizio 2

Utilizzare due pulsanti in gredo di realizzare la seguente automazione:

  • pulsante 1: attivare/disattivare la modalità di variazione continua del colore, così come esposta nell’esempio 01
  • pulsante 2: attivare/disattivare la generazione casuale di un colore

Ogni cambiamento di stato deve essere segnalato sulla Serial Monitor.

Esercizio 3

Utilizzando la Serial Monitor come unico strumento per inviare comandi ad Arduino, realizzare un menù di selezione che permette di impostare le funzionalità dell’esercizio 01 e dell’esercizio 03.

Papà mi costruisci una lampada ecosostenibile?

Quando fare il Maker ti mette nei guai…

Figlia: Papà quando hai un secondo di tempo mi costruisci una lampada per la scrivania?
Però la devi fare:

  • bella
  • con oggetti di recupero, che sia ecosostenibile e quindi meglio se utilizzi materiali riciclati
  • deve essere a risparmio energetico

Io: senti signorina altre richieste?

Figlia: No no va bene così… anzi dimenticavo se la fai di legno e di colore blu così si abbina al colore della mia scrivania… grazie sei il papà più bravo dell’universo conosciuto 😊

Dopo una frase del genere come dire di no 😊

Lista materiali:

  • Avanzi stecche di legno 18×18 mm
  • Viti e dadi recuperati da un tenditore per cavi utilizzato in passato per i cavi stendibiancheria
  • Stampa 3d di un triangolo da usare come base per lampada
  • Cavo elettrico recuperato dalla precedente lampada rotta
  • Spezzone di striscia led
  • Alimentatore 12Vcc utilizzato in passato per alimentare un vecchio hard disk esterno
  • Avanzo di canalina elettrica da usare come paraluce in cui inserire la striscia led

Design essenziale, da rifinire, ma per essere stata prodotta in 1 ora di tempo credo possa andare bene.

Misure della lampada iniziando dalla base di appoggio:

  • 40 cm
  • 15 cm
  • 20 cm

Nel caso desiderate replicare il progetto le stecche di legno potete acquistarle in qualsiasi bricocenter, sono vendute a pezzi di 1m costano pochissimo.

Condivido inoltre il file per la stampa 3D della base della lampada.

Buon making a tutti 🙂

Evitare il loop di messaggi inviati sulla Serial Monitor

Con questo post rispondo ad alcuni miei studenti su quesiti posti sull’uso di Arduino durante il ripasso condotto in questi giorni sulla modalità di stampa di messaggi sulla Serial Monitor.

L’esercizio assegnato consisteva nella tipica accensione e spegnimento di un LED mediante un pulsante con antirimbalzo software, nella seconda parte bisognava aggiungere un secondo pulsante che permetteva di accendere e spegnere un secondo LED e nella terza fase segnalare l’accensione e lo spegnimento sulla Serial Monitor mediante i messaggi:

“LED Rosso ON”
“LED Rosso OFF”
“LED Verde ON”
“LED Verde OFF”

Qundi per ciascun LED, alla prima pressione del pulsante accensione del LED e segnalazione ON sulla Serial, alla seconda pressione del pulsante segnalazione OFF sulla Serial e spegnimento del LED, ovviamente senza alcun limite sul numero di pressioni sui pulsanti.

Gli studenti sono riusciti a realizzare lo sketch ma con il solito problema di ripetizione in loop del testo di segnalazione sulla Serial.

Il problema può essere superato utilizzando un codice simile al seguente:

int stampaMessaggio = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  if(!stampaMessaggio)
  {
     Serial.println(“Qualsiasi testo da stampare una sola volta…“);
     stampaMessaggio = 1;
  }
}

Nel primo ciclo di loop la condizione dell’if risulterà vera e ciò permetterà l’esecuzione della stampa del testo,  successivamente impostata la variabile “stampaMessaggio” ad 1 non sarà più possibile stampare il testo al ciclo di loop successivo in quanto “!stampaMessaggio” risulterà uguale a 0.

Di seguito le due soluzioni, la prima con testo in loop sulla Serial, mentre la seconda con testo NON in loop.

Al fondo del post un esercizio aggiuntivo per i miei studenti.

All’interno del codice la spiegazione del funzionamento.

Soluzione con testo di output in loop

/*
   Prof. Michele Maffucci
   Accensione e spegnimento
   23.09.19

   Accensione e spegnimento di LED mediante pulsanti
   con antirimbalzo e messaggio ripetuto dello stato del LED
   sulla Serial Monitor

   Pulsante Rosso: accensione e spegnimento LED Rosso
   (prima pressione accende, seconda pressione spegne)

   Pulsante Verde: accensione e spegnimento LED Verde
   (prima pressione accende, seconda pressione spegne)

*/

// ledRosso variabile di tipo intero a cui viene assegnato
// il valore intero 5 che sarà associato al pin digitale 5

int ledRosso = 5;

// ledVerde variabile di tipo intero a cui viene assegnato
// il valore intero 4 che sarà associato al pin digitale 4

int ledVerde = 4;


// pulsanteRosso variabile di tipo intero a cui viene assegnato
// il valore intero 7 che sarà associato al pin digitale 7
// a cui sarà collegato il pulsante che comanda il LED Rosso

int pulsanteRosso = 7;

// pulsanteVerde variabile di tipo intero a cui viene assegnato
// il valore intero 6 che sarà associato al pin digitale 6
// a cui sarà collegato il pulsante che comanda il LED Verde

int pulsanteVerde = 6;

// inizializzazione della variabili in cui verrà memorizzato il valore della
// digitalRead: 0 non premuto, 1 premuto

int valRosso = 0;
int valVerde = 0;

// inizializzazione della variabili in cui verrà memorizzato lo stato del pulsante
// All'avvio dello sketch i pulsanti non sono premuti

int statoRosso = 0;
int statoVerde = 0;

// inizializzazione della variabili in cui verrà memorizzato lo stato precedente del pulsante
// All'avvio dello sketch i pulsanti non sono premuti

int valRossoOld = 0;
int valVerdeOld = 0;

void setup() {
  pinMode(ledRosso, OUTPUT);           // imposta il pin digitale come output
  pinMode(ledVerde, OUTPUT);           // imposta il pin digitale come output
  pinMode(pulsanteRosso, INPUT);       // imposta il pin digitale come input
  pinMode(pulsanteVerde, INPUT);       // imposta il pin digitale come input

  Serial.begin(9600);                 // imposta la velocità di scrittura della serial monitor
}

void loop() {

  valRosso = digitalRead(pulsanteRosso);  // lettura dell'input (pulsante) e memorizzazione in valRosso
  valVerde = digitalRead(pulsanteVerde);  // lettura dell'input (pulsante) e memorizzazione in valVerde

  // ---------- Controllo pulsante LED Rosso ----------

  if ((valRosso == HIGH) && (valRossoOld == LOW)) {
    statoRosso = 1 - statoRosso;

    // antirimbalzo software - attesa di 15 ms per attendere che l'input si stabilizzi
    delay(15);
  }


  // memorizzazione del valore precedente restituito dalla digitalRead

  valRossoOld = valRosso;

  // ---------- Controllo pulsante LED Verde ----------

  // viene controllato che l'input sia HIGH (pulsante premuto) e cambia lo stato del LED

  if ((valVerde == HIGH) && (valVerdeOld == LOW)) {
    statoVerde = 1 - statoVerde;

    // antirimbalzo software - attesa di 15 ms per attendere che l'input si stabilizzi

    delay(15);

    // memorizzazione del valore precedente restituito dalla digitalRead
  }

  valVerdeOld = valVerde;

  // ---------- Stampa sulla Serial Monitor dello stato del LED Rosso ----------

  // Se il pulsante è stato premuto la condizione dell'if risulta vera ed il LED Rosso si accende

  if (statoRosso == 1) {
    digitalWrite(ledRosso, HIGH);
    Serial.println("LED Rosso ON");
  }

  // nel caso in cui il pulsante non sia premuto o nello stato precedente era stato premuto
  // allora il LED dovrà essere spento ed il messaggio sulla seriale dovrà essere "LED Rosso OFF"

  else {
    digitalWrite(ledRosso, LOW);
    Serial.println("LED Rosso OFF");
  }

  // ---------- Stampa sulla Serial Monitor dello stato del LED Verde ----------

  // Se il pulsante è stato premuto la condizione dell'if risulta vera ed il LED Verde si accende

  if (statoVerde == 1) {
    digitalWrite(ledVerde, HIGH);
    Serial.println("LED Verde ON");
  }

  // nel caso in cui il pulsante non sia premuto o nello stato precedente era stato premuto
  // allora il LED dovrà essere spento ed il messaggio sulla seriale dovrà essere "LED Verde OFF"

  else {
    digitalWrite(ledVerde, LOW);
    Serial.println("LED Verde OFF");
  }
}

Soluzione con testo di output NON in loop

/*
   Prof. Michele Maffucci
   Data: 23.09.19

   Accensione e spegnimento di LED mediante pulsanti
   con antirimbalzo e messaggio NON ripetuto dello stato del LED
   sulla Serial Monitor

   Stampa 1 sola volta il messaggio dello stato del LED sulla Serial Monitor
   (non va in loop la stampa dello stato del LED)

   Pulsante Rosso: accensione e spegnimento LED Rosso
   (prima pressione accende, seconda pressione spegne)

   Pulsante Verde: accensione e spegnimento LED Verde
   (prima pressione accende, seconda pressione spegne)

*/

// ledRosso variabile di tipo intero a cui viene assegnato
// il valore intero 5 che sarà associato al pin digitale 5

int ledRosso = 5;

// ledVerde variabile di tipo intero a cui viene assegnato
// il valore intero 4 che sarà associato al pin digitale 4

int ledVerde = 4;


// pulsanteRosso variabile di tipo intero a cui viene assegnato
// il valore intero 7 che sarà associato al pin digitale 7
// a cui sarà collegato il pulsante che comanda il LED Rosso

int pulsanteRosso = 7;

// pulsanteVerde variabile di tipo intero a cui viene assegnato
// il valore intero 6 che sarà associato al pin digitale 6
// a cui sarà collegato il pulsante che comanda il LED Verde

int pulsanteVerde = 6;

// inizializzazione della variabili in cui verrà memorizzato il valore della
// digitalRead: 0 non premuto, 1 premuto

int valRosso = 0;
int valVerde = 0;

// inizializzazione della variabili in cui verrà memorizzato lo stato del pulsante
// All'avvio dello sketch i pulsanti non sono premuti

int statoRosso = 0;
int statoVerde = 0;

// inizializzazione della variabili in cui verrà memorizzato lo stato precedente del pulsante
// All'avvio dello sketch i pulsanti non sono premuti

int valRossoOld = 0;
int valVerdeOld = 0;

// inizializzazione delle variabili che consentono la stampa dello stato del LED

int stampoRossoON = 0;
int stampoRossoOFF = 0;

int stampoVerdeON = 0;
int stampoVerdeOFF = 0;

void setup() {
  pinMode(ledRosso, OUTPUT);           // imposta il pin digitale come output
  pinMode(ledVerde, OUTPUT);           // imposta il pin digitale come output
  pinMode(pulsanteRosso, INPUT);       // imposta il pin digitale come input
  pinMode(pulsanteVerde, INPUT);       // imposta il pin digitale come input

  Serial.begin(9600);                 // imposta la velocità di scrittura della serial monitor
  Serial.println("Avvio programma");  // stampa la stringa tra le " e va a campo
  Serial.println("---------------");  // stampa la stringa tra le " e va a campo
}

void loop() {

  valRosso = digitalRead(pulsanteRosso);  // lettura dell'input (pulsante) e memorizzazione in valRosso
  valVerde = digitalRead(pulsanteVerde);  // lettura dell'input (pulsante) e memorizzazione in valVerde

// ---------- Controllo pulsante LED Rosso ----------

  // viene controllato che l'input sia HIGH (pulsante premuto) e cambia lo stato del LED

  if ((valRosso == HIGH) && (valRossoOld == LOW)) {
    statoRosso = 1 - statoRosso;

    // antirimbalzo software - attesa di 15 ms per attendere che l'input si stabilizzi
    delay(15);

    // poichè il pulsante è stato premuto la variabile stampoRossoON viene posta a 0
    // per consentire la stampa del messaggio "LED Rosso ON"

    stampoRossoON = 0;
  }

  // memorizzazione del valore precedente restituito dalla digitalRead

  valRossoOld = valRosso;

// ---------- Controllo pulsante LED Verde ----------

  // viene controllato che l'input sia HIGH (pulsante premuto) e cambia lo stato del LED

  if ((valVerde == HIGH) && (valVerdeOld == LOW)) {
    statoVerde = 1 - statoVerde;

    // antirimbalzo software - attesa di 15 ms per attendere che l'input si stabilizzi

    delay(15);

    // poichè il pulsante è stato premuto la variabile stampoVerdeON viene posta a 0
    // per consentire la stampa del messaggio "LED Verde ON"

    stampoVerdeON = 0;
  }

  // memorizzazione del valore precedente restituito dalla digitalRead

  valVerdeOld = valVerde;

// ---------- Stampa sulla Serial Monitor dello stato del LED Rosso ----------

// Se il pulsante è stato premuto la condizione dell'if risulta vera ed il LED Rosso si accende

  if (statoRosso == 1) {
    digitalWrite(ledRosso, HIGH);

    // Se la variabile stampoRossoON è 0 allora !stampoRossoON vale 1
    // ciò consente la stampa del messaggio "LED Rosso ON"

    if (!stampoRossoON) {
      Serial.println("LED Rosso ON");

      // Per evitare una stampa continua del messaggio viene posto ad 1 stampoRossoON
      // in modo che nel ciclo di loop successivo non venga più stampato il messaggio
      // "LED Rosso ON". Viene posto a 0 stampoRossoOFF per consentire la stampa "LED Rosso OFF"
      // nel caso si prema nuovamente il pulsante che controlla il LED Rosso.

      stampoRossoON = 1;
      stampoRossoOFF = 0;
    }
  }

  // nel caso in cui il pulsante non sia premuto o nello stato precedente era stato premuto
  // allora il LED dovrà essere spento ed il messaggio sulla seriale dovrà essere "LED Rosso OFF"

  else {
    digitalWrite(ledRosso, LOW);

    if (!stampoRossoOFF) {
      Serial.println("LED Rosso OFF");

      // Per evitare una stampa continua del messaggio viene posto ad 0 stampoRossoON
      // in modo che nel ciclo di loop successivo non venga più stampato il messaggio
      // "LED Rosso OFF". Viene posto a 1 stampoRossoOFF per consentire la stampa "LED Rosso OFF"
      // nel caso si prema nuovamente il pulsante che controlla il LED Rosso.

      stampoRossoON = 0;
      stampoRossoOFF = 1;
    }
  }

// ---------- Stampa sulla Serial Monitor dello stato del LED Verde ----------

// Se il pulsante è stato premuto la condizione dell'if risulta vera ed il LED Verde si accende

  if (statoVerde == 1) {
    digitalWrite(ledVerde, HIGH);

    // Se la variabile stampoVerdeON è 0 allora !stampoVerdeoON vale 1
    // ciò consente la stampa del messaggio "LED verde ON"

    if (!stampoVerdeON) {
      Serial.println("LED Verde ON");

      // Per evitare una stampa continua del messaggio viene posto ad 1 stampoVerdeON
      // in modo che nel ciclo di loop successivo non venga più stampato il messaggio
      // "LED Verde ON". Viene posto a 0 stampoVerdeOFF per consentire la stampa "LED Verde OFF"
      // nel caso si prema nuovamente il pulsante che controlla il LED Rosso.

      stampoVerdeON = 1;
      stampoVerdeOFF = 0;
    }
  }

  // nel caso in cui il pulsante non sia premuto o nello stato precedente era stato premuto
  // allora il LED dovrà essere spento ed il messaggio sulla seriale dovrà essere "LED Verde OFF"

  else {
    digitalWrite(ledVerde, LOW);

    if (!stampoVerdeOFF) {
      Serial.println("LED Verde OFF");

      // Per evitare una stampa continua del messaggio viene posto ad 0 stampoVerdeON
      // in modo che nel ciclo di loop successivo non venga più stampato il messaggio
      // "LED Verde OFF". Viene posto a 1 stampoVerdeOFF per consentire la stampa "LED Verde OFF"
      // nel caso si prema nuovamente il pulsante che controlla il LED Verde.

      stampoVerdeON = 0;
      stampoVerdeOFF = 1;
    }
  }
}

Esercizio: implementare il controllo della marci e dell’arresto di un motore

Realizzare un circuito in cui con tre pulsanti vengono identificate le tre situazioni:

  1. Marcia
  2. Arresto
  3. Anomalia

Associare ad ogni situazione il colore del LED:

  1. Rosso: marcia
  2. Verde: arresto
  3. Giallo: anomalia

Alla pressione del corrispondente pulsante mostrare sulla Serial Monitor :

  1. Motore in marcia
  2. Motore fermo
  3. Anomalia motore

Buon lavoro 🙂