MicroPython A complete reimplementation of Python Designed to be efficient with resources Designed to run bare metal Includes: A compiler, runtime & familiar REPL Support for basic libraries Extra modules to control hardware
How does MicroPython solve the issue of having a low amount of RAM? Interned strings, most already in ROM Small integers stuffed in a pointer to avoid using heap (trick from lisp) Optimised method calls to not use heap Garbage collection
Tips: Memory allocation Doesn’t use heap Uses Heap Expressions Importing If, while, for and try statements Defining functions & classes Local variables Assigning global variables for the first time Small integer arithmetic Creating data structures Inplace operations on existing data structures Calling functions/ methods with positional or keyword args
Tips: CPU time USE FUNCTIONS TO AVOID GLOBAL SCOPES USE LOCAL VARIABLES CACHE MODULE FUNCTIONS & OBJECT METHODS AS LOCALS PREFER LONGER EXPRESSIONS NOT SPLIT UP ONES RUNTIME IS FAST! E.G. STR.STARTSWITH
Tips: RAM usage DON'T USE HEAP WHEN POSSIBLE SHORTER VARIABLE NAMES, REUSE THEM; EG X,Y,I, LEN, VAR DON'T USE * OR ** ARGS SCRIPT MINIFICATION ULTIMATE SOLUTION: FREEZE SCRIPTS INTO THE FIRMWARE (AT COMPILE TIME)
Inside a function - removes global variables 60kHz import time, machine led = machine.Pin('LED_BLUE') def blink_simple(n): for i in range(n): led.on() led.off() @dpgeorge
Preload methods & range() optimisation def blink_preload(n): on = led.on # returns a bound method off = led.off r = range(n) # optimise the range for i in r: on() off() 180kHz @dpgeorge
Native mode @micropython.native def blink_preload_unrolled8_native(n:int): n //= 4 on = led.on off = led.off r = range(n) for i in r: on() off() on() off() .... 290kHz @dpgeorge
Takeaways ○ If your code runs faster it can sleep for longer and that saves battery! ○ ROM everything that you can ○ Use runtime methods! ○ Local not global variables!