RP2040 MicroPython: mpremote
An updated look at the utility, mpremote, used to communicate with a board running MicroPython.
Review
A tool which has improved a great deal with the 1.20 release is mpremote - micropython remote control. After using it extensively, I’ve found its biggest issue is the lack of documentation as compared to its capabilities. It is invaluable, if not mandatory for interacting with a MicroPython board.
Installation
# to install
pip install mpremote
# to upgrade
pip install --upgrade mpremote
Help Command
Once installed, use the help command to see the available commands. Make sure CoolTerm is not connected, otherwise you won’t be able to connect to the board via mpremote.
mpremote help
mpremote -- MicroPython remote control
See https://docs.micropython.org/en/latest/reference/mpremote.html
List of commands:
connect connect to given device
disconnect disconnect current device
edit edit files on the device
eval evaluate and print the string
exec execute the string
fs execute filesystem commands on the device
help print help and exit
mip install packages from micropython-lib or third-party sources
mount mount local directory on device
repl connect to given device
resume resume a previous mpremote session (will not auto soft-reset)
rtc get (default) or set the device RTC
run run the given local script
sleep sleep before executing next command
soft-reset perform a soft-reset of the device
umount unmount the local directory
version print version and exit
Stages of use
I recommend learning to use mpremote in stages:
Stage 1: File management
- Use it to copy files to the board and understand what is on the board. At times, this might be the only tool which can do what you want. Examples:
# copy file from computer to board
mpremote fs cp filename :filename
mpremote fs cp filename :main.py
# list the files on the board
mpremote fs ls
# remove a file from the board
mpremote fs rm filename
Stage 2: Add New Commands
- Add more capability using a .config file. See Stage 2:. This can provide more and extremely helpful capabilities such as reformatting the filesystem or command simplification. When you add a .config file, the shortcuts you have added will be listed, however, I have yet to find a way to add a comment or documentation as to what the shortcut does.
# reformat the board, DELETES ALL FILES ON THE BOARD!
mpremote littlefs_rp2
# shortened command for listing files
mpremote fl
# provides detailed information as to filesystem
mpremote info
Stage 3: Customization
- Develop your own specific command shortcuts or actions, which you need to be more efficient. For example, in version 1.2.1, the ability for mpremote to set the real-time-clock (RTC) was added. This means a new copy command might be of value, which not only copies over the file, it also sets the value of the RTC. More than likely, using raw REPL might be required to build powerful commands, see Note 2.
Details on Stages
Stage 1: File Management
Copy a file
If you wish a program to always execute on boot, copy your file to main.py, . Remember the destination requires a preceding “:”. It is helpful to execute a ls following, to ensure the program was copied.
# to copy a file
mpremote fs cp pintest.py :main.py
cp pintest.py :main.py
# to show contents of Pico filesystem
mpremote fs ls
ls :
2332 main.py
Stage 2: Add New Commands Using a .config file
A compelling aspect of mpremote is its config file. The config file for mpremote may contain shortcuts and they can be quite powerful.
For example, based on this entry by @jimmo, I used his shortcut on the Pico W to clear file memory. The command is a simple, yet powerful way to remove all files from the Pico, in order to fix a problem or start anew on a project. Be sure you want to erase your Pico program files, if you use this command!
I also simplify commands I quite often use such as mpremote fs ls
to mpr fl
, for which, I had to do two things, first, setup an alias of mpremote
to mpr
(I’ll use mpr going forward instead of mpremote, their use is identical.) then create the shortcut fl
in the mpremote config file.
The other two examples are extremely handy for using a file on your computer on the microcontroller. The first mpr test
will execute the program test.py in my local directory on my computer on the Pico. The second mpr info
will execute a program which prints the information on local file storage on the Pico. This command is valuable to help you understand the storage impact of program components.
Local directory . is mounted at /remote
Attempting to determine filesystem
Littlefs v2 filesystem
0008 magic littlefs
0014 version 0x20000
0018 block_size 4096
001c block_count 212
0020 name_max 255
0024 file_max 2147483647
0028 attr_max 1022
0000 program memory 868352
0000 used memory 151552
0000 free memory 716800
When you run mpr devs
, it will list the serial ports on your computer along with an ID of each MicroPython board. You can use the ID to connect with a specific board using the shortcut shown in the config file, as in mpr A
, will connect to the board with the specific ID e6614864d3323634.
mpremote devs
/dev/cu.Bluetooth-Incoming-Port None 0000:0000 None None
/dev/cu.JabraEvolve65 None 0000:0000 None None
/dev/cu.usbmodem31401 e6614864d3323634 2e8a:0005 MicroPython Board in FS mode
/dev/cu.wlan-debug None 0000:0000 None None
Finally, I am also able to combine some commands shown above into a specific command which will blink the connected board.
~/.config/mpremote/config.py
commands = {
"A": "connect id:e6614864d3323634",
"fl": "fs ls",
"littlefs_rp2": [
"exec",
"--no-follow",
"import os, machine, rp2; os.umount('/'); bdev = rp2.Flash();\
os.VfsLfs2.mkfs(bdev, progsize=256); \
vfs = os.VfsLfs2(bdev, progsize=256); \
os.mount(vfs, '/'); machine.reset()",
],
"test": ["mount", ".", "exec", "import test"],
"info": ["mount", ".", "run", "fs_info.py"],
"blink": ["mount", ".", "exec",
"from blink import Blink; Blink()"]
}
Stage 3: Custom Commands
Understand raw REPL vs. REPL
The single biggest “aha!” I have found from developing code in MicroPython was raw REPL. It happened when I was attempting to write mpbuild, a program which can automatically load your Pico with the desired files. I tried multiple methods of automating the copy process, using a python exec call on mpremote, creating a subprocess call on mpremote…etc. I knew I was going down the wrong path when I saw this comment “I do not recommend using mpremote via subprocess! Everything you need should be available from pyboard.py.”
Ok, fine. I began to explore using pyboard.py, same issues remained. I wasn’t able to get my version of the example to work. In my version, I wanted to copy a file and not print(1 + 1)
.
I gave up for a few hours and did a little bit more searching. And bless Dave Hylands…in 2014, he had this to say: “Primarily - yeah. You can think of raw REPL as a programmatic interface, and regular REPL as a human interface. The raw REPL also makes it much easier (from the script’s perspective) to determine exactly what the real output of a command (like print) is.”
With that, the light bulb went off, and I changed my code. In the example, there was a call to raw_repl, which I wasn’t doing as I wasn’t “attempting to execute code” such as the example. Wrong! If you want to execute the pyboard code, you need to be in raw_repl mode, then everything works!
So my example became (this is the key code in the program mpbuild):
from mpremote.pyboard import Pyboard
pyb = Pyboard(os.environ['PYBOARD_DEVICE'], 115200)
pyb.enter_raw_repl()
pyb.fs_put(s, d)
pyb.exit_raw_repl()
pyb.close()
It works great! And mpbuild works exactly as I wish. If you wish to create your own interface Python programs to communicate between your MicroPython microcontroller board and your PC, I highly recommend “playing” with the pyboard tool, just remember to use raw_repl.
Additional mpremote Commands
Mount folder
Using the mount command, “mpremote mount .”, you can mount the folder on the PC as local storage to the microcontroller. When the listdir() is executed it is showing the contents of the folder on the PC, not on the Pico. Here is an example:
mpremote mount .
Local directory . is mounted at /remote
Connected to MicroPython at /dev/cu.usbmodem141201
Use Ctrl-] or Ctrl-x to exit this shell
>
MicroPython v1.20.0 on 2023-04-26; Raspberry Pi Pico W with RP2040
Type "help()" for more information.
>>> import os
>>> os.listdir()
['hello.py', 'serial_test.py', 'index.html', '.DS_Store', 'config.py', 'delay.txt', 'blink_key.py', 'wlan.py', 'favicon.png', 'microdot.py', '.gitignore', 'secrets.py', 'light_leds.py', 'blink_wo_delay.py', 'bulma.min.css', 'pin_test.py', 'computer.svg', '.git']
Confirm Board
Its helpful to confirm you are connected to a board, particularly, if you have mulitple boards connected to your computer. I use a version of the blink program to do this. The program is here and I use it in this manner:
mpremote mount .
# now I'm in mpremote connected to a board, with the PC folder as local storage
# if I don't have the REPL, hit Ctrl-B
>>> from blink_key import Blink
>>> Blink()
# and now the board connected to the mpremote program is blinking!
This allows me to immediately determine if my “empty” Pico can execute a command. I don’t need to load it with the blink program, I am able to import it and execute it locally!
A single line program is this:
mpremote mount . exec "from blink_key import Blink; Blink()"
However I have found that it requires a bit of work to stop it. The easiest thing to do is to press RESET on the Pico to stop.
Edit file
If you set your editor in the system environmental variable $EDITOR, mpremote will use it to enabling editing a file on the microcontroller. You use the EXPORT command in bash or the set command in the fish shell to do so. Once I did, I was able to enter mpremote edit main.py and the Pico version of main.py opened in my editor. Cool!
# make a simple change to the boot program
mpremote edit main.py
# edit the password in the secrets file
mpremote edit secrets.py
I wouldn’t recommend you use this as a code development practice, however, it works great for testing a quick and dirty fix to a program. For example, let’s say you are attempting to connect to a new wireless LAN and you use the secrets file for the SSID and password. You could use mpremote edit secrets.py to edit the file on the Pico and quickly change the SSID/password to new values.
Specific Connection
The mpremote connect command is of value when you have multiple microcontrollers attached to you PC. Here is an example, where I have two Picos attached:
ls /dev/cu.*
/dev/cu.BLTH /dev/cu.JabraEvolve65 /dev/cu.usbmodem141301
/dev/cu.Bluetooth-Incoming-Port /dev/cu.usbmodem141201
mpremote connect /dev/cu.usbmodem141201 fs ls
ls :
206838 bulma.min.css
2837 computer.svg
18 config.py
1245 draw.html
1264 lost.html
4165 main.py
46276 microdot.py
1331 microdot_utemplate.py
36 secrets.py
0 templates/
0 utemplate/
1464 wlan.py
1241 won.html
Or combine the hint using blink along with the connect command to blink a specific Pico led:
mpremote connect /dev/cu.usbmodem141201 mount . exec "from blink_key import Blink; Blink()"
Execute local files
A local file is one which resides on your PC, not on the microcontroller. The run command provides the capability of running the local file on your microcontroller without downloading it first. For example, another way to blink the led on a connected board would be:
# you may also use the run command to execute the local file on the Pico
mpremote connect /dev/cu.usbmodem141201 run blink_key.py
Notice that the blink_key.py file is not on the Pico (see the fs ls example above), and the run command is executing the local file (one which resides on your PC) on the microcontroller. Again, I needed to use Ctrl-C to disconnect from the board.
Build an Application
As you begin to develop more complex programs, you will need to copy files to the Pico in a structured way. If you don’t, you might end up with a version control nightmare. As I developed the multiple versions of microserver, I realized I needed a way to easily delete all the files and reload the Pico with a new set.
The first command and possibly dangerous command is ’littlefs_rp2’. This command will reformat your storage on the Pico. It is the rm -rf /
for the Pico. Only use it when you know you have backed up all of the files on your Pico! Thank you @jimmo
The second command uses a python application I wrote called mpbuild. It uses a text file to describe the files to copy to the board. There is a very simple syntax, which is described in the file:
# requires a text file containing the following:
# lines starting with '#' are comments and ignored
# lines starting with '/' are directories and are created
# lines starting with '!' are files to be copied and renamed,
# two fields are required, separated by a ',', localname, piconame
# 1 line starting with '+' will be copied to main.py
# directory lines must appear prior to the files in the directories
# all other lines are considered valid files in the current directory
# PYBOARD_DEVICE environmental variable must be set to board serial port
A example file would be:
# light_leds_v4 files
/templates
/utemplate
computer.svg
microdot.py
microdot_utemplate.py
secrets.py
wlan.py
+light_leds_v4.py
templates/marx.css
utemplate/compiled.py
utemplate/recompile.py
utemplate/source.py
!templates/index_v4.html,templates/index.html
!templates/configured_v4.tpl,templates/configured.tpl
This file will create the following on the Pico W:
mpbuild.py files_v4.txt
/
2837 computer.svg
2645 main.py
46368 microdot.py
1331 microdot_utemplate.py
36 secrets.py
0 templates/
0 utemplate/
2346 wlan.py
/templates/
652 configured.tpl
1302 index.html
18120 marx.css
/utemplate/
380 compiled.py
593 recompile.py
6085 source.py
Connected 0.0 secs
I typically use it in this situation:
# delete all files on the Pico
mpr littlefs_rp2
# build a new application on Pico
mpbuild files_v4.txt
The program mpbuild does require CoolTerm_pip to be installed to automate disconnection and re-connection to CoolTerm, please see this entry to install or comment out the following lines in mpbuild.py:
17 from CoolTerm.CT_connect import conn
18 from CoolTerm.CT_disconnect import disc
66 disc()
132 conn()
Comments powered by Talkyard.