Arduino: encoder conta impulsi-giri motore

A cosa serve un conta impulsi?

Un conta impulsi serve a contabilizzare gli impulsi elettrici che arrivano da sensori, cioè a stabilirne la quantità in base ad una unità di tempo. I sensori normalmente sono dei contagiri del motore (encoder), oppure dei sensori di posizione. Servo nei robot per stabilire il tragitto percorso e la direzione da prendere.

Il conta impulsi può servire per contare le persone che entrano in una stanza o in una fiera. Ci sono misuratori di energia che emettono impulsi in proporzione ai Watt consumati. Attualmente anche i contatori di acqua e gas possono presentare delle uscite a impulsi per il conteggio dei consumi.

Ci sono dei potenziometri che all’interno hanno un encoder rotativo per stabilirne la posizione. Vengono utilizzati in abbinamento ad un microprocessore, come Arduino, per cambiare numeri nelle memorie o menù nei display.

Come funziona un conta impulsi

Il conta impulsi può essere diviso in almeno tre parti principali:

  • la base dei tempi T in cui vengono contabilizzati gli impulsi elettrici
  • la sezione elettronica che somma i singoli impulsi S
  • il circuito di ingresso che adatta il segnale entrante e lo rende compatibile con la sezione elettronica che esegue il conteggio A

La base dei tempi può essere fissa con un certo lasso di tempo, oppure senza tempo. In quest’ultimo caso il contatore di impulsi è assoluto, e conteggia fino a quando non viene spento/azzerato. Ogni impulso incrementa un contatore, aumentando il numero memorizzato. Quando è terminato il tempo massimo per la conta il numero viene visualizzato su un display o altro dispositivo di visualizzazione. Il contatore ed il timer vengono azzerati e si ricomincia a contare gli impulsi in ingresso.

La sezione che somma gli impulsi, via via che arrivano all’ingresso, può essere di tipo elettromeccanico, oppure elettronica a circuiti integrati o a microprocessore. Un particolare conta impulsi di tipo elettromeccanico lo potresti trovare in casa tua sotto forma di interruttore per le luci di casa. Quando si hanno più di 3 punti luce da accendere/spegnere si utilizza un particolare dispositivo, il relè passo passo, che ad ogni impulso ricevuto attiva o disattiva un relè. In passato i mouse sfruttavano gli encoder ottici per contare gli spostamenti in base agli impulsi ricevuti.

Arduino e encoder - mouse
Arduino e encoder – mouse

Il circuito di adattamento del segnale di ingresso è da usare quando la tensione dell’impulso è maggiore della tensione di alimentazione del circuito integrato/microprocessore che conta gli impulsi. Un semplice partitore di tensione può essere, in molti casi, sufficiente.

Come contare i giri del motore con Arduino e un encoder

Per contare i giri di un motore dobbiamo accoppiare al rotore un encoder rotativo. Nella immagine un motore è stato dotato di un disco che alterna parti nere a parti trasparenti. Un sensore di prossimità ad infrarossi riconosce quando viene a contatto con una superficie nera, e quando invece la superficie è trasparente (passaggio di luce).

Arduino e encoder - encoder fai da te
Arduino e encoder – encoder fai da te
Arduino e encoder - sensore di prossimità a infrarossi
Arduino e encoder – sensore di prossimità a infrarossi

Si creano così degli impulsi di luce che, attraverso il sensore di prossimità, diventano impulsi elettrici. Se conti gli impulsi puoi calcolare la posizione angolare del disco, e di conseguenza del rotore (la parte che gira del motore).

Per calcolare la velocità basta contare gli impulsi ogni TOT di tempo, utilizzando un timer. Facendo un esempio pratico possiamo ipotizzare che il disco ha 36 spicchi colorati di nero e 36 di trasparente. Questo significa che, per ogni giro completo dell’asse del motore, la fotocellula (sensore di prossimità ad infrarossi) genera 36 impulsi elettrici. Se nell’intervallo di tempo di 1 secondo conto 360 impulsi significa che il motore ha compiuto 10 giri in un secondo (600 RPM giri per minuto).

Così facendo conosciamo la velocità, ma non la direzione con cui gira il motore. Per sapere anche questo dobbiamo avere due fotocellule, messe in due posizioni diverse. Quando il perno dell’encoder viene ruotato si formano due segnali elettrici in quadratura, definiti così perchè sono sfasati tra loro di 90° elettrici. Questi due impulsi forniscono la velocità, con cui ruota il perno, ma anche la direzione calcolata “vedendo” quale dei due impulsi arriva prima dell’altro. I segnali vengono chiamati A e B.

Arduino e encoder - segnale elettrico a quadratura
Arduino e encoder – segnale elettrico a quadratura

Come programmare Arduino per usare un encoder

Abbiamo visto che i due segnali elettrici A e B vanno “interpretati”.

Se sei interessato a misurare solo la velocità/spostamento del motore basta contare il totale degli impulsi in un dato arco di tempo.

Se ti serve conoscere anche la direzione dello spostamento allora dovrai misurare sia il numero degli impulsi, sia la fase tra gli impulsi A e B.

In alcuni casi non serve calcolare la velocità, ma solo di quale quantità è stato ruotato il perno di un encoder. In questi casi non serve tenere conto del tempo trascorso, e questo semplifica il programma di Arduino. Ci sono almeno due modi per rilevare il numero degli impulsi prodotti da un encoder:

  • con il metodo “polling”: ogni TOT tempo (una quantità di tempo definita a priori nel programma) si misura lo stato elettrico dei pin di ingresso a cui è collegato l’encoder. Si decodifica lo stato che varia nel tempo e si estrapola l’informazione. Con questo metodo si deve decidere a priori, ed in base al tipo/velocità del segnale elettrico, il timer che “sveglia” la misura dello stato dei segnali elettrici. Si possono perdere scatti/spostamento perchè il microprocessore sta eseguendo altre parti del programma. Si possono utilizzare indistintamente tutti i pin della scheda Arduino.
  • con il metodo “interrupt”: ogni volta che all’ingresso del pin c’è una variazione del segnale elettrico viene chiamata una funzione speciale “interrupt” (alle volte definita ISR). Questa funzione è speciale perchè ha la priorità massima, cioè il microprocessore della scheda Arduino ferma la riga di comando che sta eseguendo per eseguire la funzione “interrupt”. Si devono utilizzare solo i pin che possono diventare interrupt hardware: per esempio nella scheda Arduino UNO solo il pin 2 e 3 digitali sono fisicamente collegati agli interrupt esterni INT0 (digital pin 2) e INT1 (digital pin 3). Nel caso vuoi utilizzare un qualsiasi pin della scheda Arduino UNO allora puoi usare una libreria chiamata PinChangeInt.

il diagramma temporale delle variazioni del segnale elettrico di un encoder incrementale a quadratura le vedi nella figura che segue. CW significa senso orario, mentre CCW significa senso anti-orario:

arduino e encoder - segnale elettrico encoder a quadratura
arduino e encoder – segnale elettrico encoder a quadratura

 

Schema elettrico ARDUINO senza e con de-bounce

Lo schema più semplice è utilizzare il rotary encoder direttamente collegato ai pin digitali 2 e 3 della scheda Arduino (attivando le resistenze di pull-up). Se si ha la possibilità è meglio implementare il circuito di de-bounce che elimina i falsi contatti, i quali possono provocare un conteggio errato degli impulsi dell’encoder (consigliato).

Arduino e encoder - collegamento elettrico pratico
Arduino e encoder – collegamento elettrico pratico

 

Il circuito dell’immagine che segue ha due versioni di de-bounce. A sinistra quella più elaborata che utilizza un filtro RC. A destra vengono utilizzati dei solo condensatori. Dalle mie prove pratiche è risultato sufficiente un solo condensatore da 10nF tra pin 2 e GND, e pin 4 e GND.

arduino e encoder - schema elettrico con debounce
arduino e encoder – schema elettrico con debounce

PROGRAMMA Arduino per calcolare il numero di impulsi encoder con metodo “interrupt”

Propongo un programma per Arduino UNO che ho utilizzato con un encoder ALPS dotato di pulsante.

Ogni volta che viene ruotato l’encoder i segnali elettrici cambiano in funzione del verso di rotazione. Nelle due immagini che seguono ho rappresentato il diagramma temporale. Le frecce indicano la variazione del segnale. Il programma utilizza i pin 2 e 4 per calcolare gli scatti dell’encoder, ed il pin 3 per rilevare l’attivazione del pulsante. I segnali elettrici provenienti dall’encoder rotativo sono filtrati con 3 condensatori ceramici da 10 nF (nano Farad) collegati tra i pin 2, 3 e 4 e il pin GND della scheda Arduino.

Ogni volta che viene ruotato l’encoder il programma invia il totale aggiornato degli scatti effettuati sulla porta seriale. Ogni volta che viene premuto il pulsante viene scritto sulla porta seriale “pulsante premuto” e viene azzerato il totale degli scatti. Puoi vedere cosa succede attivando il “Monitor seriale” nella IDE, interfaccia di programmazione, di Arduino.

Arduino e encoder - segnale elettrico scatto ORARIO
Arduino e encoder – segnale elettrico scatto in senso ORARIO

 

Arduino e encoder - segnale elettrico scatto ANTI ORARIO
Arduino e encoder – segnale elettrico scatto in senso ANTI ORARIO

 

// Programma che utilizza un rotary encoder a quadratura
// il pin A dell'encoder va collegato al pin 2 di Arduino
// il pin B dell'encoder va collegato al pin 4 di Arduino
// il pin del pulsante va collegato al pin 3 di Arduino
// i rimanenti pin dell'encoder vanno collegati al pin GND di Arduino
//
// vengono utilizzati 3 condensatori ceramici da 10 nF per creare
// il circuito elettrico di de-bounce che evita i falsi contatti
//
// www.sciamannalucio.it
//
// Pin utilizzati per gli ingressi dell'encoder
#define encoder0PinA 2
#define encoder0PinSwitch 3
#define encoder0PinB 4
volatile char encoder0Pos = 0;
volatile boolean encoder0Switch = 0;
unsigned int tmp = 0;

// imposta i dati iniziali del programma
void setup() {
// I pin sono impostati come ingresso e viene
// attivata la resistenza di pull-up
// la logica è NEGATIVA
// utilizzare condensatore da 10nF tra il Pin e la GND
  pinMode(encoder0PinA, INPUT_PULLUP); 
  pinMode(encoder0PinB, INPUT_PULLUP);
  pinMode(encoder0PinSwitch, INPUT_PULLUP);
// Il pin attiva l'interrupt hardware sul fronte di salita
  attachInterrupt(digitalPinToInterrupt(encoder0PinA), doEncoderA, RISING);
// Il pin attiva l'interrupt hardware sul fronte di salita
  attachInterrupt(digitalPinToInterrupt(encoder0PinSwitch), doSwitch, RISING);
// Attiva la comunicazione seriale 115200 baud
  Serial.begin (115200);
}

void loop(){
  // Ogni volta che l'encoder fa uno scatto
  // entra nel IF e invia alla seriale lo stato dell'encoder
  if (tmp != encoder0Pos) {
    Serial.println(encoder0Pos, DEC);
    tmp = encoder0Pos;
  }
  if (encoder0Switch) {
    Serial.println("Pulsante premuto");
    encoder0Switch = 0; // riarma il trigger del pulsante
    encoder0Pos = 0; // azzera il contatore degli impulsi di rotazione
  }
}
// Il pin A dell'encoder ha variato il suo stato elettrico
void doEncoderA(){
  if(digitalRead(encoder0PinB)) encoder0Pos--;
    else encoder0Pos++;
}
// Il pin abbinato al pulsante dell'encoder ha variato il suo stato elettrico
void doSwitch(){
  encoder0Switch = 1;
}

Mappatura Pin di un encoder rotativo con pulsante

Vista dall’alto di un rotary encoder con l’associazione tra il nome del Pin e la sua posizione.

Arduino e encoder - mappatura pin di un encoder rotativo con pulsante
Arduino e encoder – mappatura pin di un encoder rotativo con pulsante

vista di lato dell’encoder rotativo.

Arduino e e ncoder - pin rotary encoder con pulsante
Arduino e e ncoder – pin rotary encoder con pulsante

Schema elettrico SENZA utilizzare Arduino

E chi non vuole utilizzare Arduino come fa? Ci sono circuiti integrati che fungono da contatore di impulsi. Puoi vedere il circuito elettrico utilizzabile anche con un encoder a quadratura. Gli integrati utilizzabili sono il 74190 (versione con uscita BCD per collegamento diretto a display decimali) e 74191 per uscita binaria e puoi scaricare cliccando sul link datasheet_74190_191_counter. Questi integrati sono in tecnologia TTL e pertanto vanno alimentati con una tensione di 5 Volt. Se vogliamo utilizzare una tensione di alimentazione fino a 15 Volt usiamo gli integrati CMOS datasheet_cd40192_cd40193. Questo circuito può essere utilizzato per dividere la frequenza di un encoder per un numero che varia tra 2 e 256, basta collegarsi alle uscite U1-Q0 (divisione per 2), U1-Q1 (divisione per 4), U1-Q2 (divisione per 8), U1-Q3 (divisione per 16), U2-Q0 (divisione per 32), U2-Q1 (divisione per 64), U2-Q2 (divisione per 128) e U2-Q3 (divisione per 256). Si devono utilizzare gli integrati con uscita binaria 74191 oppure cd40193.

Arduino e encoder - schema elettrico versione senza microprocessore
Arduino e encoder – schema elettrico versione senza microprocessore

Segnali elettrici di un rotary encoder

Ho usato l’oscilloscopio per vedere, nella pratica, come le tensioni e i segnali elettrici di un encoder rotativo cambiano in funzione di come viene girata la sua manopola.

Il rotary encoder è girato in senso orario con un movimento lento. Il segnale elettrico A da zero diventa 5 Volt. Passati 5 millisecondi anche il segnale B diventa 5 Volt. Tutti i segnali sono a logica positiva. Quando utilizzate Arduino e i resistori di pull-up contenuti nei pin la logica diventa negativa, cioè i segnali passano da 5 Volt a zero.

Arduino e encoder - segnale elettrico CW lento
Arduino e encoder – segnale elettrico CW lento

Il rotary encoder è girato in senso orario con un movimento veloce. Nello stesso tempo del caso precedente, avvengono 15 variazioni di segnale, che corrispondono ad altrettanti scatti dell’encoder totativo.

Arduino e encoder - segnale elettrico CW veloce
Arduino e encoder – segnale elettrico CW veloce

Qui vediamo un ingrandimento temporale del segnale elettrico più veloce.

Arduino e encoder - segnale elettrico CW veloce ingrandimento
Arduino e encoder – segnale elettrico CW veloce ingrandimento

In questo caso l’encoder rotativo l’ho girato in senso anti-orario. Puoi verificare come la teoria è confermata: il segnale B arriva prima, temporalmente parlando, del segnale A.

Arduino e encoder - segnale elettrico CCW lento
Arduino e encoder – segnale elettrico CCW lento

Link a risorse di approfondimento:


Pubblicità

Autore dell'articolo: Lucio Sciamanna

Lascia un commento