EduRobot Lift/Elevator

Nuova versione del kit EduRobot Lift, ascensore/montacarichi da utilizzare per le esercitazioni di laboratorio di sistemi elettronici e attività di PCTO negli istituti tecnici industriali e professionali.

Rispetto alla versione precedente alcune migliorie che ne facilitano la costruzione. Il controllo può essere effettuato in diverse modalità: Siemens Step 7 1200, Logo8!, Siemens IoT 2040, Arduino. La struttura è stata disegnata con Adobe Illustrator e tagliata a laser presso il Laboratorio Territoriale del mio istituto, l’ITIS G.B. Pininfarina di Moncalieri. Il materiale è costituito da compensato da 4 mm e due elementi stampati in 3D in PETG. Il montaggio della struttura richiede circa 40/45 min.

Se desideri realizzare il kit, seguire il link su Thingiverse, da cui potrete prelevare il file PDF per il taglio laser e i file STL per la stampa 3D della struttura del motore.

Volutamente per la realizzazione di questo kit sono stati scelti materiali economici in quanto il mio desiderio è quello di assegnarne un kit ad ogni studente.

  • foglio di compensato da 4mm 80×60 mm (costo indicativo: €4)
  • 24 viti M3 da 12 mm
  • 24 dadi M3
  • motorino passo passo 28BYJ-48
  • colla vinilica
  • due elementi stampati in 3D
  • spago

Nel kit viene utilizzato un motore passo passo economico il 28BYJ-48 in modo che possa essere acquistato da tutti gli studenti. Con qualche piccola modifica è possibile utilizzare anche un motorino DC da 6V, i classici “motorini gialli” utilizzati dagli studenti per la costruzione di piccoli robot.

Quattro gli obiettivi di questo progetto:

  1. offrire una guida fotografica per i miei studenti della classe 3′ che dovranno svolgere il PCTO (ex Alternanza Scuola Lavoro) facendo una simulazione di attività aziendale, quest’anno dovranno diventare tecnici di un’azienda che produce ascensori e montacarichi;
  2. mostrare agli studenti che è possibile imparare ad imparare attraverso attività laboratoriali che prevedono la progettazione e la costruzione dei propri strumenti di apprendimento;
  3. il mercato offre molteplici strumenti, kit robotici di ogni tipo che rispondono a molteplici esigenze didattiche, ma alcune volte non rispondono ad esigenze specifiche di un percorso di studio o di un argomento, ecco che la scuola diventa produttrice dei propri ausili didattici specifici;
  4. rispondere alle numerose richieste di realizzazione del kit pervenutemi da molti colleghi di scuole italiane dopo il mio intervento per SCE Siemens in cui ho mostrato le mie sperimentazioni didattiche nell’ambito dell’automazione, tra queste anche EduRobot Lift. Ringrazio tutti.

Di seguito un breve video che mostra la struttura generale del kit e di seguito una guida fotografica passo passo che ne dettaglia le fasi di costruzione.

In successive lezioni verranno proposti modalità di controllo del sistema.

Sentitevi liberi di apportare modifiche e migliorie alla struttura. Mi farebbe piacere avere un vostro parere ed eventualmente, se utilizzate il kit, inviatemi le fotografie dei vostri lavori in modo che io possa pubblicarle su questo sito.

Il progetto è rilasciato con la seguente licenza: Attribuzione 4.0 Internazionale (CC BY 4.0)

Come viene mostrato nell’immagine che segue il kit è costituito da 21 elementi di compensato e due elementi stampati in 3D, nell’immagine potete notare anche un 3′ elemento, una piccola rondella di plastica, che è stata poi sostituita da un dado M3 (i dettagli al fondo di questa lezione).

Struttura impiegata per fissare il motore passo passo e il rocchetto utilizzato per avvolgere lo spago a cui verrà fissata la cabina dell’ascensore.

Nell’immagine si vedono viti M3 da 12 mm e dadi M3.

La colla vinilica viene utilizzata solamente per fissare i piedini alla base della struttura.

Poiché sulla base del kit sono presenti delle viti, per evitare che queste raschino la base di appoggio, sono stati previsti dei piedini la cui altezza è di 8 mm, ciò si ottiene incollando tra loro due elementi.

Incollare i piedini sugli angoli della base.

Allineare i piedini come riportato nell’immagine che segue.

Fare in modo che ci sia anche un allineamento rispetto alla verticale.

Predisporre il montaggio della cabina dell’ascensore. Si consiglia di inserire prima il dato nella fessura così come riportato nell’immagine. La parte inferiore della cabina è identica a quella superiore con la differenza che la parte superiore ha un foro in cui andremo ad inserire lo spago.

Inserire la parete laterale e dalla parte opposta inserire la vite. Bloccare i due elementi, ma attenzione a non avvitare con forza.

Procedere allo stesso modo per la parte posteriore della cabina dell’ascensore: Inserire i dadi, incastrare nella fessura la parete ed avvitare con le due viti.

Inserire la parte superiore della cabina contraddistinta da un foro centrale.

Passiamo ora alle colonne. Sono presenti 6 colonne di due tipi: con fori e senza fori, hanno tutte la stessa dimensione. Le colonne con fori hanno un’orientamento, nell’immagine si nota che i fori hanno distanze diverse dal bordo che va incastrato alle basi. I fori che hanno una distanza di 4 cm dalla base vanno rivolti verso la base di appoggio dell’ascensore.

Tre sono le colonne frontali ed andranno inserite nelle apposite fessure. Anche in questo caso si consiglia di inserire prima i dadi.

Posizione in cui devono essere inserite le colonne frontali.

Inserire le viti dalla parte inferiore della base.

Inserire le colonne laterali. Prima di inserirle nelle fessure incastrare i dadi M3.

Bloccare con viti.

Montare la colonna posteriore.

Procedere nel montaggio così come fatto per le altre colonne.

Inserire la cabina dell’ascensore, con la parte aperta disposta frontalmente.

Le scanalature laterali permettono di far scorrere la cabina tra le guide.

Fissare la base superiore del kit. Inserire nelle colonne i dadi e successivamente inserire nella posizione indicata dalle frecce le viti.

Avvitare, ma attenzione a non serrare con forza, rischiereste di rompere il compensato.

Inserire 4 viti nella posizione indicate dalle frecce.

Avvitare i dadi.

Inserire il rocchetto all’interno dell’asse del motore. Attenzione che il rocchetto ha un’orientamento, ciò è mostrato nel video ad inizio di questa lezione. Come si nota l’asse del motore non è cilindrico.

Inserire la vite nella posizione indicata dalla freccia, questa costituisce un supporto per il rocchetto. Avvitare il motore alla struttura.

Fissiamo lo spago alla cabina. Inserite lo spago nel foro dalla parte superiore e legateci un dado.

Poggiate la cabina sulla base della struttura e fate in modo che il filo sia ben dritto ed incollatelo sul rocchetto. Il risultato dovrebbe essere il seguente:

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

1/*  Prof. Maffucci Michele
2    06.01.2021
3 
4    Esempio 01
5    Variazione colore continuo
6    di un LED RGB secondo lo schema:
7 
8    ROSSO > VERDE, VERDE > BLU, BLU > ROSSO
9 
10*/
11 
12/* Utilizzo della direttiva #define per definire una costante
13   La direttiva viene utilizzata per definire una MACRO ovvero
14   un simbolo.
15 
16   La sintassi per la definizione di una macro è:
17   #define nome-MACRO  valore_MACRO
18 
19   Per convenzione il nome della macro viene scritta in maiuscolo.
20 
21   Il preprocessore legge la definizione di ogni MACRO e ogni volta che
22   ne incontra il nome all'interno del programma (file sorgente) sostituisce
23   al simbolo il valore corrispondente, senza che venga effettuata la verifica
24   della correttezza sintattica dell'espressione risultante.
25*/
26 
27#define VERDE 9
28#define BLU 10
29#define ROSSO 11
30 
31// tempo di dissolvenza tra i colori
32#define tempoRitardo 10
33 
34void setup()
35{
36  // impostazione ad OUTPUT dei pin
37  pinMode(ROSSO, OUTPUT);
38  pinMode(VERDE, OUTPUT);
39  pinMode(BLU, OUTPUT);
40 
41  // all'avvio viene emesso il colorore ROSSO
42  digitalWrite(BLU, LOW);
43  digitalWrite(VERDE, LOW);
44  digitalWrite(ROSSO, HIGH);
45}
46 
47// definizione di variabili
48int valoreRosso;
49int valoreVerde;
50int valoreBlu;
51 
52void loop()
53{
54  // Impostazioni variabili per avere partire con LED:
55  // ROSSO accesso, VERDE spento, BLU spento.
56  valoreRosso = 255;
57  valoreVerde = 0;
58  valoreBlu = 0;
59 
60  // partendo dal ROSSO si sfuma al VERDE pieno quando i = 255
61  for (int i = 0; i < 255; i += 1)
62  {
63    valoreRosso -= 1;
64    valoreVerde += 1;
65 
66    // L'intensità del ROSSO viene diminuita ad ogni ciclo, mentre
67    // l'intensità del VERDE viene aumentata ad ogni ciclo
68    analogWrite(ROSSO, valoreRosso);
69    analogWrite(VERDE, valoreVerde);
70    delay(tempoRitardo);
71  }
72 
73  // Impostazioni variabili per avere partire con LED:
74  // ROSSO spento, VERDE acceso, BLU spento.
75  valoreRosso = 0;
76  valoreVerde = 255;
77  valoreBlu = 0;
78 
79  // partendo dal VERDE si sfuma al BLU pieno quando i = 255
80  for (int i = 0; i < 255; i += 1)
81  {
82    valoreVerde -= 1;
83    valoreBlu += 1;
84 
85    // L'intensità del VERDE viene diminuita ad ogni ciclo, mentre
86    // l'intensità del BLU viene aumentata ad ogni ciclo
87    analogWrite(VERDE, valoreVerde);
88    analogWrite(BLU, valoreBlu);
89    delay(tempoRitardo);
90  }
91 
92  // Impostazioni variabili per avere partire con LED:
93  // ROSSO spento, VERDE spento, BLU acceso.
94  valoreRosso = 0;
95  valoreVerde = 0;
96  valoreBlu = 255;
97 
98  // partendo dal BLU si sfuma al ROSSO pieno quando i = 255
99  for (int i = 0; i < 255; i += 1)
100  {
101    valoreBlu -= 1;
102    valoreRosso += 1;
103 
104    // L'intensità del BLU viene diminuita ad ogni ciclo, mentre
105    // l'intensità del ROSSO viene aumentata ad ogni ciclo
106    analogWrite(BLU, valoreBlu);
107    analogWrite(ROSSO, valoreRosso);
108    delay(tempoRitardo);
109  }
110}

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.

1/*  Prof. Maffucci Michele
2    06.01.2021
3 
4    Esempio 02
5    Inserimento da Serial Monitor dei valori
6    di intensità del colore.
7    La stringa di richiesta inserimento viene ripetuta una sola volta.
8    Ad ogni nuovo inserimento non viene stampato sulla serial monitor
9    il valore inserito.
10 
11    L'inserimento dei tre valori potrà essere effettuato
12    in una delle due modalità:
13    1. separando i tre numeri con spazio
14    2. separando i tre numeri con la virgola
15*/
16 
17/*
18   Una variabile const indica al compilatore che il valore della
19   variabile non può essere modificato durante l'esecuzione del programma.
20   Una variabile const viene inizializzata nel momento della dichiarazione,
21   se ciò viene fatto in un momento successivo il compilatore rileverà un
22   errore che segnalerà anche errore in ogni operazione che comportano la
23   modifica del valore dell avariabile definita come const
24*/
25 
26const byte pinRosso = 11;
27const byte pinBlu = 10;
28const byte pinVerde = 9;
29 
30void setup() {
31  // Inizializzazione della comunicazione seriale
32  Serial.begin(9600);
33 
34  // Impostazione dei pin come OUTPUT
35  pinMode(pinRosso, OUTPUT);
36  pinMode(pinBlu, OUTPUT);
37  pinMode(pinVerde, OUTPUT);
38 
39  // Messaggio sulla serial monitor
40  Serial.println("Inserisci i valori R G B (es. 125, 50, 255)");
41  Serial.println("-------------------------------------------");
42  delay(1000);
43}
44 
45void loop() {
46 
47  // Controlla se è disponibile almeno un carattere sulla seriale
48  // La Serial.available() restituisce
49  // 1 se presente un cattere,
50  // 0 se non è presente un carattere
51 
52  // per maggior informazioni sull'uso di parseInt() consultare il link:
54 
55  if (Serial.available()) {
56    // memorizzazione dei colori nelle variabili
57    int rosso = Serial.parseInt();
58    int verde = Serial.parseInt();
59    int blu = Serial.parseInt();
60 
61    // impostazione del PWM
62    analogWrite(pinRosso, rosso);
63    analogWrite(pinVerde, verde);
64    analogWrite(pinBlu, blu);
65  }
66}

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.

1/*  Prof. Maffucci Michele
2    06.01.2021
3 
4    Esempio 03
5    Inserimento da Serial Monitor dei valori
6    di intensità del colore.
7    Il valore inserito verrà stampato sulla Serial Monitor e ad ogni
8    invio verrà richiesto di inserire un nuovo valore.
9 
10    L'inserimento dei tre valori potrà essere effettuato
11    in una delle due modalità:
12    1. separando i tre numeri con spazio
13    2. separando i tre numeri con la virgola
14*/
15 
16/*
17   Una variabile const indica al compilatore che il valore della
18   variabile non può essere modificato durante l'esecuzione del programma.
19   Una variabile const viene inizializzata nel momento della dichiarazione,
20   se ciò viene fatto in un momento successivo il compilatore rileverà un
21   errore che segnalerà anche errore in ogni operazione che comportano la
22   modifica del valore dell avariabile definita come const
23*/
24 
25const byte pinRosso = 11;
26const byte pinBlu = 10;
27const byte pinVerde = 9;
28 
29// per stampare una sola volta il messaggio sulla Serial Monitor
30bool abilitaMessaggio = 0;
31 
32void setup() {
33  // Inizializzazione della comunicazione seriale
34  Serial.begin(9600);
35 
36  // Impostazione dei pin come OUTPUT
37  pinMode(pinRosso, OUTPUT);
38  pinMode(pinBlu, OUTPUT);
39  pinMode(pinVerde, OUTPUT);
40}
41 
42void loop() {
43  // consente di visualizzare sulla Serial Monitor
44  // una sola stampa delle stringa
45  if (abilitaMessaggio == 0) {
46    // ritardo che evita la doppia stampa del messaggio
47    delay(200);
48    Serial.print("Inserisci i valori R G B (es. 125, 50, 255): ");
49    abilitaMessaggio = 1;
50  }
51 
52  // Controlla se è disponibile almeno un carattere sulla seriale
53  // La Serial.available() restituisce
54  // 1 se presente un cattere,
55  // 0 se non è presente un carattere
56 
57  // per maggior informazioni sull'uso di parseInt() consultare il link:
59 
60 
61  if (Serial.available()) {
62    // memorizzazione dei colori nelle variabili
63    int rosso = Serial.parseInt();
64    int verde = Serial.parseInt();
65    int blu = Serial.parseInt();
66    Serial.print(rosso);
67    Serial.print(", ");
68    Serial.print(verde);
69    Serial.print(", ");
70    Serial.println(blu);
71    Serial.println("-------------------------------------------");
72 
73    // impostazione del PWM
74    analogWrite(pinRosso, rosso);
75    analogWrite(pinVerde, verde);
76    analogWrite(pinBlu, blu);
77 
78    // abilita alla stampa di una nuova stringa:
79    // "Inserisci il ritardo in millisecondi: "
80    abilitaMessaggio = 0;
81  }
82}

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.

Arduino: utilizzo di buzzer attivi e passivi – lezione 1

Nella progettazione di un sistema di automazione sono molto spesso previsti apparati di interazione e di allarme che potranno essere visivi o sonori. Per quanto riguarda gli apparati sonori spesso vengono utilizzati dei buzzer, chiamati anche cicalini. Con questo dispositivo potremo quindi segnalare lo stato di un sistema.

I buzzer possono essere di due tipi:

  • attivi
  • passivi

I buzzer possono essere di tipo magnetico o piezoelettrici la scelta del tipo dipende sostanzialmente da tre fattori:

  1. segnale di pilotaggio
  2. potenza di uscita richiesta
  3. spazio fisico disponibile

Buzzer attivo

Un buzzer attivo usa un oscillatore interno che permette di emettere un tono a frequenza fissa se viene alimentato con una tensione continua.

L’oscillatore interno è in grado di modificare il campo magnetico di una bobina a cui è connesso meccanicamente una membrana che oscillerà alla frequenza fissata dall’oscillatore.

Con Arduino si potrà realizzare un sistema di automazione in grado di comandare l’emissione del suono abilitando o disabilitando l’alimentazione del buzzer.

Caratteristiche tecniche di un buzzer attivo

  • Tensione nominale: 6V DC
  • Tensione di esercizio: 4-8V DC
  • Corrente nominale: < 30mA
  • Tipo di suono: segnale acustico continuo
  • Frequenza di risonanza: ~2300 Hz

Buzzer passivo

Un buzzer passivo non possiede un oscillatore interno e quindi è indispensabile un circuito esterno in grado di generare un’onda quadra che mettere in oscillazione la membrana interna del buzzer, questi attuatori potranno così emettere toni a diversa frequenza.

Con Arduino si potrà realizzare un sistema di automazione in grado di comandare l’emissione del suono per un certo tempo ad una determinata frequenza utilizzando il la modulazione digitale PWM.

Caratteristiche tecniche di un buzzer attivo

  • Tensione nominale: 5V DC
  • Tensione di esercizio: 4-8V DC
  • Corrente nominale massima: ≤ 32 mA
  • Min. Uscita audio a 10 cm: 85 dB
  • Temperatura di esercizio: da 20°C a 45°C

Pilotare un buzzer con Arduino

Per produrre un suono con Arduino si utilizza la funzione tone, il link vi rimanda al references di Arduino in cui troverete tutti i dettagli di utilizzo della funzione.

L’istruzione che verrà utilizzata è:

1tone(pin, frequenza)
2tone(pin,frequenza,durata)
  • pin: sarà il pin (PWM) su cui sarà presente il segnale modulato a cui verrà connesso il buzzer.
  • frequenza: frequenza del suono emesso. (unsigned int)
  • durata: la durata del tono espressa in millisecondi. (unsigned long)

Come indicato nel references:

Genera un’onda quadra alla frequenza specificata ( e duty cycle al 50% ) su un pin. Una durata puà essere specificata, altrimenti l’onda continua fino alla chiamata di noTone(). Il pin può essere connesso ad un buzzer piezoelettrico o altro speaker per riprodurre toni.

Solo un tono alla volta può essere generato. Se un tono è gia in riproduzione su un pin differente, la chiamata a tone() non avrà alcun effetto. Se il tono è in riproduzione sullo stesso pin, la chiamata ne imposterà la frequenza.

L’uso della funzione tone() interferirà con l’output PWM sui pin 3 e 11 (sulle schede diverse dalla Mega ).

Non è possibile generare toni inferioni a 31Hz. Per i dettagli tecnici, vedi le note di Brett Hagman.

NOTA: Se vuoi riprodurre toni differenti su pin multipli, hai bisogno di chiamare noTone() su un pin prima di chiamare tone() sul pin successivo.

La funzione noTone() interrompe la generazione dell’onda quadra causata da tone(). L’uso di noTone() non ha alcun effetto se non si sta generando alcun tono.

Sintassi:

Con Arduino è possibile riprodurre un solo tono alla volta in quanto l’utilizzo della funzione tone è legato ad un timer specifico del microcontrollore, il timer2 e se questo è richiesto da altre funzioni, come ad esempio un analogRead su pin PWM la funzione tone non potrà essere utilizzata. Per aggirare questo limite è possibile utilizzare la libreria Tone.h che vedremo nella prossime lezioni.

Il suono che può essere riprodotto mediante un altoparlante o un buzzer passivo collegato ad Arduino sarà un suono “metallico”, non sarà simile a quello di uno strumento musicale, e questo verrà ottenuto utilizzando un’onda quadra alla frequenza specificata.

Per riprodurre suoni simili a quelli di uno strumento musicale bisognerà utilizzare una scheda elettronica esterna che verrà controllata da Arduino, ma vedremo questa possibilità in una lezione successiva.

Per questa lezione utilizzerò prima un buzzer attivo e successivamente un buzzer passivo.

Esempio 1 – utilizzo buzzer attivo

 

1/* Prof. Michele Maffucci
2   data: 04.01.2021
3 
4   Esempio 01
5   Utilizzo di un buzzer attivo
6*/
7 
8// pin a cui è collegato il buzzer
9byte buzzerPin = 2;
10int buzzerRitardo = 1000;     
11 
12void setup() {
13  // inizializzazione pin a cui è collegto il buzzer
14  pinMode(buzzerPin, OUTPUT);
15}
16 
17void loop() {
18   
19  // buzzer ON
20  digitalWrite(buzzerPin,HIGH);
21  delay(buzzerRitardo);
22 
23  // buzzer OFF
24  digitalWrite(buzzerPin,LOW);
25  delay(buzzerRitardo);
26}

Esempio 02 – utilizzo buzzer attivo

Per richiamare l’uso di valori interi dalla Serial Monitor di seguito uno sketch che permette di inserire da computer il valore del delay che regola l’ON e l’OFF del buzzer attivo.

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

1/* Prof. Michele Maffucci
2   data: 04.01.2021
3 
4   Esempio 02
5   Utilizzo di un buzzer attivo
6   Inserimento delay da Serial Monitor
7*/
8 
9// pin a cui è collegato il buzzer
10byte buzzerPin = 2;
11int  buzzerRitardo = 0;     
12 
13// per stampare una sola volta il messaggio sulla Serial Monitor 
14bool abilitaMessaggio = 0;
15 
16void setup() {
17    
18  // inizializzazione della serial monitor
19  Serial.begin(9600);
20 
21  // inizializzazione pin a cui è collegto il buzzer
22  pinMode(buzzerPin, OUTPUT);
23}
24 
25void loop() {
26 
27  // consente di visualizzare sulla Serial Monitor
28  // una sola stampa delle stringa
29  if (abilitaMessaggio == 0) {
30    // ritardo che evita la doppia stampa del messaggio
31    delay(200);
32    Serial.print("Inserisci il ritardo in millisecondi: ");
33    abilitaMessaggio = 1;
34  }
35 
36  // Controlla se è disponibile almeno un carattere sulla seriale
37  // La Serial.available() restituisce
38  // 1 se presente un cattere,
39  // 0 se non è presente un carattere
40 
41  // per maggior informazioni sull'uso di parseInt() consultare il link:
43 
44  if (Serial.available())
45  {
46    // in r viene memorizzato il valore inserito
47    // attraverso la Serial Monitor
48    int r = Serial.parseInt();
49    if (r != 0) {
50      buzzerRitardo = r;
51      Serial.println(buzzerRitardo);
52 
53      // abilita alla stampa di una nuova stringa:
54      // "Inserisci il ritardo in millisecondi: "
55      abilitaMessaggio = 0;
56    }
57  }
58   
59  // funzione permette di fare suonare il Buzzer
60  suona();
61}
62 
63void suona() {
64  // buzzer ON
65  digitalWrite(buzzerPin,HIGH);
66  delay(buzzerRitardo);
67 
68  // buzzer OFF
69  digitalWrite(buzzerPin,LOW);
70  delay(buzzerRitardo);
71}

Esempio 03 – utilizzo buzzer attivo

Utilizziamo ora un trimmer per modificare il delay che varia tra 100 e 1000 millisecondi, per fare questa operazione utilizzeremo la funzione map che rimapperà i valori presenti su A0 nell’intervallo 100, 1000.

 

1/* Prof. Michele Maffucci
2   data: 01.01.2021
3 
4   Esempio 03
5   Utilizzo di un buzzer attivo
6   Inserimento delay da Trimmer per impostare
7   un ritardo tra 100 e 1000 millisecondi
8*/
9 
10// pin a cui è collegato il buzzer
11byte buzzerPin = 2;
12int  buzzerRitardo = 0;     
13 
14// per stampare una sola volta il messaggio sulla Serial Monitor 
15bool abilitaMessaggio = 0;
16 
17// variabile in cui memorizzare il valore restituito dall'analogRead
18int val = 0;
19 
20void setup() {
21    
22  // inizializzazione della serial monitor
23  Serial.begin(9600);
24 
25  // inizializzazione pin a cui è collegto il buzzer
26  pinMode(buzzerPin, OUTPUT);
27}
28 
29void loop() {
30 
31  // valore analogico letto su A0 inserito con il trimmer
32  val = analogRead(A0);
33 
34// Togliere il commento per valutare
35// valore massimo/minimo del valore restituito
36// dall'analogRead in questo modo si potranno
37// inserire nella map i valori massimi e minimi
38// dell'intervallo di partenza
39 
40// Serial.println(val);
41// delay(1000);
42 
43  // ValMax = 285, ValMin = 719
44  // riconvertiti nell'intervallo 100, 1000
45   
46  buzzerRitardo = map(val, 285, 719, 100, 1000);
47 
48  // funzione permette di fare suonare il Buzzer
49  suona();
50}
51 
52void suona() {
53  // buzzer ON
54  digitalWrite(buzzerPin,HIGH);
55  delay(buzzerRitardo);
56 
57  // buzzer OFF
58  digitalWrite(buzzerPin,LOW);
59  delay(buzzerRitardo);
60}

Esempio 4 – utilizzo buzzer passivo

Utilizziamo ora un buzzer passivo per riprodurre un tono in base alla frequenza impostata da un trimmer collegato al pin A0. Si faccia attenzione che ora il buzzer è collegato al pin 5 di tipo PWM

1/* Prof. Michele Maffucci
2   data: 04.01.2021
3 
4   Esempio 04
5   Utilizzo di un buzzer passivo per riprodurre
6   un tono in base alla frequenza impostata
7   da un trimmer collegato al pin A0
8*/
9 
10// pin (PWM) a cui è collegato il buzzer
11byte buzzerPin = 5;
12 
13// variabile in cui memorizzare la frequenza del tono
14int  intonazionePin = 0;
15 
16 // variabile in cui memorizzare il valore restituito dall'analogRead
17int val = 0;
18 
19// frequenza del tono
20unsigned int frequenza;
21 
22// durata del tono
23unsigned long durata = 10;
24 
25void setup()
26{
27  // inizializzazione pin a cui è collegto il buzzer
28  pinMode(buzzerPin, OUTPUT);
29}
30 
31void loop()
32{
33   // valore analogico letto su A0 inserito con il trimmer
34   val = analogRead(A0);
35 
36 // Togliere il commento per valutare
37// valore massimo/minimo del valore restituito
38// dall'analogRead in questo modo si potranno
39// inserire nella map i valori massimi e minimi
40// dell'intervallo di partenza
41 
42// Serial.println(val);
43// delay(1000);
44 
45  // ValMax = 285, ValMin = 719
46  // riconvertiti nell'intervallo 1000, 5000
47 
48  // frequenza assunerà un valore tra 1000 Hz e 5000 Hz
49  frequenza = map(val, 285, 719, 1000, 5000);
50 
51  // emissione del tono
52  tone(buzzerPin, frequenza, durata);
53 
54  // pausa di 1 millisecondo
55  delay(1);
56}

Nella prossime lezioni, utilizzando un buzzer passivo, realizzeremo dei brevi brani musicali e successivamente sostituiremo il buzzer con un altoparlante da 8 Ohm.

Buon Making a tutti 🙂

Arduino: controllo sequenziale uscite digitali

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.

 

1/* Prof. Michele Maffucci
2   30.12.2020
3   Lezione di riferimento: https://wp.me/p4kwmk-4D3
4 
5   Versione 01
6   Sequenza di accensione e spegnimento alternato
7   da destra e sinistra e viceversa di 8 LED con
8   tempo di accensione di 100 millisecondi.
9    
10   Questo codice è di dominio pubblico
11 */
12 
13// creazione di un array di 8 pin a cui vanno collegati i LED
14// per ulteriori informazioni sull'uso degli array si consulti il seguente link:
16 
17byte ledPin[] = {3, 4, 5, 6, 7, 8, 9, 10};
18 
19// per approfondimenti sull'uso dei tipi di dati
20// si consultino i link:
23 
24// intervallo di accensione/spegnimento
25byte ritardoLed = 100;
26 
27// indicatore di direzione di accensione
28byte direzione = 1;
29 
30// indice dell'array per l'accensione del LED
31byte ledCorrente = 0;
32 
33// variabile in cui memorizzare il tempo di accensione di Arduino
34// per ulteriori informazioni sui tipi unsigned long si consulti il seguente link:
36 
37unsigned long tempoTrascorso;
38 
39void setup() {               
40  // impostiamo tutti i pin ad output
41  for (byte x=0; x<8; x++) {
42    pinMode(ledPin[x], OUTPUT);
43  }
44     
45  // Memorizzazione del tempo trascorso
46  // dal momento in cui avviamo Arduino
47  // Per ulteriori informazioni sull'uso di millis() si consulti il seguente link:
49   
50  tempoTrascorso = millis();
51}
52 
53void loop() {
54  // Se sono passati "ritardoLed" millisecondi dall'ultimo cambiamento
55  if ((millis() - tempoTrascorso) > ritardoLed) {
56    cambiaStatoLed();
57    tempoTrascorso = millis();
58  }
59}
60 
61// la funzione cambiaStatoLed() permette di controllare
62// la sequenza di accensione dei LED
63 
64void cambiaStatoLed() {
65  // spegne tutti i LED
66  for (byte x=0; x<8; x++) {
67    digitalWrite(ledPin[x], LOW);
68  }
69  // accende il LED corrente
70  digitalWrite(ledPin[ledCorrente], HIGH);
71  // incrementa la variabile direzione
72  ledCorrente += direzione;
73  // cambia la direzione se si arriva alla fine
74  if (ledCorrente == 7) {
75    direzione = -1;
76  }
77  if (ledCorrente == 0) {
78    direzione = 1;
79  }
80}

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).

1/* Prof. Michele Maffucci
2   30.12.2020
3   Lezione di riferimento: https://wp.me/p4kwmk-4D3
4 
5   Versione 02
6   Sequenza di accensione e spegnimento alternato
7   da destra e sinistra e viceversa di 8 LED controllato
8   da un trimmer che permetterà di variare il tempo di accensione
9   da 50 millisecondi a 1000 millisecondi (1 secondo).
10    
11   Questo codice è di dominio pubblico
12 */
13 
14// creazione di un array di 8 pin a cui vanno collegati i LED
15// per ulteriori informazioni sull'uso degli array si consulti il seguente link:
17 
18byte ledPin[] = {3, 4, 5, 6, 7, 8, 9, 10};
19 
20// per approfondimenti sull'uso dei tipi di dati
21// si consultino i link:
24 
25// intervallo di accensione/spegnimento
26int ritardoLed;
27 
28// variabile in cui memorizzare il valore restituito dall'analogRead
29int val = 0;
30 
31// indicatore di direzione di accensione
32byte direzione = 1;
33 
34// indice dell'array per l'accensione del LED
35byte ledCorrente = 0;
36 
37// variabile in cui memorizzare il tempo di accensione di Arduino
38// per ulteriori informazioni sui tipi unsigned long si consulti il seguente link:
40 
41unsigned long tempoTrascorso;
42 
43void setup() {
44  Serial.begin(9600);           
45  // impostiamo tutti i pin ad output
46  for (byte x=0; x<8; x++) {
47    pinMode(ledPin[x], OUTPUT);
48  }
49     
50  // Memorizzazione del tempo trascorso
51  // dal momento in cui avviamo Arduino
52  // Per ulteriori informazioni sull'uso di millis() si consulti il seguente link:
54   
55  tempoTrascorso = millis();
56}
57 
58void loop() {
59 
60  // valore analogico letto su A0 inserito con il trimmer
61  val = analogRead(A0);
62 
63// Togliere il commento per valutare
64// valore massimo/minimo del valore restituito
65// dall'analogRead in questo modo si potranno
66// inserire nella map i valori massimi e minimi
67// dell'intervallo di partenza
68 
69// Serial.println(val);
70// delay(1000);
71 
72  // ValMax = 285, ValMin = 719
73  // riconvertiti nell'intervallo 50, 1000
74   
75  ritardoLed = map(val, 285, 719, 50, 1000);
76   
77  // Se sono passati "ritardoLed" millisecondi dall'ultimo cambiamento
78  if ((millis() - tempoTrascorso) > ritardoLed) {
79    cambiaStatoLed();
80    tempoTrascorso = millis();
81  }
82}
83 
84// la funzione cambiaStatoLed() permette di controllare
85// la sequenza di accensione dei LED
86 
87void cambiaStatoLed() {
88  // spegne tutti i LED
89  for (byte x=0; x<8; x++) {
90    digitalWrite(ledPin[x], LOW);
91  }
92  // accende il LED corrente
93  digitalWrite(ledPin[ledCorrente], HIGH);
94  // incrementa la variabile direzione
95  ledCorrente += direzione;
96  // cambia la direzione se si arriva alla fine
97  if (ledCorrente == 7) {
98    direzione = -1;
99  }
100  if (ledCorrente == 0) {
101    direzione = 1;
102  }
103}

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.

1/* Prof. Michele Maffucci
2   30.12.2020
3   Lezione di riferimento: https://wp.me/p4kwmk-4D3
4 
5   Versione 03
6   Sequenza di accensione e spegnimento alternato
7   da destra e sinistra e viceversa di 8 LED.
8 
9   Partenza sequenza con 100 millisecondi e messaggio sulla
10   Serial Monitor per modificare il tempo di
11   accensione e spegnimento del singolo LED (delay)
12    
13   Questo codice è di dominio pubblico
14 */
15 
16// creazione di un array di 8 pin a cui vanno collegati i LED
17// per ulteriori informazioni sull'uso degli array si consulti il seguente link:
19 
20byte ledPin[] = {3, 4, 5, 6, 7, 8, 9, 10};
21 
22// per approfondimenti sull'uso dei tipi di dati
23// si consultino i link:
26 
27// intervallo di accensione/spegnimento
28int ritardoLed = 100;
29 
30// indicatore di direzione di accensione
31byte direzione = 1;
32 
33// indice dell'array per l'accensione del LED
34byte ledCorrente = 0;
35 
36// variabile in cui memorizzare il tempo di accensione di Arduino
37// per ulteriori informazioni sui tipi unsigned long si consulti il seguente link:
39 
40unsigned long tempoTrascorso;
41 
42// per stampare una sola volta il messaggio sulla Serial Monitor 
43bool abilitaMessaggio = 0;
44 
45void setup() {
46  // inizializzazione della serial monitor
47  Serial.begin(9600);
48                
49  // impostiamo tutti i pin ad output
50  for (byte x=0; x<8; x++) {
51    pinMode(ledPin[x], OUTPUT);
52  }
53 
54  // Memorizzazione del tempo trascorso
55  // dal momento in cui avviamo Arduino
56  // Per ulteriori informazioni sull'uso di millis() si consulti il seguente link:
58  tempoTrascorso = millis();
59}
60 
61void loop() {
62  // consente di visualizzare sulla Serial Monitor
63  // una sola stampa delle stringa
64  if (abilitaMessaggio == 0) {
65    // ritardo che evita la doppia stampa del messaggio
66    delay(200);
67    Serial.print("Inserisci il ritardo in millisecondi: ");
68    abilitaMessaggio = 1;
69  }
70 
71  // Controlla se è disponibile almeno un carattere sulla seriale
72  // La Serial.available() restituisce
73  // 1 se presente un cattere,
74  // 0 se non è presente un carattere
75 
76  // per maggior informazioni sull'uso di parseInt() consultare il link:
78 
79  if (Serial.available())
80  {
81    // in r viene memorizzato il valore inserito
82    // attraverso la Serial Monitor
83    int r = Serial.parseInt();
84    if (r != 0) {
85      ritardoLed = r;
86      Serial.println(ritardoLed);
87 
88      // abilita alla stampa di una nuova stringa:
89      // "Inserisci il ritardo in millisecondi: "
90      abilitaMessaggio = 0;
91    }
92  }
93   
94  // funzione che fa lampeggiare il LED su Arduino
95  lampeggio();
96}
97 
98void lampeggio() {
99  // Se sono passati "ritardoLed" millisecondi dall'ultimo cambiamento
100  if ((millis() - tempoTrascorso) > ritardoLed) {
101    cambiaStatoLed();
102    tempoTrascorso = millis();
103  }
104}
105 
106// la funzione cambiaStatoLed() permette di controllare
107// la sequenza di accensione dei LED
108 
109void cambiaStatoLed() {
110  // spegne tutti i LED
111  for (byte x = 0; x < 8; x++) {
112    digitalWrite(ledPin[x], LOW);
113  }
114  // accende il LED corrente
115  digitalWrite(ledPin[ledCorrente], HIGH);
116  // incrementa la variabile direzione
117  ledCorrente += direzione;
118  // cambia la direzione se si arriva alla fine
119  if (ledCorrente == 7) {
120    direzione = -1;
121  }
122  if (ledCorrente == 0) {
123    direzione = 1;
124  }
125}

Continua a leggere

BBC micro:bit – Esercizio: Realizzare un timer per il lavaggio delle mani

In una situazione di didattica a distanza fare laboratorio può essere complicato, ma con un po’ di fantasia e l’aiuto degli studenti si può fare molto. Alcuni mesi fa avevo proposto ai miei allievi questa stessa esercitazione però realizzata con Arduino: Arduino – Esercizio: Realizzare un timer per il lavaggio delle mani.

Ho realizzato la medesima esercitazione questa volta con BBC micro:bit in tre modalità diverse che vi condivido, nel codice trovate anche i commenti che spiegano sommariamente il codice. Ovviamente al sistema potrebbe essere aggiunto:

  • allarme sonoro
  • servomotore su cui inserire indice rotante, così come fatto per la sperimentazione con Arduino.

Spero che questa proposta possa essere utile anche ad altri.

Versione 1 (link al codice sorgente)

Versione 2 (link al codice sorgente)

Versione 3 (link al codice sorgente)

Buon making a tutti.