Monthly Archives: February 2022

RP2040 operating temperature

Yesterday we described the usage of Ethernet with RP2040 (Raspberry Pi Pico) using the W5100s-EVB-Pico board here:

As I started working today, I decided to let it connected to the power source to monitor its operation and robustness.

Here is a plot of the first minutes of operation using BIPES EasyMQTT:

After that, the temperature is stable at about 41 degrees Celsius:

The data is updated in real-time and open for anyone at the link (EasyMQTT tab):

https://bipes.net.br/beta2/ui/#ag86id

Building MicroPython for the Raspberry Pi PICO with Ethernet and WebREPL support

WizNet is offering a low-cost Raspberry Pi PICO with Ethernet: the W5100S-EVB-Pico at about 9 dollars worldwide. For example, it can be purchased at Digikey here. There are firmwares ready to download and use based on MicroPython and CircuitPython. I used this one and it worked fine:

https://github.com/Wiznet/RP2040-HAT-MicroPython

However, some features I really wanted and needed were not available on this build. So let’s build ours.

Quick solution

This post discusses several issues and steps to compile and use Ethernet for Raspberry Pi Pico. For a ready-to-use quick solution, just go to:

Compiling MicroPython

Building MicroPython for the Raspberry Pi Pico is very easy and well documented. The best resource and guide I found is the official documentation from the Raspberry Pi Foundation using the document Raspberry Pi Pico Python SDK:

As explained in the above document, the commands to build Raspberry Pi Pico are:

mkdir pico
cd pico
git clone -b master https://github.com/micropython/micropython.git
cd micropython
git submodule update --init -- lib/pico-sdk lib/tinyusb
sudo apt update
sudo apt install cmake gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential
make -C mpy-cross
cd ports/rp2
make

After the build is done, the firmware built (firmware.uf2) will be available at the directory build-PICO.

Now we can install picotool to check the modules included as builtins in the firmware. picotool install is explained here:

mkdir pico
cd pico 
git clone -b master https://github.com/raspberrypi/pico-sdk.git
git clone -b master https://github.com/raspberrypi/picotool.git
cd picotool
sudo apt-get install libusb-1.0-0-dev
mkdir build
cd build
export PICO_SDK_PATH=~/pico/pico-sdk
cmake ../
make

Before running cmake ../, edit CMakeFiles.txt and add:

install(TARGETS picotool RUNTIME DESTINATION bin)

install(TARGETS picotool RUNTIME DESTINATION bin)

This solved a compilation bug for me, as reported here.

Now we can use picotool with the built firmware:

./picotool info /home/rafael/builds/pico/micropython/ports/rp2/build-PICO/firmware.uf2 
File /home/rafael/builds/pico/micropython/ports/rp2/build-PICO/firmware.uf2:

Program Information
 name:            MicroPython
 version:         v1.18-128-g2ea21abae
 features:        USB REPL
                  thread support
 frozen modules:  rp2, _boot, ds18x20, onewire, dht, uasyncio, uasyncio/core,
                  uasyncio/event, uasyncio/funcs, uasyncio/lock,
                  uasyncio/stream, neopixel

This default configuration lacks some important modules. MicroPython allows us to add other modules by editing the manifest file:

File vi rp2/boards/manifest.py original contents is:

freeze("$(PORT_DIR)/modules")
freeze("$(MPY_DIR)/drivers/onewire")
freeze("$(MPY_DIR)/drivers/dht", "dht.py")
include("$(MPY_DIR)/extmod/uasyncio/manifest.py")
include("$(MPY_DIR)/drivers/neopixel/manifest.py")

We have to edit it and add some lines, so manifest.py will have these contents:

freeze("$(PORT_DIR)/modules")
freeze("$(MPY_DIR)/drivers/onewire")
freeze("$(MPY_DIR)/drivers/dht", "dht.py")
include("$(MPY_DIR)/extmod/uasyncio/manifest.py")
include("$(MPY_DIR)/drivers/neopixel/manifest.py")

freeze("$(MPY_DIR)/tools", ("upip.py", "upip_utarfile.py"))
freeze("$(MPY_DIR)/drivers/display", "ssd1306.py")
include("$(MPY_DIR)/extmod/webrepl/manifest.py")

# Libraries from micropython-lib, include only if the library directory exists
if os.path.isdir(convert_path("$(MPY_LIB_DIR)")):
    # file utilities
    freeze("$(MPY_LIB_DIR)/micropython/upysh", "upysh.py")

    # requests
    freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py")
    freeze("$(MPY_LIB_DIR)/micropython/urllib.urequest", "urllib/urequest.py")

    # umqtt
    freeze("$(MPY_LIB_DIR)/micropython/umqtt.simple", "umqtt/simple.py")
    freeze("$(MPY_LIB_DIR)/micropython/umqtt.robust", "umqtt/robust.py")

Some of these libraries are on another github repository. So we need to cline micropython-lib repo to use umqtt, urlib and requests. This way:

git clone https://github.com/micropython/micropython-lib

Now we can build the firmware again:

make -C mpy-cross
cd ports/rp2
make

And the resulting firmware now has the modules we need:

./picotool info /home/rafael/builds/pico/micropython/ports/rp2/build-PICO/firmware.uf2 
File /home/rafael/builds/pico/micropython/ports/rp2/build-PICO/firmware.uf2:

Program Information
 name:            MicroPython
 version:         v1.18-128-g2ea21abae-dirty
 features:        USB REPL
                  thread support
 frozen modules:  rp2, _boot, ds18x20, onewire, dht, uasyncio, uasyncio/core,
                  uasyncio/event, uasyncio/funcs, uasyncio/lock,
                  uasyncio/stream, neopixel, upip, upip_utarfile, ssd1306,
                  webrepl, webrepl_setup, websocket_helper, upysh, 
                  urequests, urllib/urequest, umqtt/simple, umqtt/robust

Ethernet and Raspberry Pi Pico

Ok, now let’s add ethernet support! Consider that the last section was an exercise (at least it was for me). So, the next operations can be done independently from the ones already discussed. The firmware sources are based on https://github.com/Wiznet/RP2040-HAT-MicroPython.

git clone https://github.com/rafaelaroca/RP2040-HAT-MicroPython
cd RP2040-HAT-MicroPython
git submodule add https://github.com/micropython/micropython-lib/
cmake CMakeLists.txt
cd libraries
make -C mpy-cross
cd ports/rp2
make

The above commands will build a complete MicroPython firmware with Ethernet support for the Raspberry Pi Pico with WIZNET W5100S (W5100S-EVB-Pico). Copy firmware.uf2 to the board and test it.

But, as we just did, we can edit the manifest files and add more features, like this:

freeze("$(PORT_DIR)/modules")
freeze("$(MPY_DIR)/drivers/onewire")
freeze("$(MPY_DIR)/drivers/dht", "dht.py")
include("$(MPY_DIR)/extmod/uasyncio/manifest.py")
include("$(MPY_DIR)/drivers/neopixel/manifest.py")

freeze("$(MPY_DIR)/tools", ("upip.py", "upip_utarfile.py"))
freeze("$(MPY_DIR)/drivers/display", "ssd1306.py")
include("$(MPY_DIR)/extmod/webrepl/manifest.py")

# Libraries from micropython-lib, include only if the library directory exists
if os.path.isdir(convert_path("$(MPY_LIB_DIR)")):
    # file utilities
    freeze("$(MPY_LIB_DIR)/micropython/upysh", "upysh.py")

    # requests
    freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py")
    freeze("$(MPY_LIB_DIR)/micropython/urllib.urequest", "urllib/urequest.py")

    # umqtt
    freeze("$(MPY_LIB_DIR)/micropython/umqtt.simple", "umqtt/simple.py")
    freeze("$(MPY_LIB_DIR)/micropython/umqtt.robust", "umqtt/robust.py")

After editing the manifest file, let’s build the firmware again by simply running make.

Well, after all that, I am having trouble having WebREPL running. Details here: https://forum.micropython.org/viewtopic.php?f=21&t=11996

Anyway, the binary and ready-to-use firmware is here. If you cannot build, just download and use it:

https://bipes.net.br/firmwares/firmware_rpi_pico_ethernet_13022022.uf2

I had problems with the requests module. The fix I did is explained here:

https://github.com/micropython/micropython/issues/8298

BIPES and Raspberry Pi Pico Ethernet

WizNet is offering a low-cost Raspberry Pi PICO with Ethernet: the W5100S-EVB-Pico at about 9 dollars worldwide. For example, it can be purchased at Digikey here. There are firmwares ready to download and use based on MicroPython and CircuitPython.

If you want to quickly get started, just use this firmware I built:

https://bipes.net.br/firmwares/firmware_rpi_pico_ethernet_13022022.uf2

Next, just use BIPES with your RPI Pico (RP2040) + Ethernet.

Example 1: web client (HTTP GET)

Example result:

=== 
Trying to access http://bipes.net.br
Network connection status: True
HTTP Request result = b'BIPES Test: Live long and prosper!\n\n'
Date and Time from BIPES Server = b'2022-02-13 03:01:18pm'
>>> 
>>> 

Direct link to the program:

https://bipes.net.br/beta2/ui/#a97vw5

Example 2: send temperature using MQTT

Example result:

=== 
0
EasyMQTT connected
Network connection status: True
Trying to publish temperature to MQTT server...
EasyMQTT Publish - Session: ftxr7b Topic: temperature Value: 38.74783
Trying to publish temperature to MQTT server...
EasyMQTT Publish - Session: ftxr7b Topic: temperature Value: 40.62041
Trying to publish temperature to MQTT server...
EasyMQTT Publish - Session: ftxr7b Topic: temperature Value: 41.08855
Trying to publish temperature to MQTT server...
EasyMQTT Publish - Session: ftxr7b Topic: temperature Value: 41.08855
Trying to publish temperature to MQTT server...
EasyMQTT Publish - Session: ftxr7b Topic: temperature Value: 41.5567
Trying to publish temperature to MQTT server...
EasyMQTT Publish - Session: ftxr7b Topic: temperature Value: 41.08855
Error sending data. Network may be down.
Trying to publish temperature to MQTT server...
EasyMQTT Publish - Session: ftxr7b Topic: temperature Value: 40.15226

I removed the Ethernet cable during this program execution, and the try-catch detected it and alerted us (“Error sending data”).

Direct link to the program:

https://bipes.net.br/beta2/ui/#97vwqz

Updated version, ready to be saved and executed at BOOT:

https://bipes.net.br/beta2/ui/#x7maeo

IOT tab result:

Useful reference:

https://github.com/Wiznet/RP2040-HAT-MicroPython