Meine Verssuche das CYD mit Micropython zu betreiben.

Meine ersten Versuche waren noch nicht sehr erfolgreich. Letztendlich war es mir gelungen Das Display zum Leben zu erwecken. Allerdings wurden die Farben als BGR dargestellt, was ich nicht ändern konnte.

Schließlich konnte ich das CYD nicht mehr mit Thonny erreichen und habe Micropython neu installiert. Damit waren dann aber auch alle meine bisherigen Versuche und Änderungen gelöscht.

Nun also ein neuer Anlauf.

Zuerst erstelle ich mal eine Gliederung, das hilft mir strukturierter vorzugehen und bietet die Möglichkeit meiner Ergebnisse gleich an der richtigen Stelle zu dokumentieren – bevor ich wieder MPY neu aufspiele.

Das CYD, Daten, Eigenschaften und Varianten

Micropythonspezifische Informationen zum CYD

Hier meine aktuelle Linksammlung zum Thema:

CYD Links:

Das Display

Ich möchte zuerst das Display benutzen können. Es handelt sich dabei um einen Controller ILI9341.

Hier sind die Pinbelegungen des CYD dargestellt. Für das Display ist dort folgendes aufgeführt:

disp = ili9XXX.ili9341(factor=32, double_buffer=False, clk=14, cs=15, dc=2, rst=12, power=23, backlight=21, miso=12, mosi=13,width=320, height=240, backlight_on=1, rot=ili9XXX.LANDSCAPE)

Da dort ein anderer Treiber verwendet wird sind noch weitere Parameter enthalten, die bei dem von mir verwendeten Treiber nicht vorhanden sind.

Ich habe zuerst den ili9341.py Treiber von hier ausprobiert. Ich habe ihn nach /lib auf dem ESP32 kopiert und dann mit dem Demoprogramm demo_fonts8x8_bgcolor.py getestet.

In der Initialisierungssequenz habe ich die Zeile

self.write_cmd(self.INVON)        # Ergänzt

hinzugefügt, da ich von meinen ersten Versuchen noch wusste, das das etwas gebracht hat. Es hat sich aber gezeigt, dass die Invertierung falsch war. Siehe weiter unten.

Aber auch damit erschien kein Bild. Deshalb habe ich die Anschlüsse in demo_fonts8x8_bgcolor.py überprüft. Die waren falsch. Hier die Richtigen.

In ili9341.py ist eine falsche Geometrie als Default eingetellt. Deshalb muss hier noch width und hight angegeben werden.

spi = SPI(1, baudrate=40000000, sck=Pin(14), mosi=Pin(13))
display = Display(spi, dc=Pin(2), cs=Pin(15), rst=Pin(12), width=320, height=240)

Auch das zeigte kein Bild. Es fiel mir aber auf, das die Hintergrundbeleuchtung des Displays nicht leuchtete. Deshalb habe ich Pin21 manuell eingeschaltet:

bl = machine.Pin(21, machine.Pin.OUT)
bl.on()

Und siehe da, das Display wurde hell und test() zeigte etwas an!

Nun habe ich die folgenden Zeilen in der REPL eingegeben:

spi = SPI(1, baudrate=40000000, sck=Pin(14), mosi=Pin(13))
display = Display(spi, dc=Pin(2), cs=Pin(15), rst=Pin(12), width=320, height=240)
display.draw_text8x8(100, 120, "sollte Grün sein!", color565(0, 255, 0))

Der Text wurde angezeigt, aber in Lila. Außerdem enthält der Default 8×8 Font kein ü, es wird wohl der aus dem MPY Framebuffer sein.

Da Lila die Komplementärfarbe zu Grün ist war wohl die Invertierung falsch. Nachdem ich diese Zeile auskommentiert hatte wurde der Text auch Grün angezeigt.

Display ON/OFF

In der __init__ Methode von Display in ili9341.py steht in Zeile 171:

self.write_cmd(self.DISPLAY_ON)

Ich hatte angenommen, dass damit das Display eingeschaltet wird. Das passiert auch, aber die Hintergrundbeleuchtung hat damit nichts zu tun! Diese muß extra eingeschaltet werden:

bl = Pin(21, Pin.OUT)
bl.on()

Statt on/off kann man auch einen PWM-Anschluss darauf legen und so die Helligkeit einstellen.

Soweit ist also die grundsätzliche Funktion des Displays hergestellt.

CYDR.py

CYDR.py fasst die Möglichkeiten der Platine in einem Objekt zusammen. Das vereinfacht den Start gewaltig. Jetzt werde ich dieses Modul mal ausprobieren.

Ich habe die Datei cydr.py mit Thonny gestartet (entspricht einem Import). Dann das unten dargestellte Protokoll habe ich anschließend durchgeführt. Die getesteten Methoden habe alle funktioniert!

MicroPython v1.23.0 on 2024-06-02; Generic ESP32 module with ESP32

Type "help()" for more information.

>>> %Run -c $EDITOR_CONTENT

MPY: soft reboot
Booting...
>>> %Run -c $EDITOR_CONTENT

MPY: soft reboot
Booting...
>>> cyd = CYD(rgb_pmw=False, speaker_gain=512, display_width=320, display_height=240, wifi_ssid = None, wifi_password = None)
CYD ready...
>>> cyd.display.draw_text8x8(100, 120, "sollte Grün sein!", color565(0, 255, 0))
>>> cyd.touches()
(0, 0)
>>> cyd.touches()
(245, 113)
>>> cyd.touches()
(236, 279)
>>> cyd.play_tone(1000, 100, gain=0)
>>> cyd.play_tone(1000, 100, gain=0)
>>> cyd.wifi_connect('ssid', 'password')
connecting to network...
network config: 192.168.3.180
>>> 
  • cyd = CYD(rgb_pmw=False, speaker_gain=512, display_width=240, display_height=320, wifi_ssid = None, wifi_password = None)
    • Initialize CYD class
    • OK
  • cyd.display.ili9341_cydr_function_name()
    • Use to access ili9341_cydr functions.
    • OK
  • cyd._touch_handler(x, y)
    • Called when a touch occurs.
    • INTERNAL USE ONLY
  • cyd.touches()
    • GETS the last touch coordinates.
    • OK
  • cyd.double_tap(x, y, error_margin = 5)
    • Check for double taps.
    • ?
  • cyd.rgb(color)
    • SETS rgb LED color.
    • OK
  • cyd._remap(value, in_min, in_max, out_min, out_max)
    • Converts a value form one scale to another.
    • INTERNAL USE ONLY
  • cyd.light()
    • GETS the current light sensor value.
    • liefert nur 0.0 zurück.
  • cyd.button_boot()
    • GETS the current boot button value.
    • gibt <bound_method> zurück.
  • cyd.backlight(value)
    • SETS backlight brightness.
    • Es geht nur 1 und 0.
  • cyd.play_tone(freq, duration, gain=0)
    • Plays a tone for a given duration.
    • OK
  • cyd.mount_sd()
    • Mounts SD card
    • OK
  • cyd.unmount_sd()
    • Unmounts SD card.
    • Failed to unmount SD card
      • Laufwerk sd lässt sich nicht unmounten.
  • cyd.wifi_connect(ssid, password)
    • Connects to a WLAN network.
    • OK
  • cyd.wifi_isconnected()
    • Checks to see that the wifi connection is connected.
    • OK
  • cyd.wifi_ip()
    • Get the CYD’s IPv4 address on your WLAN.
    • OK
  • cyd.wifi_create_ap(_ssid)
    • Creates an Access Point (AP) WLAN network.
    • ?
  • cyd.shutdown()
    • Safely shutdown CYD device
      • Failed to unmount SD card
      • display off
      • ========== Goodbye ==========
      • Micropython steht in der REPL weiterhin zur Verfügung.

TODO

  • Backlight ein- und ausschalten in backlight_on() und backlight_off() integrieren.

Mein Traum seit vielen Jahren ist es ein drahtloses Multimeter aufzubauen. Mit den M5Stack Geräten ist dieser Traum der Wirklichkeit sehr viel näher gerückt und mit dem Erscheinen der isolierten Units VMeter und AMeter steht der Realisierung nun nichts mehr im Wege.

Erster Testaufbau – ein chaotisches Gewusel

Auf dem Bild seht Ihr den ersten Testaufbau. Dank der Steckmöglichkeiten war es schnell zusammengesteckt und getestet und funktionierte. Die Spannungswerte sind zwar nicht real aber die Grundsätzliche Funktion ist gegeben. Die Spannungseingänge sind offen und fangen sich offenbar alle möglichen Störsignale ein. Die Stormaufnahme von 500mA enthält den Ladestrom für den Akku des M5Stick Cplus. Mit geladenem Akku sind es immerhin noch 460mA.

Ganz einfach war es nicht diese Kombination zu realisieren, weil die UIFlow-IDE es nicht ermöglichte ohne weiteres die Units am PaHUB zu betreiben. Erst der in diesem Beitrag beschriebene Trick brachte den Durchbruch:

Der Workaround ist nun nicht mehr erforderlich.

Die Units können inzwischen auch direkt in der UIFlow-IDE hinter einem PaHUB benutzt werden.

Das erste Testprogramm

Das erste Testprogramm – Die GUI wurde mit dem UI-Simulator von UIFlow erstellt.
Das an die neuen Möglichkeiten der UIFlow-IDE angepasste Programm (MVA033-010.m5f).

Messgenauigkeit

VMeter Unit

Um überhaupt etwas messen zu können habe ich eine LiIon-Zelle an alle drei VMeter angeschlossen. Eine davon invers gepolt. Das geht Dank galvanischer Trennung der Messteile problemlos. Die Anzeige schwankt zwischen 3,463 und 3,475 Volt. Als eine Unsicherheit von 12 mV. Die Spannungsänderungen springen in 4 mV Schritten. Mein Rigol DM3068 zeigt 3,4629 Volt an. Das entspricht -0% … +0,35% Abweichung. Für allgemeine DIY-Messungen völlig in Ordnung.

AMeter Unit

Zum testen der AMeter habe ich alle drei und das Rigol in Reihe geschaltet und an ein Hameg HM8040 Netzgerät angeschlossen. Mit dem Stromegrenzungspoti habe ich den Stron eingestellt. Da ich die Stromanzeige auf ganze mA eingestellt habe gibt es bei den kleineren Strömen ungenauigkeiten. dazu werden ich anschließend eine Weitere Messreihe durchführen.

DM3068AMeter
10,0776 mA10 mA
20,461 mA20/21 mA
50,76251/50 mA
99,315100/99 mA
201,025201/202 mA
301,47301/302/304 mA
404,92405/406/407 mA
mehr geht nicht beim HM8040

Auch diese Werte können sich sehen lassen. Alle Abweichungen <1%.

Maximal können Ströme bis ±4 A gemessen werden. Die höheren Ströme werde ich später testen. Genauso wie Ströme <1 mA.

Drahtlose Kommunikation

Ein großer Vorteil des ESP32 ist es, dass die Messwerte drahtlos übertragen werden können. Dafür stehen die WLAN-Einheit oder die Bluetooth-Einheit des ESP32 zur Verfügung.

Ein eigenes Übertragungsprotokoll

Im Prinzip ermöglichen die unten aufgeführten drahtlosen Übertragungsprotokolle schon Alles. Warum also noch ein eigenes Protokoll darauf setzen?

Der wesentliche Grund ist, dass es mir beim ESP Now – das ich bevorzugt einsetzen möchte – noch nicht gelungen ist mit der UIFlow-IDE im laufenden Betrieb neue Peers in ein Netzwerk aufzunehmen. Die MAC-Adresse muss zur Programmierzeit bekannt und fest im Programm vorgegeben sein. Damit lässt sich aber kein flexibles zur Laufzeit zusammenstellbares Mess-Netzwerk aufbauen.

https://www.peters-bastelkiste.de/wp-admin/post.php?post=694&action=edit

ESP Now

ESP Now ist ein Protokoll von Espressif, dass die UIFlow-IDE unterstützt. Damit ist recht einfach ein kleines Netzwerk aufgebaut, dass keinen Accesspoint benötigt. Die einzelnen ESP32 Geräte kommuniziernen direkt miteinander. Der Nachteil ist, das bei der Programmierung mit der UIFlow-IDE die MAC-Adressen aller Mitglieder eines solchen Netzwerkes bekann sein müssen. Ob das bei ESP Now grundsätzlich so ist glaube ich nicht. Es ist mir bisher aber nicht gelungen einen Workaround für Micropython und damit für Blockly zu finden. Man kann mit ESP Now aber auch Broadcast Packete aussenden, so dass jedes andere Gerät die Informationen empfangen kann. Das ist zwar nichts für reale Anwendungen, aber zum Ausprobieren ist es zu gebrauchen.

Ein einfaches Programm, dass alle 6 Messwerte ermittelt und anzeigt. U1 wird als Broadcast mit ESP Now gesendet.
Hier das dazugehörige Empfangsprogramm

Die beiden oben abgebildeten Programme zeigen die Möglichkeit der Übertragung mit ESP Now.

Eine Schwierigkeit bei ESP Now ist, dass die Daten als String übertragen werden. Wenn Die Daten in eine Liste gepackt werden und diese Liste übertragen wird sieht der String nach dem Empfang so aus: „[ Wert1, Wert2, Wert3, Wert4, Wert5 Wert6] „. Die Werte daraus zu entpacken ist etwas umständlich. Zuerst müssen die eckigen Klammern entfernt werden:

Aus dem von den eckigen Klammern befreiten String kann nun wieder eine Liste erstellt werden:

Nun ist tmp_date eine Liste die die Messwerte enthält.

In einer Schleife lassen sich nun die Messwerte auslesen. Hier ein kleines Programm, dass die Messwerte untereinander im Display darstellt, zurechtgestutzt auf ganze mV und mA.

Ein universelles Empfangprogramm. Es wird eine Liste mit Daten erwartet und dargestellt.

Hier kann das Programm heruntergeladen werden:

Das dazugehörige Sendeprogramm sieht so aus:

Ein einfaches Sendeprogramm, dass die Daten der 6 Messstellen in eine Liste verpackt überträgt.

Damit kann man schon erste Versuche anstellen.

MQTT

MQTT ist ein Protokoll, dass für den Zweck der Messwerverteilung sicher gut geeignet ist. Es benötigt im WLAN aber einen Brocker, der die Daten entgegen nimmt und weiterverteilt an die Geräte die diese abonniert habe.

WLAN

Das Gerät mit einem Webserver auszurüsten und die Daten dort abzuholen oder vom Server zuschicken zu lassen ist wohl die Königsklasse der drahtlosen Übertragung. Dazu fehlt mir aber noch einiges an Wissen, so dass dieser vorläufig nicht von mir beschritten werden wird.

Grenzwertüberwachung

Die integration einer Grenzwertüberwachung erweitert den Einsatzbereich des Gerätes. Dazu ist eine Tastatur zur Eingabe der Grenzwerte und eine Ausgabe durch Logiksignale, ggf. eine Darstellung auf dem Display.

Für die Grenzwertüberwachung ist wie schon erwähnt eine Tastatur erforderlich, die 5, 7 oder 8 Leitungen benötigt, je nach Anzahl der Tasten. Ausserdem sollte eine Grenzwertüberschreitung auch nach
Außen gemeldet werden. Dazu sind weitere 6 oder 12 Leitungen erforderlich. Je nach dem ob Über- und Unterschreitung oder nur eine einfache Meldung erfolgen soll.

Nun wird es eng auf dem I2C-Bus. Es werden weitere 2 bis 3 I/O-Expander benötigt. Das funktioniert nicht weil deren Adresse nicht umgestellt werden kann (in der UIFlow IDE). Ein weiterer PaHUB kan auch nicht eingesetzt werden, aus dem selben Grund. Der Versuch einen I/O-Expander und einen PbHUB zu kombinieren schlug auch fehl, weil ein I2C-Error gemeldet wurde. Der PbHUB belastet den I2C-Bus offenbar zu stark. Eine M5Stack inherente Lösung gibt es offenbar nicht. Deshalb habe ich I2C-Bus -Expander-IC’s bestllt. Ich hoffe damit lässt sich das Problem lösen.

Ich habe das Proglem mit den fixen Adressen in der UIFlow-IDE und damit auch in Micropython zwar an M5Stack weitergegeben, aber aufgrund meiner bisherigen Erfahrungen rechne ich mit großer Resonanz.

Alternativ könnte das Problem mit den Adressen mit der Arduino-IDE gelöst werden. Soweit ich weiß, kann man dort die I2C-Adresse eines Bausteins angeben. Aber ich wollte doch bei Blockly und Micropython bleiben.

Eingabe Tastatur

Als Eingabetastatur käme eine 4×4-Matrix-Tastatur in Frage. Diese ist aber relativ groß. Alternativ könnten auch Touchkeys zum Einsatz kommen. Deren Eignung muss aber noch untersucht werden.

Software

Die Software muss zum Einen die Eingabe des Grenzwertes für jeden Messkanal ermöglichen. Während des Messens müssen die Werte überprüft und ggf. Aktionen ausgeführt werden.

Darstellung im Display

Im Display kann ein Wert normal grün, in der Nähe des Grenzwerte gelb und bei überschreiten des Grenzwertes rot angezeigt werden.

Ausgabe

Die Ausgabe könnte durch Darlingten-Treiber-IC z.B. ULN2008 realisiert werden. Das ist universal einsetzbar und kann ggf. auch Relais treiben.

Derzeit ist es nicht so ohne weiteres möglich an den M5Stck C aber auch an die ATOM’s Units über einen PaHUB anzuschließen. Ich hoffe, dass sich das in einer der nächsten Versionen der UIFlow-IDE ändern wird. Ich habe jedenfalls darum gebeten.

Die Reaktion darauf in der Comunity erfolgte sehr schnell. Noch am selben Tag wurde die Änderung angekündigt und als ich 2 Tage später wieder in der UIFlow-IDE nachsah war sie tatsächlich schon Realität! Ich habe mich sehr darüber gefreut. Außerdem wurde mir mitgeteilt, dass auch die Möglichheit die I2C-Adressen zu verändern implementiert werden soll. Das lässt hoffen und erzeugt bei mir eine große Vorfreude.

Der folgende Teil dieses Beitrages ist jetzt nicht mehr erforderlich (20.03.2021)

Bei der Unitauswahl für die Core Geräte ist es möglich den PaHUB-Kanal anzugeben an dem die Unit angeschlossen ist. Dann funktioniert alles problemlos mit den bereitgestellten Blöcken. Beim Core2 soll es in Firmware Version 1.7.2 auch Probleme geben.

Beim Stick C/plus und ATOM wird die Möglichkeit einen PaHUB-Kanal anzugeben nicht angeboten. Wenn man die Units trozdem anschließt gibt es eine Fehlermeldung beim Start des Programms.

Für das oben erwähnte Problem beim Core2 habe die folgende Lösung, oder besser den Workaround gefunden:

https://community.m5stack.com/topic/2852/not-possible-to-connect-pa-hub-on-m5stack-core2/6

Die Möglichkeit in der UIFlow-IDE den „Führe Code aus:“ Block einzusetzen bietet sehr viele Möglichkeiten die Einschränkungen bei den Blöcken zu umgehen. Hier wird die Initialisierung der Units hinter dem PaHUB nicht durch die UIFlow-IDE, sondern durch das Programm vorgenommen, inden der entsprechende Python-Code in den „Führe Code aus:“ Block eingetragen wird. Damit entfällt aber auch die Möglichkeit diese Units mit Blöcken anzusteuern. Diese stehen jetzt nicht zur Verfügung. In diesem Fall muss die Abfrage der Spannungs- und Stromwerte dann auch mit Python-Code in „Führe Code aus:“ Blöcken erfolgen. Deshalb ist dieser Weg für mich auch ein Workaround und keine Lösung!

Dieses Konzept lässt sich auch beim Stick C anwenden. Da die beiden Units VMeter und AMeter um die es mir hier geht in der Pythondokumentation bisher noch nicht aufgeführt sind habe ich einmal die dafür zur Verfung stehenden Blöcke eingesetzt und die Pythonübersetzung gegenübergestellt. Damit kann ich jetzt arbeiten.

Nun bleibt noch auszuprobieren, ob das auch wirklich funktioniert. Deshalb habe ich den kurzen Codeschnipzel produziert. Die PaHUB-Unit wird durch die IDE eingebunden. Das funktioniert ja. Die VMeter- und AMeter-Unit habe ich per Programm eingebunden.

Dieser Programmschnipzel funktioniert.

…und siehe da, es gibt keine Felermeldung! So kann man das Problem also umschiffen.

Einige aber nicht alle M5-Geräte sind mit einem AXP192 als Powermanagementsystem ausgestattet. Dieses IC biete viele Möglichkeiten zur Überwachung und Steuerung der Stromversorgung. Hier stelle ich ein Blockly Programm vor, dass die interessantesten Daten auf dem Bildschirm ausgibt.

Ich habe das Programm auf einem M5Stick C plus entwickelt. Mit entsprechender Anpassung der grafischen Oberfläche läuft es auch auf einem M5Stick C und einem M5Stack Core2. Nur diese 3 Geräte haben derzeit einen AXP192 als Powermanager.

Das Programm kann dauerhaft auf des Gerät geladen und bei Bedarf gestarte werden.

Das Bild oben zeigt, was alles angezeigt wird. Zur Zeile Ladestrom ist noch eine Erklärung nötig. Für den M5Stick C/plus gibt es diverse Hats mit einem eigenen Akku. Der kat keine eigene Ladeelektronik, sondern wird einfach parallel zum eingebauten Akku geschaltet. Diese Akkus haben eine Kapazität von 700 – 750mAh. Die Voreinstellung für den Ladestrom liegt bei 100mA. Da kann sich jeder selbst ausrechnen wie lange es dauert bis der Akku voll ist. Bei dem eingebauten mit 90mAh dauert es nur eine Stunde.

Deshalb habe ich eine Ladestrom Umschaltung mit Taster B eingebaut. Voreingestellt sind weiterhin 100mA. Ein Druck auf Taster B schaltet den Ladestrom auf 360mA um. Ein weiterer Druck auf Taste B schaltet wieder auf 100mA zurück. Wenn die Ladung abgeschlossen ist oder unterbrochen wird schaltet das Programm automatisch auf 100mA zurück.

Der Ladestrom kann auf vorgegebene Werte zwischen 100mA und 1A eingestellt werden. Das lässt sich auch im Programm ändern. Allerdings sollte man wissen was man tut, wenn man sich daran macht.

Die grafische Oberfläche wurde mit den UI-Simulator in der UIFlow IDE erstellt. Dashalb erscheinen im Programm keine Blöcke zur Positionierung. Der Vorteil ist, dass das Display beim Neuaufbau nicht flackert. Das erledigt die Firmware ohne das man etwas davon wahrnimmt. Mit CLS und dem lcd.print Block aus der Textsammlung gibt es erheblich Flackereffekte.

Wenn daran Änderungen vorgenommen werden sollen, dann müssen die entsprechendn Elemente in diesem Bild verschoben werden.

Download

Hier kann das Programm heruntergeladen werden:

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:

dig_006.m5f

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.

24. November 2020 · Kommentare deaktiviert für Terminal für M5Stack · Kategorien: ESP32, M5Stack · Tags: , , , ,

Einführung

Ich liebe die Geräte des M5Stack-Universums. Sie haben aber einen entscheidenen Nachteil – die Eingabe von Werten ist sehr umständlich. Insbesondere beim M5Stick C steht, wenn er in ein Gehäuse eingebaut wird, nur eine Taste zur Verfügung. Die UIFlow-IDE stellt zwar Blöcke für einen doppelten und einen langen Tastendruck zur Verfügung, so dass man mit dem normalen Tastendruck quasi 3 Tasten zur Verfügung hat. Damit Werte eingeben geht – ist aber sehr umständlich und m.E. nur eine Notlösung.

Da man meistens nicht ständig Eingaben macht – kaum einer wird auf dem M5Stack Textverarbeitung betreiben wollen – muss nicht jedes Gerät eine eigene Eingabetastatur besitzen. Diese kann, wie heute bei vielen Dingen üblich, „geschared“ werden.

Im einfachsten Fall kann dazu ein M5Stick C mit einem Tastatur-Hat herhalten. Die Kommunikation erfolgt über ESP-Now. Dieses wird von der UIFlow-IDE mit Blöcken unterstützt und ist im Internet gut dokumentiert.

Das Gerät, dass eine Eingabe benötigt ruft per Broadcast noch einem geeigneten Gerät. Dieses meldet sich und ab nun werden die Pakete direkt von Gerät zu Gerät ausgetauscht. Sind alle erforderlichen Eingaben erfolgt. Verabschiedet sich das anfordernde Gerät und Das Eingabegerät steht wieder anderen M5Stack’s zur Verfügung.

Realisierung

Aber wie meistens liegt der Teufel im Details. Es können keine Variablen benutzt werden um eine Mac-Adresse in die Liste einzufügen.

Hallo lieber Leser,

ich habe vor ca. einem Jahr M5Stack entdeckt und beschäfftige mich jetzt überwiegend damit. Insbesondere die Programmierung mit der grafischen Benutzeroberfläche Blockly begeistert mich. Ich werde meine Erfolge und Miserfolge demnächt hier veröffentlichen.

Hier der Link zur M5Stack Webseite.