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.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.