Inhoudsopgave:

Een complete Arduino-rotatieoplossing: 5 stappen
Een complete Arduino-rotatieoplossing: 5 stappen

Video: Een complete Arduino-rotatieoplossing: 5 stappen

Video: Een complete Arduino-rotatieoplossing: 5 stappen
Video: How to use up to 10 push button switch with 1 Arduino input pin ANPB-V1 2024, November
Anonim
Een complete Arduino roterende oplossing
Een complete Arduino roterende oplossing

Roterende encoders zijn draaibare bedieningsknoppen voor elektronische projecten, die vaak worden gebruikt met microcontrollers uit de Arduino-familie. Ze kunnen worden gebruikt om parameters fijn af te stellen, door menu's te navigeren, objecten op het scherm te verplaatsen en allerlei soorten waarden in te stellen. Het zijn veel voorkomende vervangingen voor potentiometers, omdat ze nauwkeuriger en oneindiger kunnen worden gedraaid, ze verhogen of verlagen één discrete waarde per keer, en vaak geïntegreerd met een drukbare schakelaar voor selectiefuncties. Ze zijn er in alle soorten en maten, maar de laagste prijsklasse is moeilijk om mee te communiceren, zoals hieronder wordt uitgelegd.

Er zijn talloze artikelen over de werkdetails en gebruiksmodi van roterende encoders, en talloze voorbeeldcodes en bibliotheken over hoe ze te gebruiken. Het enige probleem is dat geen van hen 100% nauwkeurig werkt met de laagste prijsklasse Chinese roterende modules.

Stap 1: roterende encoders binnen

Roterende encoders binnen
Roterende encoders binnen
Roterende encoders binnen
Roterende encoders binnen
Roterende encoders binnen
Roterende encoders binnen

Het roterende gedeelte van de encoder heeft drie pinnen (en nog twee voor het optionele schakelgedeelte). De ene is common ground (zwarte GND), de andere twee zijn voor het bepalen van de richting wanneer de knop wordt gedraaid (ze worden vaak blauwe CLK en rode DT genoemd). Beide zijn aangesloten op een PULLUP-ingangspin van de microcontroller, waardoor het niveau HOOG hun standaardwaarde is. Wanneer de knop naar voren (of met de klok mee) wordt gedraaid, daalt eerst de blauwe CLK naar niveau LOW, dan volgt de rode DT. Als we verder draaien, stijgt de blauwe CLK terug naar HOOG, en als de gemeenschappelijke GND-patch beide verbindingspinnen verlaat, stijgt de rode DT ook terug naar HOOG. Zo voltooit u één volledig vinkje FWD (of met de klok mee). Hetzelfde geldt de andere richting BWD (of tegen de klok in), maar nu valt rood als eerste en blauw komt als laatste terug, zoals respectievelijk te zien is in de afbeeldingen op twee niveaus.

Stap 2: Ellende die voor velen echte pijn veroorzaakt

Ellende die voor velen echte pijn veroorzaakt
Ellende die voor velen echte pijn veroorzaakt
Ellende die voor velen echte pijn veroorzaakt
Ellende die voor velen echte pijn veroorzaakt
Ellende die voor velen echte pijn veroorzaakt
Ellende die voor velen echte pijn veroorzaakt

Veelvoorkomend probleem voor Arduino-hobbyisten, dat goedkope Rotary-encodermodules extra veranderingen in uitgangsniveaus stuiteren, waardoor extra en verkeerde richtingtellingen worden veroorzaakt. Dit voorkomt foutloos tellen en maakt het onmogelijk om deze modules te integreren in nauwkeurige roterende projecten. Deze extra bounces worden veroorzaakt door de mechanische bewegingen van de patches over de verbindingspinnen, en zelfs het aanbrengen van extra condensatoren kunnen ze niet volledig elimineren. Bounces kunnen overal in de volledige tekencycli verschijnen en worden geïllustreerd door real-life scenario's op de afbeeldingen.

Stap 3: Eindige-toestandsmachine (FSM)-oplossing

Eindige-toestandsmachine (FSM)-oplossing
Eindige-toestandsmachine (FSM)-oplossing

De afbeelding toont de volledige toestandsruimte van de mogelijke niveauveranderingen voor de twee pinnen (blauwe CLK en rode DT), zowel voor correcte als valse bounces. Op basis van deze toestandsmachine kan een complete oplossing worden geprogrammeerd die altijd 100% nauwkeurig werkt. Omdat er geen filtervertragingen nodig zijn in deze oplossing, is het ook de snelst mogelijke. Een ander voordeel van het scheiden van de statusruimte van de pinnen van de werkmodus is dat men zowel de polling- als de interruptmodus naar eigen inzicht kan toepassen. Polling of interrupts kunnen niveauveranderingen op pinnen detecteren en een aparte routine berekent de nieuwe status op basis van de huidige status en feitelijke gebeurtenissen van niveauveranderingen.

Stap 4: Arduino-code

Arduino-code
Arduino-code

De onderstaande code telt de FWD- en BWD-ticks op de seriële monitor en integreert ook de optionele schakelfunctie.

// Peter Csurgay 2019-04-10

// Pinnen van de draaiknop toegewezen aan Arduino-poorten

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

// Huidige en vorige waarde van de teller afgestemd door de draaiknop

int curVal = 0; int prevVal = 0;

// Zeven staten van FSM (finite state machine)

#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;

ongeldige setup() {

Serieel.begin(250000); Serial.println("Start…"); // Niveau HOOG is standaard voor alle pinnen pinMode (SW, INPUT_PULLUP); pinMode (CLK, INPUT_PULLUP); pinMode (DT, INPUT_PULLUP); // Zowel CLK als DT zullen interrupts activeren voor alle niveauwijzigingen. attachInterrupt(digitalPinToInterrupt(CLK), rotaryCLK, CHANGE); attachInterrupt(digitalPinToInterrupt(DT), rotaryDT, CHANGE); }

lege lus() {

// Bediening van de optionele schakelaar geïntegreerd in sommige roterende encoders if (digitalRead(SW)==LOW) { Serial.println ("Pressed"); while(!digitalRead(SW)); } // Elke verandering in de tellerwaarde wordt weergegeven in Serial Monitor if (curVal != prevVal) { Serial.println(curVal); prevVal = curVal; } }

// State Machine-overgangen voor CLK-niveauwijzigingen

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

// State Machine-overgangen voor DT-niveauwijzigingen

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

Stap 5: vlekkeloze integratie

U kunt in de bijgevoegde video zien dat de FSM-oplossing nauwkeurig en snel werkt, zelfs in het geval van roterende encoders met een laag bereik met verschillende sporadische bounce-effecten.

Aanbevolen: