Bemerkung
Hallo, willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Community auf Facebook! Tauchen Sie mit anderen Enthusiasten tiefer in Raspberry Pi, Arduino und ESP32 ein.
Warum beitreten?
Expertenunterstützung: Lösen Sie Probleme nach dem Kauf und technische Herausforderungen mit Hilfe unserer Community und unseres Teams.
Lernen & Teilen: Tauschen Sie Tipps und Tutorials aus, um Ihre Fähigkeiten zu verbessern.
Exklusive Vorschauen: Erhalten Sie frühzeitigen Zugang zu neuen Produktankündigungen und Sneak Peeks.
Sonderrabatte: Genießen Sie exklusive Rabatte auf unsere neuesten Produkte.
Festliche Aktionen und Gewinnspiele: Nehmen Sie an Gewinnspielen und Feiertagsaktionen teil.
👉 Bereit, mit uns zu entdecken und zu gestalten? Klicken Sie auf [here] und treten Sie noch heute bei!
2.12 Drehgeber (Rotary Encoder)
Einführung
Ein Drehgeber ist ein Eingabegerät, das Drehbewegungen in digitale Signale umwandelt. Er wird häufig zum Navigieren durch Menüs, zum Einstellen von Werten oder zum Durchscrollen von Listen verwendet. In diesem Projekt verbinden Sie einen Drehgeber (mit integrierter Drucktaste) über das Fusion HAT+ mit einem Raspberry Pi, lesen die Drehschritte aus und setzen den Zähler über den Schalter des Encoders zurück.
Dieses Experiment zeigt, wie ein Drehgeber mithilfe von Event-Callbacks angebunden wird, um eine flüssige Eingabeverarbeitung mit geringer Latenz zu ermöglichen.
Benötigte Komponenten
Die folgenden Komponenten werden für dieses Projekt benötigt:
KOMPONENTE |
KAUFLINK |
|---|---|
- |
|
Raspberry Pi |
- |
Schaltplan
Die folgende Abbildung zeigt den Schaltplan für dieses Projekt:
Verdrahtungsdiagramm
Verbinden Sie die Komponenten gemäß dem folgenden Verdrahtungsdiagramm:
Pinbelegung im Beispiel
CLK → GPIO 17
DT → GPIO 4
SW (Taste) → GPIO 27 (mit internem Pull-up)
+ → 3.3V
GND → GND
Stellen Sie sicher, dass alle Verbindungen fest sitzen. Falls Ihr Encoder separate C (COM) und NO/NC-Anschlüsse für den Schalter besitzt, verbinden Sie C mit GND und NO mit dem SW-Pin (der interne Pull-up wird in der Software aktiviert).
Beispiel ausführen
Der gesamte Beispielcode für dieses Tutorial befindet sich im Verzeichnis ai-lab-kit.
Führen Sie die folgenden Schritte aus, um das Beispiel zu starten:
cd ~/ai-lab-kit/python/
sudo python3 2.12_RotaryEncoder.py
Nach dem Start des Skripts erhöht oder verringert das Drehen des Drehgebers einen Zähler, und der aktuelle Zählerwert wird in Echtzeit in der Konsole angezeigt. Wenn Sie die Taste des Encoders drücken, wird der Zähler auf Null zurückgesetzt und eine entsprechende Meldung ausgegeben. Das Programm läuft weiter und reagiert auf Benutzereingaben, bis Sie es mit Ctrl + C beenden.
Code
Unten finden Sie den Python-Code, der in diesem Projekt verwendet wird:
#!/usr/bin/env python3
from fusion_hat.pin import Pin, Mode, Pull
import time
# GPIO pins (BCM numbering)
CLK_PIN = 17
DT_PIN = 4
SW_PIN = 27
# Initialize pins with internal pull-ups
clk = Pin(CLK_PIN, mode=Mode.IN, pull=Pull.UP)
dt = Pin(DT_PIN, mode=Mode.IN, pull=Pull.UP)
sw = Pin(SW_PIN, mode=Mode.IN, pull=Pull.UP) # Button is active LOW
raw = 0 # Raw quadrature transitions
last_clk = clk.value() # Previous CLK state
last_detent = None # Last displayed detent value
print("Rotate the knob. Press the button to reset. CTRL + C to exit.")
try:
while True:
c = clk.value()
if c != last_clk:
# Direction: DT != CLK means one direction, else the other
raw += 1 if dt.value() != c else -1
# Most encoders generate 2 transitions per detent (click)
detent = raw // 2
# Only update output when the detent value changes
if detent != last_detent:
print(f"\rCounter: {detent} ", end="", flush=True)
last_detent = detent
last_clk = c
# Reset when button is pressed
if sw.value() == 0:
raw = 0
detent = 0
print("\rCounter: 0 ", end="", flush=True)
last_detent = 0
time.sleep(0.25) # Button debounce
time.sleep(0.001) # Polling interval (1 ms)
except KeyboardInterrupt:
print("\nExit")
Den Code verstehen
Importe
from fusion_hat.pin import Pin, Mode, Pull import time
Pinwird verwendet, um GPIO-Pins für den Drehgeber zu konfigurieren und auszulesen.ModeundPulldefinieren die Pin-Richtung sowie interne Pull-up-Widerstände.timewird verwendet, um Abfrageintervalle und die Entprellzeit der Taste zu steuern.
GPIO-Pin-Konfiguration
CLK_PIN = 17 DT_PIN = 4 SW_PIN = 27 clk = Pin(CLK_PIN, mode=Mode.IN, pull=Pull.UP) dt = Pin(DT_PIN, mode=Mode.IN, pull=Pull.UP) sw = Pin(SW_PIN, mode=Mode.IN, pull=Pull.UP)
CLKundDTsind die beiden Quadratur-Signalpins des Drehgebers.SWist die integrierte Drucktaste des Encoders.Interne Pull-up-Widerstände sorgen für stabile Signale, wenn der Encoder nicht bewegt wird.
Die Taste ist aktiv LOW und liefert den Wert
0, wenn sie gedrückt wird.
Statusvariablen
raw = 0 last_clk = clk.value() last_detent = None
rawzählt die niedrigen Quadratur-Übergänge des Encoders.last_clkspeichert den vorherigen CLK-Zustand, um Signaländerungen zu erkennen.last_detentmerkt sich den zuletzt ausgegebenen Zählerwert, um doppelte Ausgaben zu vermeiden.
Erkennung der Drehbewegung
c = clk.value() if c != last_clk: raw += 1 if dt.value() != c else -1
Das Skript überwacht kontinuierlich den CLK-Pin.
Eine Änderung des CLK-Signals zeigt eine Drehbewegung des Encoders an.
Die Drehrichtung wird bestimmt, indem der Zustand von DT mit CLK verglichen wird.
Berechnung der Rastposition (Detent)
detent = raw // 2
Die meisten Drehgeber erzeugen zwei Signaländerungen pro mechanischem Klick.
Durch Division durch 2 werden die Rohübergänge in saubere Rastschritte umgewandelt.
Saubere Konsolenausgabe
if detent != last_detent: print(f"\\rCounter: {detent} ", end="", flush=True)
Die Ausgabe wird nur aktualisiert, wenn sich der Zählerwert ändert.
\\rsetzt den Cursor an den Anfang der Zeile zurück, sodass der Wert an derselben Stelle überschrieben wird.flush=Truesorgt dafür, dass die Ausgabe sofort im Terminal erscheint.
Reset über die Taste
if sw.value() == 0: raw = 0 detent = 0 print("\\rCounter: 0 ", end="", flush=True) time.sleep(0.25)
Durch Drücken der Taste wird der Zähler auf Null zurückgesetzt.
Eine kurze Verzögerung dient zur Entprellung der Taste und verhindert Mehrfachauslösungen.
Abfrageintervall und Programmende
time.sleep(0.001)
Eine Abfrageverzögerung von 1 ms bietet ein gutes Gleichgewicht zwischen Reaktionsgeschwindigkeit und CPU-Auslastung.
Mit
Ctrl + Ckann das Programm jederzeit sauber beendet werden.
Fehlerbehebung
Keine Ausgabe beim Drehen
Ursache: Falsch verdrahtete CLK/DT-Pins oder schlechte Masseverbindung.
Lösung: Überprüfen Sie CLK→GPIO17, DT→GPIO4 sowie eine gemeinsame GND-Verbindung. Stellen Sie sicher, dass die Versorgung 3,3V beträgt (keine 5V-Encoder direkt an GPIO anschließen).
Zähler springt unregelmäßig (Rauschen/Prellen)
Ursache: Mechanisches Prellen oder Störungen durch lange Kabel.
Lösung: Kabel möglichst kurz halten; ggf. verdrillen; kleine Kondensatoren (z. B. 0,01–0,1 µF) zwischen CLK/DT und GND hinzufügen; falls verfügbar, Software-Entprellung aktivieren.
Taste wird nicht erkannt
Ursache: Schalterkontakte sind an 3,3V statt GND angeschlossen oder Pull-up falsch konfiguriert.
Lösung: Sicherstellen, dass SW beim Drücken mit GND verbunden wird und
pull=Pin.PULL_UPkorrekt gesetzt ist.
Drehrichtung ist vertauscht
Ursache: CLK und DT sind vertauscht.
Lösung: Tauschen Sie die CLK- und DT-Leitungen oder invertieren Sie die Schrittlogik in der Software.
Erweiterungsideen
Variable (z. B. Lautstärke oder Helligkeit) stufenlos anpassen
value = 50 # 0..100 def rotary_change(): global value value = max(0, min(100, 50 + encoder.steps())) print(f'Value = {value}')
Taste zum Umschalten eines Modus verwenden
mode = ['Fine', 'Coarse'] idx = 0 def reset_counter(): global idx idx = 1 - idx encoder.reset() print(f'Mode switched to: {mode[idx]}')
LED- oder Buzzer-Feedback
from fusion_hat import Pin led = Pin(26, Pin.OUT) def rotary_change(): print('Counter =', encoder.steps()) led.on() # kurze LED-Anzeige ohne Blockieren der Callbacks empfohlen led.off()
Langer Tastendruck für Spezialfunktionen
Die Dauer des Tastendrucks kann über Zeitstempel in
sw.when_activatedund (falls vorhanden)sw.when_deactivatederfasst werden, um unterschiedliche Aktionen für kurze oder lange Tastendrücke auszulösen.
Fazit
Dieses Experiment zeigt, wie ein Drehgeber und seine integrierte Taste mithilfe ereignisgesteuerter Callbacks mit dem Fusion HAT+ ausgelesen werden können. Mit dieser Technik lassen sich reaktionsschnelle Benutzeroberflächen wie Menü-Navigatoren, Drehregler für Einstellungen oder Jog-Wheels für Echtzeitsteuerungen in Raspberry-Pi-Projekten realisieren.