I want to try out Micropython to see how it runs on a microcontroller. I’m looking for an educatonal platform for the embedded systems and I want to make the setup process and interface for the students as straightforward as possible. Micropython not only offers a python interpreter for microcontrollers it also euns on the microcontroller itself without any need for a programming envrironment or special uploader for the bootloader on the users computer.
Micropython’s creators have made their own development boards, the PyBoard v1.1, which is based on Arm STM32 microcontrollers. I don’t have a PyBoard to use but I do have a STM32nucleo-F411RE which is a cheap dev board made by ST. (The actual microcontroller uses Arm Corte-M processors).
For refernece here is the user guide for the STM32Nucleo
Accessing Boot0 and flashing via USB on the STM32Nucleo
There is a usb port onthe dev board which routes to ST-Link - a usb interface to the STM32xxx microcontroller. In order to flash a new bootloader I bypass this interface and connect usb from my laptop directly to the STM32 pins.
The manual doesn’t really highlight it in any of the tables but looking at the layout of the chip I can see where the USB pins are.
Here’s a run through of the connections/settings on the hardware:
- USB D+ (green wire) to PA12
- USB D- (white wire) to PA11
- USB 5V to E5V
- USB gnd to GND
- Jumper on boot0 and VCC
- Jumper on E5V on pwr
When this is plugged into the computer I run lsusb
and see a device
with vendor id: product id being 0483:df11
.
Flashing Micropython onto the STM32nucleo
I clone the micropython repo and then build the project as directed on the /ports/stm32 readme
Note I needed to have arm-none-eabi-gcc
installed and I also
installed dfu-util
both of which I got from arch/manjaro package
management.
So the commands I ran were:
$ git clone https://github.com/micropython/micropython.git
whilst in the root dir for mircropython
$ make -C mpy-cross
then I changed directory to the /ports/stm32
and
$ make submodules
And - before I ran this next part, becuase it runs a python script
that usesd a module I didn’t have installed I created a virtualenv to
work in and pip install pyusb
then I reset my stm32nucleo that was plugged in and ran
$ make BOARD=NUCLEO_F411RE depoly
The proejct builds for a the board and if all is well then the firmware is flashed onto the dev board.
Running micropython
I unplugged the USB and disconnected it from the header pins on the board.
I removed the boot- & VCC jumper and I switched the pwr jumper from E5V to U5V (which is telling the board to use the power from the ST-Link USB).
I then plugged in the usb into the ST-Link USB port to which I get
asked if I want to mount the storage device on my laptop. Instead of
this I want to try the repl and looking at dmesg
I can the device is
registered to/dev/ttyACM0
.
I then installed picocom
through the arch/manjaro package manager
and ran picocom /dev/ttyACM0
which gave me a python repl - running
on the STM32Nucleo.
$ picocom /dev/ttyACM0 --baud=115200
picocom v3.1
port is : /dev/ttyACM0
flowcontrol : none
baudrate is : 115200
parity is : none
databits are : 8
stopbits are : 1
escape is : C-a
local echo is : no
noinit is : no
noreset is : no
hangup is : no
nolock is : no
send_cmd is : sz -vv
receive_cmd is : rz -vv -E
imap is :
omap is :
emap is : crcrlf,delbs,
logfile is : none
initstring : none
exit_after is : not set
exit is : no
Type [C-a] [C-h] to see available commands
Terminal ready
MicroPython v1.12-154-gce40abcf2 on 2020-02-09; NUCLEO-F411RE with STM32F411xE
Type "help()" for more information.
>>>
When the serial terminal loads I type C-b
which sends a beak request
and reloads micropython - that’s simply so I can see the version etc
as a test.
Hello World on STM32Nucleo
The hello world of microcontrollers is to flash an LED. Micropython
has a simple way of doing this using a module pyb
. The user LED on
my STM32Nucleo is connected on D13 arduino pin or PA5, and is mapped
in the micropython libraries to led 1.
>>> import pyb
>>> pyb.LED(1).on()
That turns on the little green LED on the board (LD2 in the user
manual) and pyb.LED(0).off()
turns it off again. There’s also a
toggle()
method that can be called.
To use the switch on the board we can use the built in method Switch.
Switch can be read to see if it’s on or off with Switch.value()
and,
more interestingly, there is built in callback functionality which
will detect an interrupt an run some code.
>>> led = pyb.LED(1)
>>> sw = pyb.Switch()
>>> sw.callback(lambda: led.toggle())
I could have also created a function and passed that into the callback.