RkBlog

Micro Python and pyboard - a Python running on a microcontroller scripts your electronics

2014-08-24

MicroPython is a Python 3 implementation capable of working on microcontrollers with no operating system. PyBoard is the first microcontroller board running Micro Python. It can be scripted with Python code and can execute it, work without any connection to a PC. How does it work and what can we do with pyboard and Micro Python?

PyBoard

The pyboard is equipped with STM32F405RGT6 microcontroller (ARM 32-bit Cortex-M4 CPU with FPU), Freescale MMA766 accelerometer, micro SD and micro USB connector. Multiple GPIO provide features such as I2C, SPI, USART or DAC/ADC support.

PyBoard pin layout

PyBoard pin layout

PyBoard from the top
PyBoard from the bottom

You can buy pyboard from projects store or you may have one from Kickstarter funding. If you want to buy one I recommend the one with soldered female connectors as those seems best for this board. The board I got from Kickstarter had no pin connectors so I've soldered male ones. After doing so I couldn't use it with a breadboard as the board is to wide for a standard breadboard (you would have to use two - side by side). Also the GPIO on the end would have to be placed on the top of the board to use it with breadboards. Female GPIO connectors just make it easier in this case.

There is quite good documentation as well as Micro Python tutorial.

To wide to fit on a breadboard

To wide to fit on a breadboard

Newer version with female GPIO connectors

Newer version with female GPIO connectors

How does it work?

pyboard has a small filesystem named 0:/. If you connect a microSD card then it will be recognized as 1:/. When starting pyboard will pick the filesystem to boot from. If the microSD card is present it will pick it, and if not it will use the internal one. During boot pyboard will execute boot.py and then main.py file in which your code should be placed. When you connect the board via USB to a PC the booted filesystem will be mounted (just like if it was a flash drive) and you will be able to copy files with the code.

Aside of putting code into main.py file we can also use REPL (Read Evaluate Print Loop) which is a sort of an interactive console of Micro Python. It uses a serial connection and you can make one under Linux like so:

sudo screen /dev/ttyACM0

For other systems check the documentation. When REPL start you will the the interactive interpreter with some extra features. Write help() to get a handy help instruction. Now you can for example import the pyb module and start scripting the board right from the console. To leave REPL press CTRL + a and then CTRL + d.

Here is a simple example of using pyb in REPL, a simple loop that prints data from the accelerometer:

import pyb
accel = pyb.Accel()

while True:
    print(accel.filtered_xyz())
    pyb.delay(250)

Just tilt the board to see how values change.

MicroPython

As you could notice the pyb module allows use to script the GPIO features. You can check pyb documentation to get to know all of its classes. That just a module written to run on Micro Python - a Python 3 implementation that was designed to run on microcontrollers with limited resources and no operating system. This means that there won't be a full standard library available, and you won't be able to run most of third party libraries made for Python 3. Aside of runtime Micro Python is just few modules that we can use.

As the hardware platform is totally different than for the original Python some different design decisions have been taken to make it possible (including garbage collector, integer implementation and more). You can watch this video if you want to know more:

Micro Python can work on other similar microcontrollers. On the project wiki there are list of supported or plausible for future support boards. At the time of writing this article STM32F4-Discovery and Teensy 3.1 are more-or-less supported.

Similar project - pymite existed long before Micro Python. It supports some boards, like Arduino Mega or two mbed boards, but on the other hand documentation and marketing are quite poore as well as it seems to be quite limited in terms of features (I didn't saw any example how to use I2C/UART/SPI on Arduino Mega. There is better support for mbeds, but the tutorials seems old and no buzz can be seen there).

PyBoard in action

The API of the pyb module is quite easy to use. High level classes make handling some components quite easy. Some of my pyMCU code needed only minimal changes. Some time ago I wrote about controlling servos with pyMCU. The pyb module has a ready to use Servo class that we can use to the same thing. On the pyboard edge there are pins named from X1 to X4. As you can notice on the GPIO layout those are the pins that provide PWM for servo support. Power and GND are just next to them so it's easy to connect a three wire servo. The Servo.angle method will move the servo to a given angle. For an example we can use tilt in one of the axis to move the servo angle:

import pyb
servo = pyb.Servo(1)
ac = pyb.Accel()
SCALE_MULTIPLIER = 3

while True:
  pyb.delay(250)
  servo.angle(ac.x() * SCALE_MULTIPLIER)

Servo class constructor gets 1 as I used the X1 pin for the servo. I multiply the value from the X axis by 3 to increase the range of angle tilt the servo will get. When the loop start just tilt the board in the X axis and observe how the servo moves.

PyBoard with a servo

PyBoard with a servo

I wrote about UART controlled LCD displays. For the hobbytronics serial LCD adapter I wrote a LCD class to make it easy and clean to display something on the LCD. To convert it from pyserial to Micro Python valid code we just need few minor changes - change the import to pyb and use pyb.UART:

import pyb


class LCD(object):
    END = chr(0xFF)

    def __init__(self, device, rows, columns):
        self.commands = {
            'display_string': chr(1),
            'set_cursor_position': chr(2),
            'clear_line': chr(3),
            'clear': chr(4),
            'set_lcd_type': chr(5),
            'backlight': chr(7)
        }
        self.device = device
        self.rows = rows
        self.columns = columns
        self.connection = None

    def configure(self):
        self.connection = pyb.UART(self.device, 9600)
        pyb.delay(1000)
        self.execute_command('set_lcd_type', chr(self.rows) + chr(self.columns))
        self.clear()

    def clear(self):
        self.execute_command('clear', '')

    def clear_line(self, line):
        self.execute_command('clear_line', chr(line))

    def set_backlight(self, brightness):
        self.execute_command('backlight', chr(brightness))

    def set_cursor_position(self, row, column):
        self.execute_command('set_cursor_position', chr(row) + chr(column))

    def display_string(self, string):
        self.execute_command('display_string', string)

    def close(self):
        self.connection.deinit()

    def execute_command(self, command, payload):
        self.connection.send(self.commands[command] + payload + self.END)

Two methods have changed: configure and execute_command.

The usage is the same as the class interface did not change:

def do_serial_demo():
    lcd = LCD(3, rows=4, columns=20)
    lcd.configure()
    lcd.set_backlight(25)
    accel = pyb.Accel()

    while True:
        lcd.clear()
        lcd.set_cursor_position(1, 1)
        lcd.display_string(str(accel.x()))
        lcd.set_cursor_position(2, 1)
        lcd.display_string(str(accel.y()))
        pyb.delay(500)

I used UART3 as that was the one I found first (TX on pin Y9). I used a big 4x20 LCD and in the first two rows I've set X and Y axis tilt to be displayed.

PyBoard with UART controlled LCD display

PyBoard with UART controlled LCD display

Summary

For Python developers and enthusiasts Micro Python seems the best solution for scripting electronics with Python. There is PyMCU but it requires a PC to work (and it has some hard edges, like I2C), there are single board computers like Raspberry Pi, BeagleBone Black or PcDuino with good Python support, but they are computers while you may sometimes need something smaller and much less power demanding (battery powered). The pyboard isn't cheap, it's much more expensive than Chinese Arduino clones. It can't work on simple microcontrollers used in small Arduinos, but there are similarly priced STM32 Nucleo boards and few others. With time Micro Python should be quite popular platform.

Comment article