INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
KY-040 Rotary Encoder
06.01.2021, 17:12
Beitrag #1
KY-040 Rotary Encoder
Könnt ihr bitte mal meinen code anschauen.
Ich benutze IDE 1.8.13
Encoder.h aus der IDE von Paul Stoffregen ver. 1.4.1

1. Drehe ich am KY-040, so zählt er bei jedem Raster 2 Impules
2. Ist das auswerten und entprellen des Tasters am KY-040 so sinnvoll gelöst oder gibt es eine bessere Lösung?

Code:
#include <Encoder.h>

const int clk1 = 6;
const int dt1 = 5;
const int sw1 = 2;
long altePosition = 0;

Encoder meinEncoder1(dt1, clk1);

boolean sw1_pos = LOW;
boolean sw1_pos_alt = LOW;
uint32_t sw1_time = 0;
uint8_t entprellen = 50;

void setup() {
  Serial.begin(9600);
  pinMode(clk1, INPUT_PULLUP);
  pinMode(dt1, INPUT_PULLUP);
  pinMode(sw1, INPUT_PULLUP);
}

void loop() {
  long neuePosition = meinEncoder1.read();
  if (neuePosition != altePosition) {
    altePosition = neuePosition;      
    Serial.println(neuePosition);
  }
  
  sw1_pos = digitalRead(sw1);
  
  if (sw1_pos == LOW && sw1_pos_alt == HIGH && millis() - sw1_time > entprellen) {
    sw1_time = millis();
    Serial.println("Taste gedrückt");
  }
  
  if (sw1_pos == HIGH && sw1_pos_alt == LOW && millis() - sw1_time > entprellen) {
    sw1_time = millis();
    Serial.println("Taste losgelassen");
  }

   sw1_pos_alt = sw1_pos;
}


Vielen Dank für eure Hilfe
Harry

Wenn etwas nicht funktioniert -> Kondensator hinzufügenSmile
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
06.01.2021, 17:21
Beitrag #2
RE: KY-040 Rotary Encoder
Ich habe mit der Lib noch nicht gearbeitet. Es gibt aber durchaus die Möglichkeit mehrerer Impulse zwischen 2 Rastungen.

Literatur: hier und hier.

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
07.01.2021, 09:00
Beitrag #3
RE: KY-040 Rotary Encoder
Soweit ich das erinnere, kann man das Verhalten in der Library einstellen.

Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. Cool
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
07.01.2021, 11:28
Beitrag #4
RE: KY-040 Rotary Encoder
Servus!

Hab mir aus meinen Test rausgesucht, hab ich damals auf ESP-32 am laufen gehabt - hier nur der Rotary Teil

Code:
#define CLK 39
#define DT 36
#define SW 27

int counter = 0;
int currentStateCLK;
int lastStateCLK;
String currentDir ="";
unsigned long lastButtonPress = 0;

void setup() {
  
  pinMode(CLK,INPUT);
  pinMode(DT,INPUT);
  pinMode(SW, INPUT_PULLUP);

  Serial.begin(74880);

  lastStateCLK = digitalRead(CLK);
}

void loop() {

  currentStateCLK = digitalRead(CLK);

  if (currentStateCLK != lastStateCLK  && currentStateCLK == 1){

    if (digitalRead(DT) != currentStateCLK) {
      counter --;
      currentDir ="Links";
    } else {
      counter ++;
      currentDir ="Rechts";
    }

    Serial.print("Richtung: ");
    Serial.print(currentDir);
    Serial.print(" | Zaehler: ");
    Serial.println(counter);
  }


  lastStateCLK = currentStateCLK;

  int btnState = digitalRead(SW);

  if (btnState == LOW) {
    if (millis() - lastButtonPress > 50) {
      Serial.println("Gedrückt");
    }
    lastButtonPress = millis();
  }
  delay(1);
}

Gruß aus Wiener Neustadt
Toni

=================================================================
Seit die Mathematiker über die Relativitätstheorie hergefallen sind, verstehe ich sie selbst nicht mehr.

Wer Rechtschreibfehler findet darf sie behalten Big Grin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
07.01.2021, 12:01 (Dieser Beitrag wurde zuletzt bearbeitet: 07.01.2021 12:04 von Harry.)
Beitrag #5
RE: KY-040 Rotary Encoder
@Dieter
Wo muss ich da nachschauen und die Änderung vornehmen?
In der Encoder.h im Libary Verzeichnis?

@Toni
So etwas ähnliches hatte ich auch gefunden, die Erkennung der Drehrichtung war aber nicht immer richtig.

Jetzt hatte ich 2 Optionen. Die mit Lib, welche immer 2 zählt, oder ohne und Erkennungsfehler. Ich benutze jetzt die ohne, da diese inzwischen funktioniert. Der Fehler lag nicht am code sondern am Serial.print. Mein Beispiel, welches ich im Internet gefunden hatte, hatte zu viele Serial.print und daduch ist beim drehen das Timing durcheinander gekommen.

Mal sehen ob der code noch funktioniert wenn ich ihn in mein Programm einbaue oder ob es wieder Timingfehler gibt. In diesem Fall werde ich mir nach dem Tip von Dieter noch einmal die Encoder.h anschauen.

Wäre es einen Alternative clk und dt auf Interrupts zu legen falls es bei der Erkennung der Drehrichtung zu Probleme kommt oder ändert dies nichts?

Wie entprellt ihr eure Taster?
Ist das so ok oder gibt es elegantere Lösungen?

Vielen Dank für eure Anregungen, hier mein momentan funktionierender code:

Code:
int Counter = 0;
boolean Richtung;
int clk1_pin_alt;
int clk1_pin_neu;

int clk1_pin = 6;
int dt1_pin = 5;
int sw1_pin = 2;

boolean sw1_pos_neu = LOW;
boolean sw1_pos_alt = LOW;
uint32_t sw1_time = 0;
uint8_t entprellen = 50;

void setup() {
  pinMode (clk1_pin, INPUT_PULLUP);
  pinMode (dt1_pin, INPUT_PULLUP);
  pinMode (sw1_pin, INPUT_PULLUP);
  Serial.begin (115200);
  clk1_pin_alt = digitalRead(clk1_pin);
}

void loop() {
  Rotary_1();
  Taster_1_Reset();       // Entweder Zähler Reset
  Taster_1_Position();    // Oder Tasterposition abfragen mit entprellen
}

void Rotary_1() {

  clk1_pin_neu = digitalRead(clk1_pin);          // Auslesen des aktuellen Statuses
  if (clk1_pin_neu != clk1_pin_alt) {            // Überprüfung auf Änderung
    if (digitalRead(dt1_pin) != clk1_pin_neu) {  // Pin_CLK hat sich zuerst verändert
      Counter ++;
      Richtung = true;
    }
    else {                                        // Andernfalls hat sich Pin_DT zuerst verändert
      Richtung = false;
      Counter--;
    }

    Serial.print(Counter);
    if (Richtung) {
      Serial.println ("  Im Uhrzeigersinn");
    }
    else {
      Serial.println("  Gegen den Uhrzeigersinn");
    }

  }
  clk1_pin_alt = clk1_pin_neu;
}  

void Taster_1_Reset() {                               // Reset-Funktion um aktuelle Position zu speichern
    if (!digitalRead(sw1_pin) && Counter != 0)
  {
    Counter = 0;
    Serial.println("Position resettet");
  }
}

// --- Taster Position erkennen und entprellen als Alternative zu "Taster Reset"

void Taster_1_Position() {
  sw1_pos_neu = digitalRead(sw1_pin);
  
  if (sw1_pos_neu == LOW && sw1_pos_alt == HIGH && millis() - sw1_time > entprellen) {
    sw1_time = millis();
    Serial.println("Taste gedrückt");
  }
  
  if (sw1_pos_neu == HIGH && sw1_pos_alt == LOW && millis() - sw1_time > entprellen) {
    sw1_time = millis();
    Serial.println("Taste losgelassen");
  }

  sw1_pos_alt = sw1_pos_neu;
}

Wenn etwas nicht funktioniert -> Kondensator hinzufügenSmile
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
07.01.2021, 12:28 (Dieser Beitrag wurde zuletzt bearbeitet: 07.01.2021 12:31 von Tommy56.)
Beitrag #6
RE: KY-040 Rotary Encoder
Hast Du Dir mal die beiden von mir verlinkten Abhandlungen zu Encodern angeschaut? Damit habe ich bisher ohne Lib alle zum Laufen bekommen.

Gruß Tommy

Edit: Beispiel
Code:
// Rotary encoder example.
// Author: Nick Gammon
// Date:   24th May 2011

// Wiring: Connect common pin of encoder to ground.
// Connect pins A and B (the outer ones) to pins 2 and 3 (which can generate interrupts)

volatile boolean fired = false;
volatile long rotaryCount = 0;

// Interrupt Service Routine
void isr () {

  static boolean ready;
  static unsigned long lastFiredTime;
  static byte pinA, pinB;  

// wait for main program to process it
  if (fired) return;
  
  byte newPinA = digitalRead (2); // DT
  byte newPinB = digitalRead (3); // CLK

// Forward is: LH/HH or HL/LL
// Reverse is: HL/HH or LH/LL

// so we only record a turn on both the same (HH or LL)

  if (newPinA == newPinB) {
    if (ready) {
      long increment = 1;
      
      // if they turn the encoder faster, make the count go up more
      // (use for humans, not for measuring ticks on a machine)
      unsigned long now = millis ();
      unsigned long interval = now - lastFiredTime;
      lastFiredTime = now;
    
      if (interval < 10) increment = 3; // 5
      else if (interval < 20) increment = 2; // 3
      else if (interval < 50) increment = 1; // 2
      
      if (newPinA == HIGH) { // must be HH now
        if (pinA == LOW) rotaryCount += increment;
        else rotaryCount -= increment;
      }
      else {                  // must be LL now
        if (pinA == LOW) rotaryCount -= increment;
        else rotaryCount += increment;        
      }
      fired = true;
      ready = false;
    }  // end of being ready
  }  // end of completed click
  else ready = true;
  
  pinA = newPinA;
  pinB = newPinB;
}  // end of isr


void setup () {
  
// hat schon 10K nach VCC auf der Platine
// je 1 100 nF von CLK und DT nach GND

//digitalWrite (2, HIGH);   // activate pull-up resistors
//digitalWrite (3, HIGH);

attachInterrupt (0, isr, CHANGE);   // pin 2
attachInterrupt (1, isr, CHANGE);   // pin 3

Serial.begin (115200);
Serial.println("Start");
}  // end of setup

void loop () {

if (fired) {
   Serial.print ("Count = ");  
   Serial.println (rotaryCount);
   fired = false;
}  // end if fired

}  // end of loop

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
07.01.2021, 15:43
Beitrag #7
RE: KY-040 Rotary Encoder
(07.01.2021 12:28)Tommy56 schrieb:  Hast Du Dir mal die beiden von mir verlinkten Abhandlungen zu Encodern angeschaut?

Hatte ich mir angeschaut, aber einiges davon noch nicht verstanden. Aus diesem Grund habe ich erst einmal andere Lösungsansätze versucht. Mir ist es wichtig, dass ich die Beispiele die ich übernehme auch verstehe. Werde mich zu späterer Zeit aber noch einmal damit auseinander setzen.

Was bedeuted dies?

// hat schon 10K nach VCC auf der Platine
// je 1 100 nF von CLK und DT nach GND

Wo die 2 x 100nF hinkommen habe ich verstanden und diese sind vermutlich zum entprellen.
Das mit den 10K verstehe ich aber nicht.

Harry

Wenn etwas nicht funktioniert -> Kondensator hinzufügenSmile
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
07.01.2021, 15:48
Beitrag #8
RE: KY-040 Rotary Encoder
Mein Encoder hat jeweils von A,B, SW einen 10 kOhm Widerstand gegen + (5V) schon auf der Platine drauf. Wenn Deiner das nicht hat, kannst Du ja welche ran löten.
Die bilden jeweils mit den 100nF ein RC-Glied zum Entprellen.

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Encoder in Lüftersteuern integrieren Hilbus 8 655 05.02.2021 16:18
Letzter Beitrag: Hilbus
  Konflikt bei Rotary Encoder Karl Stanger 9 674 02.01.2021 13:39
Letzter Beitrag: hotsystems
  Rotary Encoder und I2C Display gleichzeitig verwenden BenGroll 3 1.113 27.07.2020 10:23
Letzter Beitrag: hotsystems
  7 Segment Display mit Rotary Encoder SA154 2 928 26.05.2020 13:40
Letzter Beitrag: MicroBahner
  Konfiguration i2c Encoder Igom 4 1.143 01.03.2020 13:23
Letzter Beitrag: bytecook
  Rotary Encoder - gedrückt und gleichzeitig drehen Gerdchen03 6 1.511 29.10.2019 10:49
Letzter Beitrag: Tommy56
  Menue und klick-Encoder bojojo 2 1.702 23.11.2018 13:46
Letzter Beitrag: bojojo
  Probleme mit Umstellung von Tastern auf Encoder MasterOfPuppets 5 1.787 09.11.2018 22:29
Letzter Beitrag: hotsystems
Wink per Rotary Encoder Bewegungsmelder aktivieren Davidsen74 34 8.064 09.03.2017 18:17
Letzter Beitrag: Davidsen74
  Dc Getriebemotor mit encoder clemens5555 3 2.982 12.02.2017 14:07
Letzter Beitrag: Binatone

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste