Drehimpulsgeber sind beliebte und vielseitige Eingabegeräte. Im M5-Universum gibt es leider nur einen für den M5Face. Deshalb habe ich mich drangesetzt und eine Routine für die anderen M5-Geräte entworfen. Diese ermöglicht den Einsatz eines Drehimpulsgebers mit der UIFlow-IDE und Blockly / Micropython.
Als Hardware kommt ein M5Stick C plus und ein Drehimpulsgeber von az-Delivery zum Einsatz. Der Drehimpulsgeber hat 3 Pullup Widerstände auf der Platine.
Der Drehimpulsgeber liefert 3 digitale Signale. Davon liefern zwei die Information über den den aktuellen Zustand des Drehgebers und eines den Zustand des Tasters. Im Ruhezustand liefern alle drei Signale eine 1.
Es gibt im Internet so einige Beschreibungen zum Thema Drehimpulsgeber. Einige davon basieren auf Interrupts, die zwar beim ESP32 vorhanden sind, aber in UIFlow und Blockly nicht zur Verfügung stehen. Deshalb habe ich mich für einen pragmatischen Ansatz entschieden. Ich habe die 2 Bits in eine Zahl umgewandelt und mir angeschaut was passiert. Dabei ist herausgekommen, dass im eingerasteten Zustand die Zahl 3 (0b11) ansteht. Beim Drehen bis zur nächsten Rastung entsteht entweder die Zahlenfolge 201 für vorwärts oder 102 für rückwärts. Dann steht wieder die 3 beim nächsten Rastpunkt an. Es ist also nur wichtig zu wissen welche Zahl nach der 3 kommt. Ein überschaubares Problem.
Nun gibt es aber auch noch einen Taster, der ebenfalls abgefragt werden soll. Dieser liefert im Ruhezustand 1, wenn er gedrückt wird eine 0. Deshalb habe ich eine 3-Bit-Zahl zu Grunde gelegt. Es wird dann fortlaufend der Zustand des Drehimpulgebers eingelesen. Wenn eine 7 (entspricht der 3 im obigen Absatz) eingelesen wird, wird ein Flag gesetzt. Wird eine 5 (1) eingelesen, wird geprüft, ob das Flag gesetzt ist. Wenn nicht wird der Wert ignoriert. Wenn ja, so wird das Flag zurückgesetzt und -1 ausgegeben. Bei einer 6 (2) erfolgt die selbe Prozedur, nur wird dann 1 zurückgegeben. Wenn die Zahl < 4 ist, ist der Taster gedrückt und es wird eine 0 zurückgegeben. Die anderen Werte interessieren dann nicht. Wird eine andere Zahl eingelesen, wird diese ignoriert.
Bei dieser Lösung wird das Programm blockiert, solange keine Eingabe erfolgt. Es können auch keine Tastendücke unterschiedlicher Länge identifiziert werden. Weiterhin findet keine Entprellen der Kontakte statt, so dass es gelegentlich zu falschen Werten kommt. Wenn die Impulse nicht gezählt, sondern als Zahl im Display angezeigt werden ist das zwar nicht schön, aber für Bastler m.E. aktzeptabel. Für den Anfang soll es so genügen. Spätere Verbesserungen sind ja immer möglich.
Zunächst müssen unter Setup die verwendeten Pins initialisiert werden:
Und nun das Programm:
Nach einigem hin und her funktionierte das Programm dann ordnungsgemäß. Anfangs gab das Programm zwar die Werte 1 und -1 korrekt zurück, bei der 0 wurden aber immer viele Nullen ausgegeben. Ich habe lange nach der Ursache gesucht. Schließlich stellte ich fest, dass der nächste und viele weitere Aufrufe von dig_auswerten erfolgten bevor ich den Taster wieder losließ. Deshalb habe ich die Warteschleife für die Tasterauswertung eingebaut. Nun läuft das Programm.
Einen eigenen Block erzeugen
Nun werde ich versuchen einen eigenen Block für diese Funktion zu erzeugen. Eine umfangreiche Beschreibung des Blockmaker werde ich an anderer Stelle machen. Hier nur soviel wie nötig.
Es werden drei Blöcke benötigt:
- init_dig – zum Initialisieren der Ports
- read_dig – den aktuellen 3-Bit-Wert ermitteln
- get_dig – daraus den Rückgabewert erzeugen und zurückgeben
Ich habe mich hier für englische Bezeichnungen entschieden, weil es sich dabei um die internen Bezeichnungen handelt und Englisch in der Programmierung Standard ist. Wobei dig dann in ris (rotary impuls switch) geänder werden müsste. Der Name des Blocks kann in Deutsch erfolgen.
Nachdem ich nun einige Zeit mit dem Blockmaker oder besser mit meinen mangelnden Pythonkenntnissen und einigen Nachlässigkeiten beim Testen zu kämpfen hatte, ist es mir gelungen entsprechende Blöcke zu erstellen.
Da die UIFlow-IDE die Blöcke wie Macros in den Code einfügt, ist der Block read_dig überflüssig geworden. Dessen Code habe ich gleich bei get_dig eingefügt. Die beiden übriggebliebenen Blöcke heissen jetzt init_dig und hole nächsten Impuls. Wie versprochen in deutsch.
Anwendung der Blöcke
init_dig
Wie der Name schon verrät wird mit diesem Block die Verwendung eines Drehimpusgebers initialisiert. In den Feldern pinA und pinB sind die Nummern der Pins anzugeben an denen die Anschlüsse A und B oder wie immer sie heissen mögen des Drehimpulsgebers einzutragen. Die Pinnummer des Tasteranschlusses wird bei pinT eingetragen. Das ist schon alles was zur Vorbereitung des Drehimpulsgeber Einsatzes erforderlich ist.
Hier gibt es aber einige Einschränkungen zu beachten: Es kann nur ein Drehimpulsgeber angeschlossen werden. Der Drehimpulsgeber kann nur direkt an Pins des M5-Gerätes angeschlossen werden. Ein I/O-Expander kann nicht eingesetzt werden. Weiterhin werden die drei Pins intern als Eingang und float initialisiert. Es ist also jeweils ein externen Widerstand gegen +3,3V erforderlich, so wie es bei dem von mir verwendeten Modul der Fall ist. Letzters kann leicht mit dem Blockmaker im Code geändert werden.
Da habe ich wohl schon ein neues Projekt 😉
hole nächsten Impuls
Die Impulse des Drehimpulsgebers werden einzeln geholt. Der Rückgabewert dieses Blocks ist:
- 1 = ein Schritt vorwärts
- -1 = ein Schritt rückwärts
- 0 = Taster gedrückt (erst wenn Taster losgelassen wurde)
Wobei vorwärts und rückwärts sich auf meinen Testaufbau beziehen und hängt davon ab, welche internen Schalter des Drehimpulsgebers jeweils an pinA und pinB liegen. Wenn die falsche Richtung erscheint kann man:
- die Kabel an pinA und pinB vertauschen,
- im Blockmaker die Ausgabewerte ändern oder
- die Auswertung umstellen auf -1 vorwärts und 1 rückwärts.
Wichtiger Hinweiß
Wenn Du in einem Blockly-Programm eigene Blöcke verwendest und es erneut in die IDE laden willst, so musst Du vorher die eingen Blöcke (das *.m5b-File) in die IDE laden, sonst wird das Blockly-Programm nicht geladen!
Nun viel Spaß beim Basteln.
Download
Geht noch nicht, weil WordPress den Upload der Datei noch blockiert und „WP Extra File Types“ nicht funktioniert. Ich arbeite daran.
Tipp zum Blockmaker
wenn kein Blockcode eingetragen ist speichert der Blockeditor nicht. Im Zweifelsfall hilft ein # (Kommentar) Zeichen im Codefeld.
Kontakt
Wenn Jemand sich zu diesem Beitra äußern möchte, mich auf Fehler hinweisen oder Tipps dazu geben möchte, so geht dass über die Emailadresse peter@peters-bastelkiste.de
Die Kommentar- und Diskussionsfunktion ist noch nicht freigeschaltet.
Neueste Kommentare