Wir müssen ja nicht gleich mit Kanonen auf Spatzen schießen: Ggf. könnte sich aber langfristig eine Bibliothek um den rotary kümmern, mal als erste Sammlung:
Danke Clemens. Bei Bisherige ESP32Servo-Bibliothek mit der im Arduino-Bibliotheksverwalter ersetzen haben wir gesehen, dass Kevin Harrington die ESP32Servo-Bibliothek qualitativ hochwertig vorantreibt und pflegt.
Genauso verhaelt es sich auch bei der Bibliothek GitHub - madhephaestus/ESP32Encoder: A Quadrature and half quadrature PCNT peripheral driven encoder library supporting 10 encoders, sie ist ebenfalls auf Platform.IO bei ESP32Encoder by Kevin Harrington verfuegbar.
Ich wuerde dieser Bibliothek also tendenziell den Vorzug geben, auch ohne die anderen Module vorher speziell unter die Lupe genommen zu haben.
@clemens @RoSch Ich kann das bei mir auch (mit Gewalt) nachstellen. Wenn ich heftig am Rad drehe, verpasst der Rotary ab und an einen Tick und bleibt auf einer nicht durch 5 teilbaren Zahl stehen. Beim nächsten Dreh nach rechts/links wird das aber korrigiert.
Ist das bei euch anders?
@Andreas Die ESP32Encoder habe ich in einem Test-Code, die ist gut. Alle anderen 4-12 Libraries, die ich ausprobiert habe, waren Mist. Daher auch die “eigene” Implementierung.
Das Problem mit dem ESP32Encoder ist, dass er nicht im Hintergrund verschiedene virtuelle Regler mit verschiedenen Schrittweiten zählt, so wie es der Hanimandl macht. Da ist der Portierungsaufwand höher als initial gedacht.
So heftig, wie Du schreibst, brauche ich nicht am Rotary zu drehen, um den unerwünschten Effekt beobachten zu können, insbesondere feststellbar schon bei der Auswahl der 1. Ebene im Setup-Modus …
Am Wochenende habe ich wieder Zeit, mir das auch im Programmcode genauer ansehen zu können und werde dann berichten.
Hast du das mit unterschiedlichen Encodern getestet? Du bist der Erste, der das meldet.
Bei mir ist das anders, wenn der mal “verrutscht” ist bleibt die Abweichung bestehen. Drehen nach links / rechts änder nichts, sondern erhöht oder reduziert das Gewicht nur um 5 g im “falschen” Raster. Als workaround muss ich auf das Minimum 30 g zurückdrehen, da wird der Wert dann korrigiert und wieder bis 500 g raufdrehen.
Dass in der Anzeige mal ein nicht x0 / x5-Wert stehn bleibt und beim nächsten Drehen korrigiert wird habe ich gerade 1x beim Testen gesehen, ist mir bisher allerdings nicht aufgefallen, ggf. ein anderes Problem oder Teilproblem, das seltener auftritt?
Unschöne Erkenntnis nach längeren Tests:
Die ESP32Encoder ist für Quadrature Encoder, unser KY-040 ist ein Gray-Code Encoder. Das funktioniert also nur bedingt, jede Drehung führt zu zwei Sprüngen. Das beschreibt der Entwickler auch genau so: Double count in example · Issue #28 · madhephaestus/ESP32Encoder · GitHub
Prinzipiell geht das, aber jede Änderung an der Library könnte sich anders verhalten. Das scheint mir keine Option.
Der Encoder selbst ist vermutlich ein PEC11L Rotary Encoder. Der ist nur spezifiziert bis 60rpm!
Bei der Geschwindigkeit dürfte nix passieren
Ich habe keine Gray Code Library für den ESP32 gefunden, die nicht auf Interrupts setzt.
Im oben verlinkten PEC11L datasheet steht:
Quadrature Output Table
Doch ein Quadrature Encoder? Kenn mich bisher bei Encodern gar nicht aus und weiß nicht, was die Elektronik auf “unserem” KY-040 macht. [edit] nicht der KY-040, ggf. aber ähnlich: Ollie's Workshops: Rotary Encoder with Switch da sind auf dem Platinchen nur ein paar Widerstände und eine (LE)Diode.
There are a large number of mechanical rotary encoders available on Amazon, eBay, and Aliexpress. Some of them are plain encoder switches and some of them have the pull-up resistors on a small breakout board. The pull-up resistors are not required because most MCUs can be configured to use internal pull-up resistors.
Bist du sicher, dass beim KY-040 ein PEC11L verbaut ist oder wie ist da die Quellenlage?
Unter GitHub - Billwilliams1952/KY-040-Encoder-Library---Arduino: Arduino library for the KY-040 Encoder wird für den KY-040 ein cap auf der clock line empfohlen:
The KY-040 encoder library uses interrupts on the clock line. Because of switch bounces, a 470 nF (0.47 uF) capacitor is required on each encoder clock (CLK) pin to ground.
Falls du @RoSch einen Kondensator im Bereich 470 nF rumliegen hast wäre es prima, wenn du testen könntest, ob das Problem damit immer noch auftritt.
Noch etwas in Richtung Hardware von Ollie's Workshops: Rotary Encoder with Switch :
In case of a metal shaft and a metal knob, the static charge can cause additional problems.
Verwendest du den Rotary mit knob oder drehst du momentan direkt an der Achse? Falls ja und du einen Knopf da hast, versuche dem mal zu verwenden. Der auf der Teileliste verlinkte KY-040 hat einen Metall-Knopf, ist innen aber aus Konststoff, d.h. mit dem Knopf sollte statische Aufladung weniger ein Problem sein.
Vermutlich variiert das auch je nach Hersteller… Der Bug-Report hier beschreibt aber genau das Verhalten: Double count in example · Issue #28 · madhephaestus/ESP32Encoder · GitHub
Ich hab auch keinen Plan von Binary, Quadruple oder Gray Code Encodern und glaube dem Autor einfach.
Lässt sich auch gerne mit dem Beispiel aus der Library nachstellen.
Der wesentliche Vorteil der ESP32Encoder Library ist übrigens, dass sie genau nicht mit Interrupts arbeitet sondern den Hardware Pulse Counter nutzt. Bisher habe ich keine andere Library gefunden, die das so macht.
Der Grund ist wahrscheinlich, dass nur der ESP32 eine solche Einheit besitzt?
- Pulse Counter Sensor — ESPHome
- Pulse Counter (PCNT) - ESP32 - — ESP-IDF Programming Guide latest documentation
Mit Interrupts wird aber dennoch gearbeitet, nicht? Nur muss man halt im Userspace nicht mehr jeden Rotary-Impuls per Interrupt auswerten sondern der Pulse Counter stellt Highlevel-Events zur Verfuegung, die dann per Interrupts signalisiert werden?
Die Doku der NodeMCU Firmware beschreibt das besser:
Kevin Harrington empfiehlt das ebenfalls:
Was der Autor hier anspricht ist ein Feature, das die Pulse Counter Einheit des ESP32 bereits ab Werk ermoeglicht (siehe filtering pulses) und der Treiber bereits entsprechend ansteuert.
Ob das in der Praxis jedoch wirklich ausreichend gut klappt, kann wahrscheinlich @weef besser bewerten.
vielleicht mal diese lib hier ansehen, die könnte mehrere Probleme auf einmal erledigen und dabei sogar noch gesuchte features mitbringen:
This is an adaptation of Ben Buxton’s excellent rotary library and implements additional features for encoder rotation speed.
Features
- Debounce handling with support for high rotation speeds
- Correctly handles direction changes mid-step
- Checks for valid state changes for more robust counting and noise immunity
- Interrupt based or polling in loop()
- Counts full-steps (default) or half-steps
- Calculates speed of rotation
Auch wenn der Autor im April 2020 noch jene Aussagen trifft, die darauf hindeuten, dass der KY-040 unterstuetzt wird
- https://github.com/madhephaestus/ESP32Encoder/issues/11
- E (33) pcnt: pcnt_get_counter_value(132): PCNT UNIT ERROR · Issue #14 · madhephaestus/ESP32Encoder · GitHub
simmt wohl aktuell definitiv die zitierte Aussage vom Juli 2020
die von @aholzhammer bei Probleme mit dem KY-040 rotary encoder: Gewicht springt auf Werte ausserhalb der 5 g-Schritte - #12 by aholzhammer zusammengefasst wurde:
Die von @weef vorgeschlagene Bibliothek GitHub - MajicDesigns/MD_REncoder: Rotary Encoder Library waere also wohl mindestens einen Versuch wert. Danke!
Marc Wetzel hat bei einer der oben von @clemens genannten Bibliotheken bereits etwas beigetragen.
- Implement "steps" for different types of encoders · Issue #10 · igorantolic/ai-esp32-rotary-encoder · GitHub
- My "encoderSteps" implementation as a pull request by ImkereiWetzel · Pull Request #11 · igorantolic/ai-esp32-rotary-encoder · GitHub
Aenderungen an der Firmware selbst aus seiner Feder konnte ich jedoch nur folgende entdecken:
-
Zwischenstand - neue Button-Routinen (AceButton Library)
Update hani-mandl.ino · ImkereiWetzel/hani-mandl@320278e · GitHub -
First stage of further refactoring - extracted poti, new button lib (take care only – half implemented)
Update hani-mandl.ino · ImkereiWetzel/hani-mandl@efef210 · GitHub
Gerade eben lief mir noch jene Bibliothek ueber den Weg. Ob sie auch fuer den ESP32 geeignet ist, weiss ich nicht.
Edit: Scheinbar unterstuetzt sie aber auch kein Debouncing, daher bleibt sie wohl weiter hinten in der Auswahl.
Habe jetzt nochmal geschaut und man findet einfach keine eindeutige Angabe: Mal wird der KY-040 explizit als Gray-Code Encoder beschrieben, mal explizit als Quadrature Encoder, hmm!
Ein Encoder mit zwei z.B. Schleifern und um die Hälfte ihrer Breite versetzten (und im Bogenmaß) gleichgroßen Kontaktflächen kodiert vier verschiedene Zustände. Signaltechnisch ist dies eine Phasenverschiebung um 90°, im Zeigermodell liegen diese vier Zustände in den vier Quadranten. Ihre Kodierung erfolgt im 2-bit-Gray-Code - somit ist dieser Encoder gleichzeitig ein Quadratur- als auch ein (2 bit) Gray-Code-Encoder! ;)