MicroPython ist eine Implementierung der Programmiersprache Python für Mikrocontroller, mit der das Publikum dieser Sprache unter Verwendung der bekannten Syntax und Programmierprinzipien mit kleinen Computergeräten arbeiten kann.
In meiner Arbeit verwende ich MicroPython, um Prototypen zu erstellen, Ideen schnell zu testen und kleine Stände zu erstellen. Dank REPL und einfacher Syntax eignet sich MicroPython auch hervorragend für DIY-Projekte und zum Unterrichten von Programmierung.
Wenn es um die Interaktion von Computern mit der realen Welt geht, interessiert mich immer die Geschwindigkeit ihrer Interaktion. In einigen Fällen ist beim Einsatz von Mikroprozessortechnologie, beispielsweise im Bereich des Internet der Dinge, die Reaktionsgeschwindigkeit des Gerätes nicht so wichtig. Es gibt keinen großen Unterschied, wenn die Alarmsirene eingeschaltet wird: 10 Mikrosekunden nach Bewegungserkennung oder 10 Millisekunden.
In einigen Aspekten ist jedoch die Geschwindigkeit und Reaktionszeit wichtig, und es stellt sich die Frage, ob die Verwendung von MicroPython angemessen ist. Also habe ich ein wenig recherchiert, inspiriert von dem
Video aus der Rede des Schöpfers von MicroPython Damien George. Ich fragte mich, wie schnell ein in Micropython geschriebenes Programm auf Eingabeeffekte reagieren würde.
Das experimentelle Gerät wird der Mikrocontroller ESP8266 auf der NodeMcu-Karte mit der integrierten MicroPython-Version esp8266-2018511-v1.9.4 sein.

Ich drücke die Taste und registriere auf dem Oszilloskop den Zeitunterschied zwischen dem Drücken und dem Auftreten von 3,3 V am anderen Bein des Mikroprozessors. Jede Messung wird 15 Mal durchgeführt, der Durchschnitt wird genommen (in den Diagrammen dargestellt) und die Standardabweichung berechnet (schwarzer Balken in den Diagrammen).
Test Nummer 1.
Wenn Sie dieses Problem "frontal" lösen, sieht das Programm ziemlich trivial aus:
import machine import time o = machine.Pin(5, machine.Pin.OUT)
Eine typische Wellenform mit einem solchen Programm sieht folgendermaßen aus:

Hier und bei anderen Wellenformen ist das „blaue“ Signal der Pin mit der Taste, der „grüne“ Antwort-Pin. Mit 15 Wiederholungen wird folgendes Bild erhalten:

Im Durchschnitt beträgt die Reaktionszeit etwa 310 Mikrosekunden, das Maximum beträgt 356 μs, nicht sehr schnell, aber für einige Anwendungen ist es durchaus akzeptabel.
Test Nummer 2
Sie können den Standardcode "sofort einsatzbereit" durch Interrupt-Behandlung beschleunigen.
import machine import time o = machine.Pin(5, machine.Pin.OUT)
Und das Bild ist wie folgt:


und die maximale Reaktionszeit beträgt 306 μs.
Die Verwendung von Interrupts führt zu einer Geschwindigkeitssteigerung von etwa 20%, gleichzeitig jedoch zu einer relativ großen Streuung der Reaktionszeit.
Test Nummer 3
Wenn die erhaltenen Geschwindigkeiten nicht ausreichen, besteht der nächste Schritt darin, die @ micropython.native-Konstruktion zu verwenden, mit der der Python-Code in nativen Maschinencode konvertiert werden kann. Es gibt jedoch einige
Einschränkungen .
Code-Option:
import machine import time o = machine.Pin(5, machine.Pin.OUT)
Typisches Antwortmuster auf der Wellenform:

Im Vergleich zur vorherigen Methode hat sich die Beschleunigung fast verdoppelt:

Die längste Reaktionszeit beträgt 128 μs.
Test Nummer 4
Der nächste Schritt bei der Suche nach einem „schnellen“ MicroPython besteht darin, das Konstrukt @ micropython.viper zu verwenden und direkt auf die Mikroprozessorregister zuzugreifen (Registeradressen finden Sie
hier .
import time @micropython.viper def f(): O = ptr32(0x60000300)
Infolgedessen beschleunigte sich die Reaktion spürbar:

Die Reaktionszeit ist sehr klein und kann nicht mit anderen Methoden verglichen werden (maximal 820 ns):


Wenn dies nicht ausreicht, können Sie Assembler-Einfügungen über den Dekorator @ micropython.asm_thumb verwenden. Bei dieser Methode bleibt Python nicht besonders erhalten (und die Vorteile von Python auf hoher Ebene gehen verloren). Wenn höhere Geschwindigkeiten erforderlich sind, ist es besser, andere Hardware zu verwenden, z. B. FPGA (wo Python auch nützlich sein kann, siehe
hier und
hier ).
UART
Wenn nach einem Ereignis viele Informationen übertragen werden müssen, können Sie die serielle UART-Schnittstelle verwenden.
Nehmen Sie zum Beispiel zwei Implementierungsoptionen.
Das erste ist durch Interrupt-Behandlung:
import machine i = machine.Pin(4, machine.Pin.IN)
Und die Antwortwellenform:

Die maximale Reaktionszeit beträgt 248 μs.
Und der zweite Test durch Viper:
import machine import time i = machine.Pin(4, machine.Pin.IN)
Und die Wellenform im zweiten Test:

Die maximale Antwortzeit mit diesem Code beträgt 71 μs.
Die durchschnittliche Reaktionszeit in zwei Tests:

Die Beschleunigung der Reaktion wird durch eine schnellere Erfassung des Eingangseffekts im zweiten Test erreicht.
Fazit
Mit MicroPython können Sie beim Programmieren von Mikrocontrollern Dinge verwenden, die für Hochsprachen charakteristisch sind (OOP, Ausnahmebehandlung, Listen- und Diktatvergleiche usw.), und bei Bedarf den "klassischen" Python-Code erheblich beschleunigen.