Sommario:

Una soluzione completa per Arduino Rotary: 5 passaggi
Una soluzione completa per Arduino Rotary: 5 passaggi

Video: Una soluzione completa per Arduino Rotary: 5 passaggi

Video: Una soluzione completa per Arduino Rotary: 5 passaggi
Video: Programmare Arduino, Spiegato Facile per Tutti 2024, Dicembre
Anonim
Una soluzione completa per Arduino Rotary
Una soluzione completa per Arduino Rotary

Gli encoder rotativi sono manopole di controllo girevoli per progetti elettronici, spesso utilizzate con i microcontrollori della famiglia Arduino. Possono essere utilizzati per mettere a punto parametri, navigare nei menu, spostare oggetti sullo schermo, impostare valori di qualsiasi tipo. Sono sostituzioni comuni per i potenziometri, perché possono essere ruotati in modo più accurato e infinito, aumentano o diminuiscono un valore discreto alla volta e spesso sono integrati con un interruttore a pulsante per funzioni di selezione. Sono disponibili in tutte le forme e dimensioni, ma è difficile interfacciarsi con la fascia di prezzo più bassa come spiegato di seguito.

Esistono innumerevoli articoli sui dettagli di funzionamento e sulle modalità di utilizzo degli encoder rotativi e numerosi codici e librerie di esempio su come utilizzarli. L'unico problema è che nessuno di questi funziona in modo accurato al 100% con i moduli rotanti cinesi della fascia di prezzo più bassa.

Fase 1: Encoder rotativi all'interno

Encoder rotativi interni
Encoder rotativi interni
Encoder rotativi interni
Encoder rotativi interni
Encoder rotativi interni
Encoder rotativi interni

La parte rotante dell'encoder ha tre pin (e altri due per la parte dell'interruttore opzionale). Uno è il terreno comune (nero GND), gli altri due servono per determinare la direzione quando si gira la manopola (sono spesso chiamati blu CLK e rosso DT). Entrambi questi sono collegati a un pin di ingresso PULLUP del microcontrollore, rendendo il livello HIGH la loro lettura predefinita. Quando la manopola viene ruotata in avanti (o in senso orario), prima il CLK blu scende al livello LOW, quindi segue il DT rosso. Girando ulteriormente, CLK blu torna su HIGH, quindi quando la patch GND comune lascia entrambi i pin di connessione, anche DT rosso torna su HIGH. Completando così un tick completo FWD (o in senso orario). Lo stesso vale per l'altra direzione BWD (o in senso antiorario), ma ora il rosso cade per primo e il blu risale per ultimo, come mostrato rispettivamente nelle immagini dei due livelli.

Passaggio 2: la miseria che causa dolore reale a molti

Miseria che causa vero dolore a molti
Miseria che causa vero dolore a molti
Miseria che causa vero dolore a molti
Miseria che causa vero dolore a molti
Miseria che causa vero dolore a molti
Miseria che causa vero dolore a molti

Problema comune per gli appassionati di Arduino, che i moduli encoder rotativi economici fanno rimbalzare ulteriori cambiamenti nei livelli di uscita, causando letture del conteggio della direzione extra e errate. Ciò impedisce un conteggio impeccabile e rende impossibile l'integrazione di questi moduli in progetti rotativi accurati. Questi rimbalzi extra sono causati dai movimenti meccanici delle patch sui pin di connessione e anche l'applicazione di condensatori extra non può eliminarli completamente. I rimbalzi possono apparire ovunque nei cicli di tick completi e sono illustrati da scenari di vita reale sulle immagini.

Passaggio 3: soluzione macchina a stati finiti (FSM)

Soluzione macchina a stati finiti (FSM)
Soluzione macchina a stati finiti (FSM)

L'immagine mostra lo spazio di stato completo dei possibili cambiamenti di livello per i due pin (CLK blu e DT rosso), sia per i rimbalzi corretti che per quelli falsi. Sulla base di questa macchina a stati è possibile programmare una soluzione completa che funzioni sempre con precisione al 100%. Poiché in questa soluzione non sono necessari ritardi di filtraggio, è anche la più veloce possibile. Un altro vantaggio della separazione dello spazio di stato dei pin dalla modalità di lavoro è che è possibile applicare sia la modalità di polling che quella di interruzione a proprio piacimento. Il polling o gli interrupt possono rilevare i cambiamenti di livello sui pin e una routine separata calcolerà il nuovo stato in base allo stato corrente e agli eventi effettivi dei cambiamenti di livello.

Passaggio 4: codice Arduino

Codice Arduino
Codice Arduino

Il codice seguente conta i tick FWD e BWD sul monitor seriale e integra anche la funzione di commutazione opzionale.

// Peter Csurgay 2019-04-10

// Pin del rotary mappati alle porte Arduino

#define SW 21 #define CLK 22 #define DT 23

// Valore attuale e precedente del contatore sintonizzato dal rotary

int curVal = 0; int prevVal = 0;

// Sette stati di FSM (macchina a stati finiti)

#define IDLE_11 0 #define SCLK_01 1 #define SCLK_00 2 #define SCLK_10 3 #define SDT_10 4 #define SDT_00 5 #define SDT_01 6 int state = IDLE_11;

void setup() {

Serial.begin(250000); Serial.println("Inizio…"); // Il livello HIGH sarà l'impostazione predefinita per tutti i pin pinMode(SW, INPUT_PULLUP); pinMode(CLK, INPUT_PULLUP); pinMode(DT, INPUT_PULLUP); // Sia CLK che DT attiveranno gli interrupt per tutti i cambiamenti di livello attachInterrupt(digitalPinToInterrupt(CLK), rotaryCLK, CHANGE); attachInterrupt(digitalPinToInterrupt(DT), rotaryDT, CHANGE); }

ciclo vuoto() {

// Gestione dello switch opzionale integrato in alcuni encoder rotativi if (digitalRead(SW)==LOW) { Serial.println("Pressed"); while(!digitalRead(SW)); } // Qualsiasi cambiamento nel valore del contatore viene visualizzato in Serial Monitor if (curVal != prevVal) { Serial.println(curVal); prevVal = curVal; } }

// Transizioni della macchina a stati per i cambiamenti di livello CLK

void rotaryCLK() { if (digitalRead(CLK)==LOW) { if (state==IDLE_11) state = SCLK_01; else if (stato==SCLK_10) stato = SCLK_00; else if (stato==SDT_10) stato = SDT_00; } else { if (stato==SCLK_01) stato = IDLE_11; else if (stato==SCLK_00) stato = SCLK_10; else if (stato==SDT_00) stato = SDT_10; else if (stato==SDT_01) { stato = IDLE_11; curVal--; } } }

// Transizioni della macchina a stati per i cambiamenti di livello DT

void rotaryDT() { if (digitalRead(DT)==LOW) { if (state==IDLE_11) state = SDT_10; else if (stato==SDT_01) stato = SDT_00; else if (stato==SCLK_01) stato = SCLK_00; } else { if (stato==SDT_10) stato = IDLE_11; else if (stato==SDT_00) stato = SDT_01; else if (stato==SCLK_00) stato = SCLK_01; else if (stato==SCLK_10) { stato = IDLE_11; CurVal++; } } }

Passaggio 5: integrazione impeccabile

Puoi verificare nel video allegato che la soluzione FSM funziona in modo accurato e veloce anche nel caso di encoder rotativi di gamma bassa con vari effetti di rimbalzo sporadici.

Consigliato: