Debounced Rotory Encoder - AZ-Delivery

Aangezien onze klanten herhaaldelijk vragen hebben gesteld over de uitvoering van de koppelpulser (digitale Poti) willen we hier kort laten zien dat we een schoon signaal van de koppelpulser via onderbrekingen kunnen afgeven.Hier in het voorbeeld op de seriële monitor:

Circuit:

Onderdelen:

 

Arduino Sketch.

/*
*Rotary Encoder verbonden met een Microcontroller, compatibel met Arduino Uno R3
*
*Coder Pins: CLK, DT, SW, +, GND
*De encoder bevat twee pull-up weerstanden van 10k bij CLK en DT
Alle contacten zijn laag-actief
*
*Programma gebaseerd op software van Stefan Nikolaus
*http://www.nikeoutlet.com/
*en belangrijke code geschreven door rafbuff op http://speelplaats.arduino.cc/Main/RotarEncoders
*"Een andere onderbroken Bibliotheek die ECHT werkt (de codeer onderbreekt de processor)
"en debons alsof er geen morgen is."
*
*Pins 2 en 3 worden gebruikt omdat ze interrupts ondersteunen!
*Debanking werkt echt geweldig!!!
*Wiskunde.positieve telling: DT op 3, CLK op 2
*Klokgewijs tellen: DT op 2, CLK op 3
*
*Wijzigingen:
*-verwijderde'unprintable'karakters, gewijzigd {}en TAB's
* -toegevoegd de button detectie voor pin 4 "SW"
* -toegevoegde actionButton() en actionPosition(); hier kunnen we de
*code voor verdere verwerking in ons systeem.
*
*UKA 31.05.2018
*/


"35; definieer encodrPinA 2
"35; definieer encodrPinB 3
"35; definieer SW 4


vluchtige unsigned int encodrPos= 0; een teller voor de dial
unsigned int lastReportedPos = 1; // veranderingsbeheer
statisch boolean roterend = false; // debount management

int button = LOW;
int old button = LOW;

// onderbreek de routinevariabelen van de dienst
boolean A set = false;
boolean B set = false;


Vaud setup()
{
pinMode(coderPinA, INPUT);
pinMode(coderPinB, INPUT);

PinMode(SW, INPUT)


digitalWrite(encodrPinA, HOGE); //turn op pull-up weerstanden
digitalWrite (encodrPinB, HOGE); //turn op pull-up weerstanden

Interrupt(0, doEncoderA, VERANDERING); //encoder pin on interrupt 0 (pin 2)
Interrupt(1, doEncoderB, VERANDERING); //encoder pin op interrupt 1 (pin 3)

Serie.start(9600); //uitvoer naar PC Serial Monitor

-...zet in...



holle lus()
{
roterende = true; //reset van de debuncier

indien (laatst ReportedPos)= encodrPos)
{
actionPosition();
last ReportedPos = encodrPos;
}


Button = = =
digitalRead(SW);

Als de knop!De oude knop
{
actionButton();
vertraging(10);
oude knop = knop;
}

--...main lus------------------...main-lus-------...


actionButton()
{
Serie.print("Button:");
Serie.print (knop);
Serie.print ("'124;");
Serie.printin(encodrPos, DEC);
...action Button...


actionPosition()
{
Serie.print("Position:");
Serie.print(encodrPos, DEC);
Serie.print ("'124;");
Serie.println ('button');
...action position...




"Interrupted Service Routines...

//ISR Interrupt op een veranderende staat
Leeve doEncoderA()
{
als (roterende) vertraging (1);//wacht een beetje totdat het stuiteren is gedaan
indien(digitalRead(encodrPinA)Een set //debounce opnieuw
{
Een honderd!Een honderd.
// teller +1 aanpassen als A B leidt
als && & &!B u set
encodrPos += 1;
roterend = false; //geen debuncing meer totdat lus() weer slaat
}
-...do Encoder...


// ISR Interrupt op B veranderende toestand, gelijk aan A hierboven
Vavad doEncoderB()
{
indien ('roterende) vertraging (1);
als (digitalRead(encodrPinB)!B u set
{
Een honderd!honderd B;
aanpassen counter -1 als B leidt A
als u &&!Honderd dollar.
encodrPos = 1;
rotatie = vals;
}
...de EncoderB...

We hopen dat onze blog bijdrage vandaag heeft geholpen u uw probleem op te lossen en als een gedachte boost voor uw projecten en we kijken uit naar uw opmerkingen.Tot de volgende post van AZ-Delivery, uw expert in microelektronica!

 

Für arduinoSpecials

3 Reacties

Steven

Steven

https://github.com/ownprox/Rotary_Encoder_KY-040_Fixed

0 Jumping, use one with resistors built in and no need to add extra and you do not need to add a capacitor

Stefan Andres

Stefan Andres

Mit dem ESP32 (Arduino IDE) hatte ich viele Probleme den KY-040 vernünftig zum laufen zu bringen.
Ich habe einige Lib’s und Lösungen versucht, vergebens.
Der Grund: Es ist ein analoges Signal und der Interrupt wird, beim Eintreffen von CLK, mehrfach ausgelöst. Manchmal sogar einige 100 mal. Ein “debouncing” mit delay(x) bringt auch nicht wirklich eine Lösung. Kondensatoren gegen GND genau so wenig.
Nach einigen Versuchen habe ich eine Lösung mittels Schmitt Trigger gefunden:
Das Signal (clk) vom KY-040, zum Unterdrücken von Schwingungen mit einem Kondenstator (0,1µF) gegen GND an den Eingang des Schmitt Trigger (A) legen. Den Ausgang (Y) dann auf den Interrupt PIN. Damit wird die Interrupt Routine ebenfalls sehr einfach:
Nun noch einen Interrupt auf CLK Flanke “FALLING”. In der Routine brauch man nur noch DT abfragen.:
Code Auszug:
…….
volatile int16_t count=0;
uint8
t clkPin;
uint8
t _dtPin;

portMUX_TYPE mux = portMUX_INITIALIZERUNLOCKED;

void IRAM_ATTR ISR_ROTATION() {
portENTER_CRITICAL_ISR(&(mux));
if (digitalRead(
dtPin)) _count++; //CW
else count—; // CCW
portEXIT_CRITICAL_ISR(&(mux));
}
KY040::KY040(uint8_t clkPin, uint8
t dtPin, uint8
t swPin) {
// constructor code
_clkPin = clkPin;
_dtPin = dtPin;
swPin = swPin;
pinMode(clkPin, INPUT);
pinMode(dtPin, INPUT);
pinMode(swPin, INPUT);
attachInterrupt(digitalPinToInterrupt(
clkPin), ISR
ROTATION , FALLING);
….
}
…..
int16
t KY040::readEncoder() {
uint16
t c = _count;
_count = 0;
return c;
}

Analog habe ich auch den Switch gegen Prellen geschützt.

Walter van Boer

Walter van Boer

/*

Walter van Boer 12.06.2018 Further modifications: - writing error: actionposition() actionbutton() in void loop() - should be actionPosition(), actionButton() - should be: if (A_set && !B_set) in ISR void doEncoderA() -This sketch works great!
*/

Laat een reactie achter

Alle opmerkingen worden voor publicatie gecontroleerd door een moderator

Aanbevolen blogberichten

  1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
  2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
  4. ESP32 - das Multitalent - AZ-Delivery