Aus Oxoscript wird NanoPy - mehr Infos

Warum braucht es eine neue Programmiersprache?

Wer heute Microcontroller programmiert, verwendet dafür meistens C/C++. Mit dieser Sprache ist zwar alles umsetzbar, jedoch ist die Programmierung aufwändig und fehleranfällig. Bevor man etwas Programmieren kann, muss zudem eine Toolchain installiert und konfiguriert werden. Je nach Hardware ist selbst die Konfiguration der Entwicklungsumgebung bereits eine Hürde. Je nach Einstellungen kann man damit seinen Microcontroller sogar permanent zerstören (verflashen).

Seit einer Weile gibt es zwar Alternativen, beispielsweise Micropython oder Circuitpython. Beide sind speziell für Microcontroller konfektionierte Interpreter, die auf der beliebten Python-Programmiersprache basieren. Python hat allerdings den grossen Nachteil, dass sie als dynamisch typisierte Sprache viel Speicher verwendet und ein schlechteres Laufzeitverhalten aufweist. Rechenleistung und Speicher ist auf normalen PC’s in grossen Menge verfügbar, nicht aber auf Microcontrollern. Daher kann man sich heute eigentlich nur entscheiden, ob man effizient, jedoch aufwändig mit C/C++ arbeiten möchte oder mit Micropython schnell und kompakt, dafür langsam und mit grossem Speicherlimitationen.

NanoPy füllt hier diese Lücke. Die Sprache ist statisch typisiert mit statischer Speicherverwaltung. Dadurch kann sie sehr effizient mit den beschränkten Ressourcen eines Microcontrollers umgehen. Sie ist aber auch einfach zu nutzen, da sie bekannte Sprachkonzepte der beliebten Python-Sprache übernimmt. Dies gelingt dank modernder Compilertechnik, die bis zu einem gewissen Grad auch dynamische Programmierpraktiken nachahmen kann. Bei der Ausführung erzeugt NanoPy einen kompakten Bytecode, der über einen effizienten Interpreter auf der Zielmaschine ausgeführt wird. Dadurch dass kein dynamischer Speicher verwendet wird, ist NanoPy sehr robust und läuft auch im Langzeitbetrieb stabil.

image

Beispiel:

background(0,0,0)

for i in 100:
  x = random(0,240)
  y = random(0,240)
  r = random(0,20)

  drawCircle(x,y,r)

update()

Zu NanoPy gibt es viele Tools, die man bei Microcontrollern normalweise vermisst, wobei man nichts lokal installieren und bewirtschaften muss. Alles läuft bequem im Browser. In der integrierten Entwicklungsumgebung finden wir Live-Debugging-Tools, Autocomplete-Funktionen, eine komplette interaktive Dokumentation, sowie viele fertig programmierte Beispiele, die man sofort für eigene Projekte einsetzen kann.

image

Wie sieht NanoPy aus?

NanoPy kombiniert bestehende Sprachkonzepte mit neuen technischen Verfahren.

Dadurch lässt sich häufig sogar einfacher Python-Code mit wenig Änderungen auf Microcontrollern ausführen.

image

NanoPy kann mit vielen Sprachkonstrukten von Python umgehen. U.a. verwendet die Sprache auch die Einrückung von Blöcken. Der in Python zwingend notwendigen Doppelpunkt, sowie die Klammern um Prozeduraufrufen ist in NanoPy jedoch nicht zwingend. Gerade Einsteiger:innen bekunden häufig Mühe mit diesen Konstrukten, daher kann man diese in NanoPy auch einfach weglassen.

Wie wird in NanoPy programmiert?

In NanoPy lassen sich Microcontroller ereignisgesteuert programmieren.

Das NanoPy-System für Microcontroller definiert eine Anzahl Ereignisprozeduren, die vom System automatisch aufgerufen werden, wenn eine bestimmte Situation eintritt.

Aktuell sind folgende Ereignisse verfügbar:

Ereignis Auslöser
onClick wird ausgelöst, wenn ein Button auf dem Gerät gedrückt wird.
onTimer Wenn ein Timer konfiguriert ist, wird beim Eintreffen des Ereignisses onTimer aufgerufen. Der Timer kann entweder einmalig (setTimer) oder als Intervall wiederkehrend (setInterval) definiert sein.
onDraw Wird ca. alle 20ms ausgelöst, wenn der Controller nicht mit höherprioritären Tasks beschäftigt ist. Damit lassen sich flüssige Bildschirmanimationen auf dem TFT-Screen der Oxocards darstellen.

Beispiel 1: Timer-Ereignis

Wenn der Button nach unten gedrückt wird, wird das Interval definiert und gestartet. Dadurch wird alle 100ms ein onTimer-Ereigns ausgelöst. Wenn der Button noch oben gedrückt wird, stoppt das Intervall.

Python-Style

def onTimer():
    print("timer")

def onClick():
    b = getButtons()
    if b.down:
        setInterval(100)
        print("start interval")
    if b.up:
        stopInterval()
        print("stop interval")


Compact-Style

def onTimer
    print "timer"

def onClick
    b = getButtons()
    if b.down
        setInterval 100
        print "start interval"
    if b.up
        stopInterval
        print  "stop interval"

Beispiel 2: onDraw-Ereignis

Durch Klick auf den Button wechselt die globale Variable on zwischen true und false. Das Ereignis onDraw wird 30-50x pro Sekunde aufgerufen. In dieser Funktionen prüfen wir den Zustand der Variablen und zeichnen einen Kreis, wenn on true ist.

Python-Style

on=false

def onDraw():
  clear()
  if on:
    drawCircle(120,120,80)
  update()

def onClick():
  on = not on
  delay(500)

Compact-Style

on=false

def onDraw
  clear
  if on
    drawCircle 120,120,80
  update

def onClick
  on = not on
  delay 500

Unterschiede zu Micropython und C/C++ (Arduino u.a.)

Micropython C/C++ / Arduino NanoPy
Kompletter Python-Sprachumfang Kompletter C/C++ Sprachumfang Optimierter Sprachumfang für Microcontroller
Dynamisch typisiert Statisch typisiert Statisch typisiert
Dynamische Speicherverwaltung Statische und dynamische Speicherverwaltung Statische Speicherverwaltung
Langsamer, da dynamisch typisiert / dynamische Speicherverhaltung schnell schnell
Höherer Speicherbedarf geringer Speicherbedarf geringer Speicherbedarf
Kein Debugging Debugging mit Adapter Debugging direkt via Browser
Übertragung von Benutzerscripts Nur komplette Firmware kann übertragen werden Übertragung von Benutzerscripts
Installation der Firmware / Aktualisierung via Flasher Installation von Software. Kompilieren und flashen Programmieren via Browser / App. / Firmware over the air
Interpreter Compiler Bytecode-Compiler / Interpreter