Archivi categoria: arduino

Arduino: controllare il movimento di un motore a spazzola con un transistor

Abbiamo visto a lezione in cosa consiste la Modulazione di Larghezza di Impulso, in altro modo conosciuta come PWM (Pulse Width Modulation). Questo tipo di modulazione permette ad un sistema digitale di controllare dispositivi di tipo analogico in corrente continua facendo variare in modo continuo la potenza erogata, quindi moduliamo la larghezza di un impulso, ovvero la durata temporale di una serie di impulsi che regolerà l’attivazione e disattivazione del motore. Con il PWM agiamo non sulla tensione di alimentazione per controllare la velocità del motore, ma bensì sul tempo, per maggiori informazioni vi rimando alle slide: Alfabeto Arduino – Lezione 2 in cui come esempio viene controllata l’intensità luminosa di LED. (Per i miei studenti fate riferimento al libro di testo e agli appunti di teoria).

Il transistor nell’immagine che segue viene fatto funzionare in modalità ON-OFF e quindi  possiamo assimilarlo ad un interruttore che si apre e si chiude in corrispondenza del segnale presente sulla base del transistor. Se il segnale sulla base è alto il transistor sarà in conduzione e il motore potrà essere alimentato (si chiude verso massa il collegamento del motore). Se il segnale sulla base del transistor è a livello basso il transistor è assimilabile ad un interruttore aperto per cui il motore risulta non alimentato (non si ha collegamento a massa). Quindi al motore verrà applicata una tensione continua proporzionale al duty cycle e quindi variando il duty cycle varieremo la velocità di rotazione del motore.

La generazione dell’onda quadra, che controlla la velocità del motore, viene eseguita da Arduino. Il diodo presente nel circuito è chiamato diodo di ricircolo ed è inserito in parallelo al motore (carico induttivo) per sopprimere i transienti elettrici ed è collegato in modo tale che non conduce quando il carico (il motore) viene alimentato.
Quando il motore viene disattivato rapidamente si avrà un picco di tensione in senso inverso perché l’induttore tenderà a mantenere costante la corrente che circola al suo interno, in questa situazione però il diodo sarà polarizzato direttamente e tutta la corrente scorrerà dall’induttore al diodo e l’energia che era stata immagazzinata dall’induttore  viene dissipata in calore dalla componente resistiva dell’induttore. Inserendo il diodo si eviterà di applicare una sovratensione sul collettore del transistor evitando quindi che si danneggi.

Controlliamo con Arduino il movimento del motore

Lista Componenti

  • Arduino UNO R3
  • Resistore da 1 K Ohm
  • Dido: 1N4001
  • Transistor: 2N2222
  • Condensatore: 0,1 microF

Pinout transistor 2N2222

Circuito 1 di montaggio: alimentazione del motore prelevata da Arduino

Circuito 2 di montaggio: alimentazione del motore esterna ad Arduino

Esempio 1
Si faccia riferimento al circuito 1. Realizziamo uno sketch che permette la regolazione della velocità del motore inserendo un numero compreso tra 0 e 9. Il valore 0 ferma il motore, il valore 9 permette di muovere il motore alla velocità massima, valori intermedi movimenteranno il motore ad una velocità proporzionale al numero inserito.

Valori fuori dall’intervallo impostato restituiscono un messaggio di errore.

Per la realizzazione di questo sketch si utilizza la funzione isDigit() che restituisce TRUE verifica se il carattere inviato sulla Serial Monitor è un numero, altrimenti restituisce FALSE.

1/*
2   Prof. Maffucci Michele
3   Controllo motore a spazzola:
4   accensione, spegnimento, controllo velocità.
5   All'avvio del programma il motore è spento.
6 
7   La velocità del motore è impostata
8   con un valore compreso tra 0 e 9
9 
10   Valori non numerici restituiscono
11   un messaggio di errore
12    
13   Data: 19.01.2021
14*/
15 
16// driver del motore collegato al pin 6
17const byte pinMotore = 6; // motor driver is connected to pin 3
18 
19// per stampare una sola volta il messaggio sulla Serial Monitor 
20bool abilitaMessaggio = 0;
21 
22void setup()
23{
24  // inizializzazione della serial monitor
25  Serial.begin(9600);
26 
27  // inizializzazione OUTPUT del pin 6
28  pinMode(pinMotore, OUTPUT);
29}
30 
31void loop()
32{
33  // consente di visualizzare sulla Serial Monitor
34  // una sola stampa delle stringa
35  if (abilitaMessaggio == 0) {
36    // ritardo che evita la doppia stampa del messaggio
37    delay(200);
38    Serial.println("Controllo velocità motore");
39    Serial.println("Inserire la velocità (0 - 9)");
40    Serial.println();
41    abilitaMessaggio = 1;
42  }
43 
44  // Controlla se è disponibile almeno un carattere sulla seriale
45  // La Serial.available() restituisce
46  // 1 se presente un cattere,
47  // 0 se non è presente un carattere
48 
49  // per maggior informazioni sull'uso di parseInt() consultare il link:
51   
52  if (Serial.available()) {        // Viene controllato se è disponibile un carattere
53 
54    // definizione di una variabile di tipo char in cui memorizzare
55    // il carattere inviato ad Arduino mediante la Serial Monitor
56 
57    char carattere = Serial.read();
58 
59    // La funzione isDigit restituisce TRUE se se il carattere
60    // inviato sulla Serial Monitor è un numero altrimenti restituisce FALSE
61 
62    if (isDigit(carattere)) // verifica se è un numero
63    {
64      // mappiamo l'intervallo dei caratteri da '0' a '9'
65      // in un valore compreso tra 0 e 255, intervallo di valori
66      // del Duty Cycle
67 
68      int vel = map(carattere, '0', '9', 0, 255);
69      analogWrite(pinMotore, vel);
70       
71      Serial.print("Valore del Duty Cycle: ");
72      Serial.println(vel);
73      Serial.println("--------------------------");
74      Serial.print("Velocità impostata: ");
75      Serial.println(carattere);
76      Serial.println("==========================");
77             
78    }
79    else
80    {
81      // nel caso in cui il carattere inserito non è un numero
82      // viene restituito un messaggio e stampa il carattere
83      Serial.println();
84      Serial.println("******************************");
85      Serial.print("Carattere non riconosciuto: ");
86      Serial.println(carattere);
87      Serial.println("******************************");
88      Serial.println();
89    }
90  }
91}

Esempio 2
Si faccia riferimento al circuito 1. Realizziamo uno sketch che permette la regolazione della velocità del motore inserendo un numero compreso tra 0 e 9. Il valore 0 ferma il motore, il valore 9 permette di muovere il motore alla velocità massima, valori intermedi movimenteranno il motore ad una velocità proporzionale al numero inserito.

Valori fuori dall’intervallo impostato fermano il motore.

Per la realizzazione di questo sketch si utilizza la funzione Serial.parseInt() che legge i caratteri sulla seriali e restituisce la loro rappresentazione numerica (tipo long). I caratteri che non sono numeri interi (o con segno meno) vengono ignorati.

Nel dettaglio

  • I caratteri iniziali che non sono cifre o sono numeri negativi vengono ignorati;
  • L’analisi si interrompe quando non sono stati letti caratteri per un valore di tempo di timeout che può essere configurato oppure viene letta una non cifra;
  • Se non sono state lette cifre valide quando si verifica il timeout (vedere Serial.setTimeout ()), viene restituito 0; Serial.parseInt () eredita dalla classe Stream.
1/*
2   Prof. Maffucci Michele
3   Controllo motore a spazzola:
4   accensione, spegnimento, controllo velocità.
5   All'avvio del programma il motore è spento.
6 
7   La velocità del motore è impostata
8   con un valore compreso tra 0 e 9
9 
10   Valori non numerici fermano il motore.
11 
12   Viene utilizzata la funzione Serial.parseInt() per leggere
13 
14   Data: 19.01.2021
15 
16*/
17 
18// driver del motore collegato al pin 6
19const byte pinMotore = 6; // motor driver is connected to pin 3
20 
21// per stampare una sola volta il messaggio sulla Serial Monitor
22bool abilitaMessaggio = 0;
23 
24void setup()
25{
26  // inizializzazione della serial monitor
27  Serial.begin(9600);
28 
29  // inizializzazione OUTPUT del pin 6
30  pinMode(pinMotore, OUTPUT);
31}
32 
33void loop()
34{
35  // consente di visualizzare sulla Serial Monitor
36  // una sola stampa delle stringa
37  if (abilitaMessaggio == 0) {
38    // ritardo che evita la doppia stampa del messaggio
39    delay(200);
40    Serial.println("Controllo velocità motore");
41    Serial.println("Inserire la velocità (0 - 9)");
42    Serial.println();
43    abilitaMessaggio = 1;
44  }
45 
46  // Controlla se è disponibile almeno un carattere sulla seriale
47  // La Serial.available() restituisce
48  // 1 se presente un cattere,
49  // 0 se non è presente un carattere
50 
51  // per maggior informazioni sull'uso di parseInt() consultare il link:
53 
54  if (Serial.available()) {        // Viene controllato se è disponibile un carattere
55 
56    // definizione di una variabile di tipo char in cui memorizzare
57    // il carattere inviato ad Arduino mediante la Serial Monitor
58 
59    // per maggior informazioni sull'uso di parseInt() consultare il link:
61 
62    int valore = Serial.parseInt();
63 
64    // La funzione isDigit verifica se il carattere inviato è un numero
65    // e restituisce TRUE se il carattere è un numero altrimenti restituisce FALSE
66 
67    // mappiamo l'intervallo dei caratteri da '0' a '9'
68    // in un valore compreso tra 0 e 255, intervallo di valori
69    // del Duty Cycle
70 
71    if (valore >= 0 && valore <= 9) {
72 
73      if (valore == 0) {
74        Serial.println();
75        Serial.println("************************************");
76        Serial.println("MOTORE FERMO");
77        Serial.println("Valore inserito 0 o fuori intervallo");
78        Serial.println("************************************");
79        Serial.println();
80      }
81 
82      int vel = map(valore, 0, 9, 0, 255);
83      analogWrite(pinMotore, vel);
84 
85      Serial.print("Valore del Duty Cycle: ");
86      Serial.println(vel);
87      Serial.println("--------------------------");
88      Serial.print("Velocità impostata: ");
89      Serial.println(valore);
90      Serial.println("==========================");
91    }
92  }
93}

Esercizio 1
Aggiungere al circuito 1 due pulsanti che permettono di aumentare o diminuire la velocità del motore. Fare in modo che la velocità impostata del motore sia proporzionale ai valori numerici interi nell’intervallo tra 0 e 9, così come fatto negli esempi precedenti. Ad ogni pressione del pulsante P1 si incrementa di una unità il valore della velocità. Ad ogni pressione del pulsante P2 si decrementa la velocità del motore i una unità. All’avvio di Arduino il motore è spento. Mostrare la velocità impostata sulla serial monitor.

Esercizio 2
Aggiungere all’esercizio precedente un pulsante P3 di emergenza che alla pressione ferma il motore. Se è stata azionata l’emergenza i pulsanti P1 e P2 di incremento e decremento non funzionano. Per poter riattivare il sistema bisogna premere nuovamente P3.

Supporto per motore a spazzola kit ELEGOO

La quasi totalità dei miei studenti, per svolgere le attività di sperimentazione di elettronica e automazione a casa e a scuola in questo periodo di crisi pandemica, ha acquistato uno dei molti kit ELEGOO in cui, anche nella versione base del kit, sono presenti tutti i componenti per svolgere le prime esercitazioni di automazione. All’interno dei diversi kit è presente un motore CC a spazzola 3-6 V come quello indicato nell’immagine che segue a cui è possibile connettere una ventola.

Questo semplice motore viene utilizzato in diverse esperienze di laboratorio: marcia e arresto, controllo di velocità e molto altro. Per far si che il banco di lavoro sia ordinato ho realizzato in 3D tre elementi che permettono di disporre il motore su un supporto di legno ricavato da una comune bacchetta di legno 20×20 mm che può essere acquistata in qualsiasi brico.

Condivido su Thingiverse i sorgenti grafici per la realizzazione del supporto.

Di seguito alcune immagini della semplice struttura… e quando farà caldo tutti avranno il proprio ventilatore personale 🙂

Buon Making a tutti 🙂

SumoFoam – per realizzare velocemente una struttura per robot didattico

“5 minuti da Maker” è orami un’abitudine che ho da qualche tempo: progettare in 5 minuti un oggetto o una soluzione e realizzarla. Alcune volte realizzarla mi richiede un po’ più di 5 minuti, ma cerco di non superare in tutto 60 minuti. E’ un’esercizio che mi sono imposto settimanalmente, un po’ come svago un po’ per dar sfogo ad idee nascenti che potrebbero diventare qualcosa di più importante.

Questa volta l’esercizio consiste nel rendere ancora più semplice la realizzazione del SumoBot, picco robot realizzato in compensato, trasformandolo in una versione realizzata con un materiale ancora più semplice da manipolare per gli studenti più giovani, il Foam Core, (per saperne di più continua la lettura 😉 ).

Durante una delle tante attività di PCTO feci realizzare ai miei studenti di 3′ automazione un il piccolo SumoBot su una base di compensato da 3mm, l’attività consisteva nel montare la struttura, l’elettronica e programmare i robot affinchè potessero gareggiare. Il tutto era stato realizzato con schede Arduino UNO R3 e anche con degli Arduino micro, due micro servo SG90 a rotazione continua ed un sensore ad ultrasuoni. Alcuni aggiunsero al robot una scheda Bluetooth per poter pilotare il robot anche via smartphone. Fu un’attività divertentissima che voglio riproporre ai ragazzi.

Nel riprendere in mano il progetto ho pensato di realizzare una versione della struttura in Foam Core, un materiale utilizzato dagli architetti per costruire plastici di abitazioni.  Si tratta di uno strato di spugna racchiuso da due fogli di cartoncino. Viene venduto in fogli di diverso spessore e dimensione, attualmente sto utilizzando fogli A3 di spessore 5mm. Le strutture che se ne ricavano sono sufficientemente solide. Utilizzo questo materiale quando voglio prototipare rapidamente oggetti per le mie sperimentazioni, come quello che vedete nell’immagine che segue, un supporto per un display 16×2.

In genere stampo su fogli adesivi bianchi A4 la struttura che voglio realizzare, dispongo i fogli adesivi sul Foam Core e con un cutter ne ritaglio il profilo. Tutti gli elementi poi vengono incastrati e incollati con normalissima colla vinilica.

Con il Foam Core ho provato a realizzare una serie di piccoli robot e sono rimasto più che soddisfatto.

Di seguito la sequenza fotografica delle fasi di montaggio, il taglio degli elementi non è perfetto, con un po’ più tempo e pazienza si può fare molto meglio.

Tra qualche giorno, quando terminerò di effettuare le ultime prove sul SumoFoam renderò pubblico il file pdf.

Stampo su foglio adesivo bianco il profilo del robot ed incollo su Foam Core.

Si nota la struttura a sandwich del pannello: cartoncino – materiale spugnoso – cartoncino

Oltre ad incastrare i vari elementi ho utilizzato della colla vinilica.

Prossimamente il montaggio dell’elettronica da parte dei miei studenti.

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 🙂