Whoever programs microcontrollers today mostly uses C/C++ for this. With this language, everything can be implemented, but programming is time-consuming and error-prone. Before you can program anything, you also have to install and configure a toolchain. Depending on the hardware, even the configuration of the development environment is already a hurdle. Depending on the settings, you can even permanently destroy (flash) your microcontroller.
For a while there have been alternatives, for example Micropython or Circuitpython. Both are specially designed interpreters for microcontrollers, which are based on the popular Python programming language. However, Python has the big disadvantage that as a dynamically typed language it uses a lot of memory and has a poor runtime behavior. Computing power and memory is available in large quantities on normal PCs, but not on microcontrollers. Therefore, today you can only decide whether you want to work efficiently, but costly with C/C++ or with Micropython fast and compact, but slow and with large memory limitations.
NanoPy fills this gap here. The language is statically typed with static memory management. This allows it to handle the limited resources of a microcontroller very efficiently. It is also easy to use, since it adopts well-known language concepts from the popular Python language. This is achieved thanks to modern compiler technology, which can also mimic dynamic programming practices to a certain extent. When executed, NanoPy generates a compact bytecode that is executed on the target machine via an efficient interpreter. By not using dynamic memory, NanoPy is very robust and runs stably even in long-term operation.
Example:
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()
To NanoPy there are many tools, which one misses with microcontrollers normally, whereby one must install and manage nothing locally. Everything runs comfortably in the browser. In the integrated development environment we find live debugging tools, autocomplete functions, a complete interactive documentation, as well as many ready programmed examples, which one can use immediately for own projects.
NanoPy combines existing language concepts with new technical processes.
This often allows even simple Python code to run on microcontrollers with little modification.
NanoPy can handle many of Python’s language constructs. Among other things, the language also uses the indentation of blocks. The colon, which is mandatory in Python, and the parentheses around procedure calls are not mandatory in NanoPy. Especially beginners often have trouble with these constructs, so you can simply omit them in NanoPy.
In NanoPy microcontrollers can be programmed event-driven.
The NanoPy system for microcontrollers defines a number of event procedures that are automatically called by the system when a certain situation occurs.
Currently the following events are available:
Event | Trigger |
---|---|
onClick | is triggered when a button on the device is pressed. |
onTimer | If a timer is configured, onTimer is called when the event occurs. The timer can be defined either once (setTimer) or recurring as an interval (setInterval). |
onDraw | s triggered approx. every 20ms, if the controller is not busy with higher priority tasks. This allows smooth screen animations to be displayed on the TFT screen of the Oxocards. |
When the button is pressed down, the interval is defined and started. This triggers an onTimer event every 100ms. If the button is still pressed up, the interval stops.
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"
By clicking on the button the global variable on changes between true and false. The event onDraw is called 30-50x per second. In this functions we check the state of the variable and draw a circle if on is true.
Python-Style
on=false
def onDraw():
clear()
if on:
drawCircle(120,120,80)
update()
def onClick():
on = not on
delay(500)
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"
Micropython | C/C++ / Arduino | NanoPy |
---|---|---|
Complete Python language set | Complete C/C++ language set | Optimized language scope for microcontrollers |
Dynamically typed | Statically typed | Statically typed |
Dynamic memory management | Static and dynamic memory management | Static memory management |
Slower because dynamically typed / dynamic memory management | fast | fast |
Higher memory requirements | Low memory requirements | Low memory requirements |
No debugging | Debugging with adapter | Debugging directly via browser |
Transfer of user scripts | Only complete firmware can be transferred | Transfer of user scripts |
Installing the firmware / updating via flasher | Installation of software. Compiling and flashing | Programming via browser / app. / Firmware over the air |
Interpreter | Compiler | Bytecode-Compiler / Interpreter |