Micropython Rotary Encoder Ky040

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
Tholo
User
Beiträge: 177
Registriert: Sonntag 7. Januar 2018, 20:36

Huhu, ich hab gerade einen extremen Hänger.
Ich nutze dieses Modul um auf einem ESP32 einen Ky040 Drehregler zu nutzen.
Das Funktioniert auch soweit, außer der SwitchButton.
Ich hab versucht diesen einfach als "normalen" Button einzubinden.

Code: Alles auswählen

from machine import Pin
from utime import sleep_ms
swbutton = Pin(35, Pin.IN, Pin.PULL_UP)

while True:
    if swbutton.value() == 0:
        print("jetzt sw button")
    else:
        sleep_ms(300)
        print("----")
        print(swbutton.value())
Leider ohne Erfolg. swbutton.value bleibt bei 0.
Die vielzähligen Beispiele nutzen die Switch Button funktion nicht. Auf C++ hab ich aber einmal diese Möglichkeit gesehen.Hier zum Beispiel
Da ich mir wünschen würde das ich Funktionen schreibe wie:
  • Click Sw Button- On/off
  • Rechts/Links drehen - Hell/dunkel
  • Click und Rechts/Links drehen - Farbe hoch/runter
Könnt ihr mir vielleicht einmal eine Inspiration geben? Ich denke das liegt am "Verhalten" des Ky040. Dieses Clockwise und CounterClockwise muss doch bestimmt zu einem "modulierten Clockwise und modulierten CounterClockwise" geschrieben werden. Aber das erklärt nicht warum der SwitchButton sein Value nicht ändert wenn ich ihn einzeln aufrufe...
mhh....
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

Kannst du die Spannung am Switch messen? Bei sowas simplen reicht dazu ja ein Multimeter.
Tholo
User
Beiträge: 177
Registriert: Sonntag 7. Januar 2018, 20:36

Also Clk und DT sind auf High und haben 3,3V außer ich dreh an eine bestimmte Stelle dann 0V. (das dürfte ja dieses Clockwise sein)
Bei dem SwButton kommt auf Betätigung 3,3V an ansonsten 0V

Der Gnd vom Multimeter ist am jeweiligen Ky 040 Pin und Plus am Breadboard

Ich hab hab auch die Polung glaub ich noch nicht verstanden

Messungstest2:
Multimeter Minus am SwButton und Multimeter Plus am Clk. 0,2V durchgänging bei Betätigung vom Button 3,3V.
Was ja Sinn macht weil Clk und DT mit 10k Ohm Wiederstand laufen.

Nur wie ich "richtig" Messe ist mir gerade nicht klar
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das klingt alles etwas rödelig. Und du hast auch einen pullup gesetzt. Weißt du wozu das gut ist? Für dein Problem ist das nicht richtig. Wenn der Schalter zu VCC anhebt, brauchst du einen pull down.

Und gemessen wird grundsätzlich mit -/schwarz/COM gegen ground. So wie du zwischen zwei Signalen macht wenig bis gar keinen sinnn (außer die sind zb differenziell. Sind deine nicht).
Tholo
User
Beiträge: 177
Registriert: Sonntag 7. Januar 2018, 20:36

Rödelig triff es sehr gut!
Ich hab einmal einen anderen Aufbau konstruiert

Wenn ich einen Pull Up Wiederstand setze bekomme ich den Switch Button zum laufen! Jipiiieh
Mit einem Pulldown allerdings nicht! Dann zeiht der Button nicht an.

Aber jetzt kommt der Knoten im Kopf. Mit dem Risiko mich völlig zum Gespött zu machen...

Ich komm noch nichtmal an der Schleife vorbei um Klick und Drehen mit einem anderen Faktor zu erhöhen.
Und wenn dann nur 1x weil er dann lastval als gleich mit mod_val ansieht...
Sorry aber is glaub ich grad schon zu spät...und ich bin ja nu nicht Umsonst Medizinpädagoge geworden :P

Würde mich trotzdem freuen wenn ihr mir mal eine Inspiration geben könnt.

Mir ist klar das es ingesamt 3 Funktionen (hier noch Schleifen) sein müssten
  • einfach Hoch und Runter mit Faktor 1
  • Klick, Halten und Drehen - hoch und runter mit Faktor 10
  • Klick (wahrscheinlich am besten mit)
    - Klick kurz - Funktion On/Off
    - Klick Lang- Funktion irgendwas
Ich muss also r.value modifizieren wenn gleichzeitig der Button gedrückt ist.
Ich hab an folgendes gedacht

Code: Alles auswählen

 elif pin_sw.value() == 0 and lastval != val:
Aber hier steigt er nicht in die Schleife ein

Code: Alles auswählen

import utime
from rotary_irq_esp import RotaryIRQ
from machine import Pin

r = RotaryIRQ(pin_num_clk=32,
              pin_num_dt=33,
              min_val=0,
              max_val=255,
              reverse=True,
              range_mode=RotaryIRQ.RANGE_WRAP)
pin_sw = Pin(34, Pin.IN)
lastval = r.value()
while True:
    val = r.value()
    if lastval != val:
        lastval = val
        print('result =', val)
        
    elif pin_sw.value() == 0:
        print("sw")
        mod_val = r.value() + 10
        if lastval != mod_val:
            lastval = mod_val
            print("mit sw", lastval)
    utime.sleep_ms(50)
Aber ich teste hier gerade nur dummes Zeug zusammen

Code: Alles auswählen

result = 1
sw
mit sw 11
result = 1
result = 2
sw
mit sw 12
result = 2
result = 3
sw
mit sw 13
result = 3
sw
mit sw 13
result = 4
sw
mit sw 14
result = 4
sw
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich wuerde fuer sowas

- den Taster per IRQ ansteuern, so das du durch deine warterei nichts verliest.
- einen Zustandsautomaten schreiben, der deine gewuenschten Interaktionen repraesentiert.

Wobei die Widerspruechlich sind. Du kannst nicht auf der einen Seite das gedrueckt halten dazu benutzen, eine Aktion auszuloesen, und gleichzeitig die Drehrate manipulieren. Denn dann gibt es immer eine Aktion, auch wenn der User "nur" schneller drehen will. Da musst du dich dann schon entscheiden. Da wuerde ich eher mit einem anderen Ansatz arbeiten, der die Drehung automatisch mit einem Speedup-Faktor belegt, der zB eine Exponential-Funktion der momentanen Geschwindigkeit ist. Drehst du langsam, drehst du praezise. Drehst du schneller, beschleuningt sich die Drehung.
Antworten