A quick way to talk to a Raspberry PI without monitor

A quick way to SSH into a Raspberry PI without a monitor, but that you can connect a direct Ethernet cable from your computer to the Raspberry Pi.

Physical connection:
– Connect an Ethernet cable directly from your computer ethernet port to the Raspberry Pi Ethernet port.

On your PC, setup a temporary DHCP Server with the command:

# ifconfig enp1s0f1 up 10.13.0.1 netmask 255.255.255.0; dnsmasq –port 0 –no-daemon –interface enp1s0f1 –dhcp-range=10.13.0.2,10.13.0.2

(In my case, the Ethernet network adapter is: enp1s0f1)

Example of the command output:
dnsmasq: started, version 2.86 DNS disabled
dnsmasq: compile time options: IPv6 GNU-getopt DBus no-UBus i18n IDN2 DHCP DHCPv6 no-Lua TFTP conntrack ipset auth cryptohash DNSSEC loop-detect inotify dumpfile
dnsmasq-dhcp: DHCP, IP range 10.13.0.2 — 10.13.0.2, lease time 1h
dnsmasq-dhcp: DHCPDISCOVER(enp1s0f1) b8:27:eb:72:95:02
dnsmasq-dhcp: DHCPOFFER(enp1s0f1) 10.13.0.2 b8:27:eb:72:95:02
dnsmasq-dhcp: DHCPREQUEST(enp1s0f1) 10.13.0.2 b8:27:eb:72:95:02
dnsmasq-dhcp: DHCPACK(enp1s0f1) 10.13.0.2 b8:27:eb:72:95:02 raspberrypi

The DNSMASQ
Then you can easily:

ssh pi

Please, be careful not to use this setup / command while connected to a network / switch / hub.

Raspberry Pi Pico robustness with MicroPython and Ethernet (W5100S-EVB-Pico)

In My Humble Opinion (IMHO), when a cabled infrastructure is available, an Ethernet connection is much better than Wifi for fixed IoT applications. However, I missed a good cost-benefit solution for DIY enthusiasts. Wiznet W5100S-EVB-Pico (Raspberry Pi Pico with Ethernet) was the answer to what I wanted. I got some as soon as they were available, but the firmware was unstable.

But now we have the official MicroPython support for the W5100S Ethernet chipset on the Pi Pico! And it works great! I downloaded the firmware (v1.19.1 (2022-06-18) .uf2) from https://micropython.org/download/W5100S_EVB_PICO/ and installed it on the board, by simply “dragging and dropping” the downloaded file to the Pi Pico USB Disk!

Tests performed on the Pi Pico with Ethernet (W5100S-EVB-Pico)

Init network:

from machine import Pin,SPI
spi0=SPI(0,2_000_000, mosi=Pin(19),miso=Pin(16),sck=Pin(18))
nic = network.WIZNET5K(machine.SPI(0), machine.Pin(17), machine.Pin(20))
nic.active(True)
nic.ifconfig()

DHCP over Ethernet works nicely!

Test 1 – MQTT with BIPES

Test took 7 hours. Here is the program used:

No data was lost – all data sent was received! on the server

BIPES Console:

EasyMQTT Publish - Session: 5y927 Topic: Test Value: 25193
Uptime: 25573.52
EasyMQTT Publish - Session: 5y927 Topic: Test Value: 25194
Uptime: 25574.52
EasyMQTT Publish - Session: 5y927 Topic: Test Value: 25195
Uptime: 25575.52

During all the tests, a ping flood was running against the Pi Pico board!

0% packet loss

rafael@vaio:~$ time sudo ping -f 192.168.88.234
[sudo] password for rafael: 
PING 192.168.88.234 (192.168.88.234) 56(84) bytes of data.
....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................^C  
--- 192.168.88.234 ping statistics ---
1884598 packets transmitted, 1884068 received, 0% packet loss, time 25303297ms
rtt min/avg/max/mdev = 2.326/29.941/74.117/20.287 ms, pipe 5, ipg/ewma 13.426/28.825 ms

real	421m47,266s
user	1m1,598s
sys	5m7,648s

Test 2 – MQTT and HTTP simultaneously

A more complete test, using MQTT and HTTP at the same time! With and without ping flood during the tests.

Up to now, tests were done with the board connected to a PC. After some time, on some cases, running the MicroPython garbage collector (gc) is a good idea:

import gc
gc.collect()
gc.mem_free()

For the curios, here is the code automatically generated by BIPES and uploaded to the board to perform the test mentioned:

>>> 
paste mode; Ctrl-C to cancel, Ctrl-D to finish
=== import umqtt.robust
=== from machine import ADC
=== from machine import Pin
=== import time
=== import urequests
=== 
=== mqtt_error = None
=== mqtt_sent = None
=== http_error = None
=== http_sent = None
=== adc = None
=== temperature = None
=== uptime_seconds = None
=== R = None
=== 
=== adc4=ADC(4)
=== 
=== 
=== easymqtt_session = "5y927";
=== easymqtt_client = umqtt.robust.MQTTClient("umqtt_client", server = "bipes.net.br", port = 1883, user = "bipes", password = "m8YLUr5uW3T");
=== easymqtt_client.connect()
=== print("EasyMQTT connected")
=== mqtt_error = 0
=== mqtt_sent = 0
=== http_error = 0
=== http_sent = 0
=== while True:
===   adc = (adc4.read_u16()) * 0.00005035477225909819
===   temperature = 27 - (adc - 0.706) / 0.001721
===   uptime_seconds = (time.ticks_ms()
===   ) / 1000
===   print(''.join([str(x) for x in ['Uptime: ', uptime_seconds, ' | Temperature: ', temperature, ' | HTTP Sent:', http_sent, ' | HTTP Errors: ', http_error, ' | MQTT Sent:', mqtt_sent, ' | MQTT Errors:', mqtt_error]]))
===   print('Trying to publish to the MQTT server...')
===   try:
===     easymqtt_client.publish(easymqtt_session + "/" + 'uptime', str(uptime_seconds))
===     print("EasyMQTT Publish - Session:",easymqtt_session,"Topic:",'uptime',"Value:",str(uptime_seconds))
===     easymqtt_client.publish(easymqtt_session + "/" + 'temperature', str(temperature))
===     print("EasyMQTT Publish - Session:",easymqtt_session,"Topic:",'temperature',"Value:",str(temperature))
===     mqtt_sent = (mqtt_sent if isinstance(mqtt_sent, int) else 0) + 1
=== 
===   except:
===     print('Error sending MQTT data. Network may be down.')
===     mqtt_error = (mqtt_error if isinstance(mqtt_error, int) else 0) + 1
===   print('Trying to make HTTP GET Request...')
===   try:
===     R = urequests.get('http://bipes.net.br/date-time-test.php')
=== 
===     print(R.text)
===     http_sent = (http_sent if isinstance(http_sent, int) else 0) + 1
=== 
===   except:
===     print('Error sending HTTP data. Network may be down.')
===     http_error = (http_error if isinstance(http_error, int) else 0) + 1
===   time.sleep(1)
=== 
=== 
=== 
0
EasyMQTT connected
Uptime: 28137.88 | Temperature: 28.91677 | HTTP Sent:0 | HTTP Errors: 0 | MQTT Sent:0 | MQTT Errors:0
Trying to publish to the MQTT server...
EasyMQTT Publish - Session: 5y927 Topic: uptime Value: 28137.88
EasyMQTT Publish - Session: 5y927 Topic: temperature Value: 28.91677
Trying to make HTTP GET Request...
2022-09-08 04:36:27pm
Uptime: 28139.38 | Temperature: 32.66196 | HTTP Sent:1 | HTTP Errors: 0 | MQTT Sent:1 | MQTT Errors:0
Trying to publish to the MQTT server...
EasyMQTT Publish - Session: 5y927 Topic: uptime Value: 28139.38
EasyMQTT Publish - Session: 5y927 Topic: temperature Value: 32.66196
Trying to make HTTP GET Request...
2022-09-08 04:36:29pm
Uptime: 28140.89 | Temperature: 31.72567 | HTTP Sent:2 | HTTP Errors: 0 | MQTT Sent:2 | MQTT Errors:0
Trying to publish to the MQTT server...
EasyMQTT Publish - Session: 5y927 Topic: uptime Value: 28140.89
EasyMQTT Publish - Session: 5y927 Topic: temperature Value: 31.72567
Trying to make HTTP GET Request...
2022-09-08 04:36:30pm
Uptime: 28142.39 | Temperature: 31.72567 | HTTP Sent:3 | HTTP Errors: 0 | MQTT Sent:3 | MQTT Errors:0
Trying to publish to the MQTT server...
EasyMQTT Publish - Session: 5y927 Topic: uptime Value: 28142.39
EasyMQTT Publish - Session: 5y927 Topic: temperature Value: 31.72567
Trying to make HTTP GET Request...
2022-09-08 04:36:32pm
Uptime: 28143.89 | Temperature: 31.72567 | HTTP Sent:4 | HTTP Errors: 0 | MQTT Sent:4 | MQTT Errors:0
Trying to publish to the MQTT server...
EasyMQTT Publish - Session: 5y927 Topic: uptime Value: 28143.89
EasyMQTT Publish - Session: 5y927 Topic: temperature Value: 31.72567
Trying to make HTTP GET Request...
2022-09-08 04:36:33pm
Uptime: 28145.4 | Temperature: 32.19381 | HTTP Sent:5 | HTTP Errors: 0 | MQTT Sent:5 | MQTT Errors:0
Trying to publish to the MQTT server...
EasyMQTT Publish - Session: 5y927 Topic: uptime Value: 28145.4
EasyMQTT Publish - Session: 5y927 Topic: temperature Value: 32.19381
Trying to make HTTP GET Request...
2022-09-08 04:36:35pm
Uptime: 28146.9 | Temperature: 31.72567 | HTTP Sent:6 | HTTP Errors: 0 | MQTT Sent:6 | MQTT Errors:0
Trying to publish to the MQTT server...
EasyMQTT Publish - Session: 5y927 Topic: uptime Value: 28146.9
EasyMQTT Publish - Session: 5y927 Topic: temperature Value: 31.72567
Trying to make HTTP GET Request...
2022-09-08 04:36:36pm
Uptime: 28148.41 | Temperature: 32.19381 | HTTP Sent:7 | HTTP Errors: 0 | MQTT Sent:7 | MQTT Errors:0
Trying to publish to the MQTT server...
EasyMQTT Publish - Session: 5y927 Topic: uptime Value: 28148.41
EasyMQTT Publish - Session: 5y927 Topic: temperature Value: 32.19381
Trying to make HTTP GET Request...
2022-09-08 04:36:38pm
Uptime: 28149.91 | Temperature: 31.25752 | HTTP Sent:8 | HTTP Errors: 0 | MQTT Sent:8 | MQTT Errors:0
Trying to publish to the MQTT server...
EasyMQTT Publish - Session: 5y927 Topic: uptime Value: 28149.91
EasyMQTT Publish - Session: 5y927 Topic: temperature Value: 31.25752
Trying to make HTTP GET Request...
2022-09-08 04:36:39pm
Uptime: 28151.41 | Temperature: 32.19381 | HTTP Sent:9 | HTTP Errors: 0 | MQTT Sent:9 | MQTT Errors:0
Trying to publish to the MQTT server...
EasyMQTT Publish - Session: 5y927 Topic: uptime Value: 28151.41
EasyMQTT Publish - Session: 5y927 Topic: temperature Value: 32.19381
Trying to make HTTP GET Request...
2022-09-08 04:36:41pm
Uptime: 28152.91 | Temperature: 30.78938 | HTTP Sent:10 | HTTP Errors: 0 | MQTT Sent:10 | MQTT Errors:0
Trying to publish to the MQTT server...
EasyMQTT Publish - Session: 5y927 Topic: uptime Value: 28152.91
EasyMQTT Publish - Session: 5y927 Topic: temperature Value: 30.78938
Trying to make HTTP GET Request...
2022-09-08 04:36:42pm
Uptime: 28154.42 | Temperature: 32.66196 | HTTP Sent:11 | HTTP Errors: 0 | MQTT Sent:11 | MQTT Errors:0
Trying to publish to the MQTT server...
EasyMQTT Publish - Session: 5y927 Topic: uptime Value: 28154.42
EasyMQTT Publish - Session: 5y927 Topic: temperature Value: 32.66196
Trying to make HTTP GET Request...
2022-09-08 04:36:44pm
Uptime: 28155.91 | Temperature: 32.66196 | HTTP Sent:12 | HTTP Errors: 0 | MQTT Sent:12 | MQTT Errors:0
Trying to publish to the MQTT server...
EasyMQTT Publish - Session: 5y927 Topic: uptime Value: 28155.91
EasyMQTT Publish - Session: 5y927 Topic: temperature Value: 32.66196
Trying to make HTTP GET Request...
2022-09-08 04:36:45pm
Uptime: 28157.42 | Temperature: 32.66196 | HTTP Sent:13 | HTTP Errors: 0 | MQTT Sent:13 | MQTT Errors:0
Trying to publish to the MQTT server...
EasyMQTT Publish - Session: 5y927 Topic: uptime Value: 28157.42
EasyMQTT Publish - Session: 5y927 Topic: temperature Value: 32.66196
Trying to make HTTP GET Request...
2022-09-08 04:36:47pm
Uptime: 28158.91 | Temperature: 32.19381 | HTTP Sent:14 | HTTP Error

And here is the result of the ping flood executed while the test was running. Again, 0% packet loss.

rafael@vaio:~$ time sudo ping -f 192.168.88.234
PING 192.168.88.234 (192.168.88.234) 56(84) bytes of data.
........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................^C
--- 192.168.88.234 ping statistics ---
1644217 packets transmitted, 1643682 received, 0% packet loss, time 21810566ms
rtt min/avg/max/mdev = 2.374/29.950/71.460/20.327 ms, pipe 5, ipg/ewma 13.265/30.199 ms

real	363m30,596s
user	0m44,335s
sys	3m39,977s

Again, for the curious and interested in doing the same test, here is the source code used on the server side (date-time-test.php) and the number of lines of the log file date-time-test-log.txt.

root@bipes-1:/var/www/html# cat date-time-test.php 
<?php
$d=date("Y-m-d h:i:sa");
echo $d;
file_put_contents('/var/www/html/date-time-test-log.txt', $d . "\r\n", FILE_APPEND | LOCK_EX);
?>

root@bipes-1:/var/www/html# cat date-time-test-log.txt  |wc -l
14134

Additionaly, take a look at the last lines shown on the console tab. Ctrl+C was sent at the end of the console view to stop the program/test.

Uptime: 49970.19 | Temperature: 34.53454 | HTTP Sent:14133 | HTTP Errors: 0 | MQTT Sent:14133 | MQTT Errors:0
Trying to publish to the MQTT server...
EasyMQTT Publish - Session: 5y927 Topic: uptime Value: 49970.19
EasyMQTT Publish - Session: 5y927 Topic: temperature Value: 34.53454
Trying to make HTTP GET Request...
2022-09-08 10:40:19pm
Uptime: 49971.72 | Temperature: 34.53454 | HTTP Sent:14134 | HTTP Errors: 0 | MQTT Sent:14134 | MQTT Errors:0
Trying to publish to the MQTT server...
EasyMQTT Publish - Session: 5y927 Topic: uptime Value: 49971.72
EasyMQTT Publish - Session: 5y927 Topic: temperature Value: 34.53454
Trying to make HTTP GET Request...
2022-09-08 10:40:20pm
Traceback (most recent call last):
  File "<stdin>", line 54, in <module>
KeyboardInterrupt: 
>>> 

This last test took about 14 hours. Following figure shows the temperature log (BIPES EasyMQTT Tab) stable about 34 degrees Celcius during all the tests with ping flood running!

Test 3 – Same code, but stand alone operation

Now, the same tests, but without the USB port connected to a PC. Main program was saved as main.py using BIPES and executed directly on boot, using a 1 Amp power supply, without PC USB port.

The code and results (EasyMQTT tab) can be seen at:

https://bipes.net.br/ide/#xgpana

After a few days:

root@bipes-1:/var/www/html# cat date-time-test-log.txt |wc -l
438654

And here is the view of EasyMQTT tab:

For this last test, ping foold was not executed during all the test period. But, as a matter of curiosity, ping flood was executed at the end of the test to check if the board / MicroPython was still reliable handling incoming packets while sending HTTP and MQTT messages. Again, 0% packet loss!

rafael@vaio:~$ time sudo ping -f 192.168.88.234
PING 192.168.88.234 (192.168.88.234) 56(84) bytes of data.
.............................................^C 
--- 192.168.88.234 ping statistics ---
149836 packets transmitted, 149791 received, 0% packet loss, time 2004086ms
rtt min/avg/max/mdev = 2.331/29.901/69.679/20.265 ms, pipe 5, ipg/ewma 13.375/29.506 ms

real	33m24,115s
user	0m3,943s
sys	0m19,998s

Well, the conclusion is:

IMHO, W5100S-EVB-Pico with MicroPython is good to go!

A CubeSat programmed with BIPES!

The following photos show some CubeSats and a CanSat assembled on the OBSAT-EESC-USP-Zenith Probe for the 1st Brazilian Satellite Olympiad. The white CubeSat was developed based on the PION CubeSat Educational Kit and improved/modified by the DNASAT Team, from Pirassuninga-SP.

What is amazing is the high-quality photos taken from about 20km altitude using an ESP32-CAM board programmed with BIPES and attached to a meteorological balloon.

BIPES and the Raspberry Pi Pico W

Since the announcement of Raspberry Pi Pico, many great things have happened to BIPES Project (bipes.net.br), and many great projects have been created with the Raspberry Pi Pico! But a Wifi connection was a dream of every Pico enthusiast.

The recent announcement of the 6-dollar Raspberry Pi Pico (https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html) is a dream come true, and, in my humble opinion, the start of a new revolution for IoT, STEAM, educational robotics, and other areas! Thanks and congratulations Raspberry Pi Foundation!

Today, BIPES has more than 15 thousand users (underestimated by Google Analytics considering users using BIPES online at bipes.net.br/ide) with about 50 thousand sessions/solutions created!

Raspberry Pi Pico W works out of the box with BIPES, but we could not get one on our hands to test networking features! Anyway, we made the networking functions available and they should work, thanks to MicroPython. If you have one Raspberry Pi Pico W, help us test BIPES networking options with it! We hope to test too, soon!

Best regards and enjoy playing with your Raspberry Pi Picos W!

Blockly User Summit Hands-On

Boards in order of appearance and connection port (from left to right):

[Board 1 (8061); Board 3 (8063); Board 4 (8064); Board 5 (8065); Board 2 (8062)]

Live camera:

http://uc.bipes.net.br:8280/cgi-bin/mjpg/video.cgi?subtype=1

User: camera / Password: camera123

ESP8266 boards for remote tinkering with BIPES / Blockly

Five boards are available – one user at a time!

Board 1: ws://uc.bipes.net.br:8061 / Pass: bipes1

Board 2: ws://uc.bipes.net.br:8062 / Pass: bipes10

Board 3: ws://uc.bipes.net.br:8063 / Pass: bipes0003

Board 4: ws://uc.bipes.net.br:8064 / Pass: bipes04

Board 5: ws://uc.bipes.net.br:8065 / Pass: bipesFive

Program 1 – Write B to LED Matrix

http://bipes.net.br/ide/#noyrty

Open the URL above and connect to the board:

Program: L and O

http://bipes.net.br/ide/#xw59kk

Program: C

http://bipes.net.br/ide/#dsqdmm

Program: K

http://bipes.net.br/ide/#tzgf9f

Program – L and Y

http://bipes.net.br/ide/#6pkjiw

IoT Demo:

https://bipes.net.br/ide/#fgjyum

Access the link above and check the IOT and EasyMQTT tabs.

You can also view only the data (without the program):

http://bipes.net.br/freeboard#fgjyum

OR read the QR-Code on your phone:

BIPES Talk @ Blockly User Summit

Hello!

Tomorrow, we will have the honor to present BIPES Project at the Blockly User Summit (link below). BIPES is a unique open-source platform, that allows users to quickly create embedded and IoT solutions using visual block-based programming. BIPES is currently in use in more than 100 countries by more than 10.000 recurrent users!

http://bipes.net.br/ide/

https://developers.google.com/blockly

https://sites.google.com/view/blockly-user-summit-2022/agenda

Serial GUI with BIPES

Arduino, ESP32, ESP8266, Raspberry Pi, etc: we always need a quick and simple interface (GUI) to view data and send data to microcontroller boards. With a little help from Jorge Marques (https://github.com/gastmaier) now we can push strings to be sent to the Serial port. These strings can be prepared/customized on any HTML freeboard widget on BIPES IoT tab. Note that we can use this to send pre-defined serial messages to any serial device! Of course, as already done many times, you can also receive data and route it to the freeboard using BIPES data source, allowing serial data to be seen on any freeboard widget.

Direct link to the project:

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

To use it, create a new pane and add a HTML widget to the IOT tab with freeboard:

Then, click on JS Editor and paste the code for each widget:

You can type/build any user interface using HTML. It will be automatically saved and you can share with anyone when you share the BIPES project by URL. The important part is:

parent.bufferPush(cmd);

The parent.bufferPush(cmd); command will send a message from your Javascript/HTML GUI to the serial device connected to BIPES console on the web browser. There are some examples below, but you can build your own user interfaces!

Code for the slider:

<style>
.slidecontainer {
  width: 100%;
}

.slider {
  -webkit-appearance: none;
  width: 100%;
  height: 25px;
  background: #d3d3d3;
  outline: none;
  opacity: 0.7;
  -webkit-transition: .2s;
  transition: opacity .2s;
}

.slider:hover {
  opacity: 1;
}

.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 25px;
  height: 25px;
  background: #04AA6D;
  cursor: pointer;
}

.slider::-moz-range-thumb {
  width: 25px;
  height: 25px;
  background: #04AA6D;
  cursor: pointer;
}
</style>
</head>
<body>

<h1>Slider test</h1>
<p>BIPES and Freeboard</p>
<p>Send value to serial console</p>
<p>from freeboard!</p>

<div class="slidecontainer">
  <input type="range" min="1" max="65000" value="50" class="slider" id="myRange">
  <p>Value: <span id="demo2"></span></p>
</div>

<script>
var slider = document.getElementById("myRange");
var output = document.getElementById("demo2");
output.innerHTML = slider.value;

slider.oninput = function() {
  output.innerHTML = this.value;
  var cmd='pwm25.duty_u16(' + this.value + ')' + String.fromCharCode(10) + String.fromCharCode(13);
  console.log('cmd='+cmd);
  parent.bufferPush(cmd);  
}
</script>

Code for the buttons:

<h1>Button Test</h1>
<p>Send value to serial console
from freeboard!</p>

<center>
<br>
<button onclick="ligar()">LED On</button>
<br>
<br>
<button onclick="desligar()">LED Off</button>
<br>
<br>
<button onclick="pwm()">PWM Mode</button>

<p id="demo"></p>

<script>
function ligar() {    
      var cmd='gpio_set(25, True)' + String.fromCharCode(10) + String.fromCharCode(13);
      console.log('cmd='+cmd);
      parent.bufferPush(cmd);
}

function desligar() {    
      var cmd='gpio_set(25, False)' + String.fromCharCode(10) + String.fromCharCode(13);
      console.log('cmd='+cmd);
      parent.bufferPush(cmd);
}

function pwm() {    
      var cmd='pwm25 = PWM(Pin(25))' + String.fromCharCode(10) + String.fromCharCode(13);
      parent.bufferPush(cmd);
      var cmd='pwm25.freq(1000)' + String.fromCharCode(10) + String.fromCharCode(13);
      parent.bufferPush(cmd);    
}
</script>

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