Ceci est une ancienne révision du document !
Many people think that the RPi Pico is a great little microprocessor, but because there is no “direct” support for networking, it’s not really worth it, even at its very low purchase price. I asked the MicroPython group if they thought that there was any update on networking support within MicroPython for the Pico, I was told that, at this point, there is no plan to provide that support, again due to the lack of networking hardware on the Pico. While I, too, am frustrated at the lack of networking, all is not lost. The Arduino Nano RP2040 is still in development and is supposed to have not only Wifi support, but also bluetooth, and a 9-axis IMU, and a microphone that should also support MicroPython. I’m guessing that it should be available in the next month or so, but we still don’t know how much it’s going to cost. For now, a couple of options are already available.
Just as an aside, in late April, 2021, the latest firmware for the RPi Pico, ESP8266, and the ESP32, is now at level 1.15. You can now download the latest firmware at https://micropython.org/download/. That having been said, everything presented this month will work on level 1.14. A list of changes to the various ports can be found at https://github.com/micropython/micropython/releases/tag/v1.15.
As I mentioned last month, the ESP-01 WiFi module is available, but so far, I haven’t been able to get it to work well enough to really suggest it. I’m still trying to get somewhere with it but have made only limited progress.
The good folks at Adafruit have a small networking coprocessor called the AirLift that will allow the Pico to connect to the internet and do just about anything that you need. You have to use CircuitPython on the Pico, but the project works well. You can find this project at https://learn.adafruit.com/quickstart-rp2040-pico-with-wifi-and-circuitpython .
I have tried this project and it works and works well. There are two big drawbacks for me, however. First, is that the project must be done under CircuitPython. The second is that the AirLift is about twice the price of the RPi Pico.
If you want a pure MicroPython solution that is less expensive, you are NOT out of luck. There is a project by some of the MicroPython developers that fills the bill. You can find the repository at https://github.com/peterhinch/micropython-mqtt. Basically, you use the RPi Pico and connect it to a ESP8266 via a 5-wire (plus 5Vdc and ground) interface. This allows the Pico to run things like a temperature sensor and report the data via the Internet to a MQTT server (broker), either local or hosted on the Internet. When I found this (thanks to the MicroPython group), I dropped everything and pulled an ESP8266 NodeMCU board that I purchased shortly after I got the RPi Pico. You can find various ESP8266 boards on the Internet for around $6.00 USD, which makes it a reasonably priced option.
Project of the month
So we’ll use this as the project of the month. This project will be broken down into multiple parts, the first will be to use the internal temperature sensor on the Pico to get the temperature, then we’ll set up the ESP8266 board and connect it to the Pico, and finally we’ll send the data via the Internet to a MQTT server. I’ll explain two server options, one based on a local Raspberry Pi computer, and one going to a free Internet server. When we are done, you will know how to use the internal temperature sensor and how to get that data to a MQTT server.
Part 1 - RPi Pico Temperature sensor
The first logical step is to write a test program that will read the internal temperature sensor on the Pico. We can access the sensor through the ADC (Analogue-to-Digital Converter) built into the Pico. ADC? Yes. The Pico actually has four ADC options, three available on the GPIO pins, and one internal that is dedicated to the temperature sensor. These are all 12-bit converters.
Using an ADC is really very easy. We provide a voltage into one of the pins – which comes in as a 16-bit unsigned integer – which will be a number from 0 to 65,535. In theory, the value becomes 0 for no voltage and 65,535 for the full 3.3 volts. Please be sure that your maximum voltage going into the ADC is 3.3 volts DC. Otherwise, you will overload the system and cause the magic blue smoke to escape. This will render the Pico non-functional!
While this is a nice way to view the range of voltages, and 65,535 is an easy way to visualize the fact that you are receiving the full 3.3 volts, it doesn’t quite relate in most people's minds. So, we can apply a little math to convert that value into a value that shows the “actual” voltage being applied to the pin. Since we know that the maximum voltage is 3.3 volts, and we know that when that voltage is applied to the pin, the ADC will respond with 65,535 at that voltage, we can simply create a conversion factor by dividing 3.3 by 65,535. Now we can see the actual voltage being applied to the ADC input pin. Let’s test this by taking 65,535 and multiplying it with (3.3 / 65535). That gives us 0.000050355 per unit. So if we have an input of 65535 and we apply our conversion factor, we will get 3.3. Amazing!
So we now know that the temperature sensor within the Pico returns an integer that we can use to get the temperature value. However, there is another formula that is specific to the Pico to get our final value. That formula is:
temperature = 27 - (reading - 0.706) / 0.001721
Where reading is our ADC value with the conversion factor applied. So assuming the average temperature inside of our house ranges between 22-24 degrees Centigrade, we can assume that our voltage value should be somewhere between 0.7139803 and 0.7107576 (22.36296 and 24.23554 C). The actual voltage reading has a tiny variance. Due to this, many factors can cause the reading to vary quite a bit. Some of this could be due to variance in the voltage provided to the Pico. Many people have commented on the temp sensor in the Pico not being very stable. For our purposes (at least here), it will do us well. I’m sorry for the long dissertation on the way that the ADC works, but I felt you should know.
So, let’s code our test program. First, as always, we need to import the needed libraries…
import machine import utime
Now we set up which ADC we will be using (remember, the temperature sensor is ADC # 4) and our conversion factor:
sensor_temp = machine.ADC(4)
conversion_factor = 3.3 / (65535)
We enter a “forever” loop (see above): read the temp sensor, apply the conversion factor, then apply the magic formula to get the temperature in Centigrade. We print the temperature into the console, and then sleep for 2 seconds before doing it all again. (If you can’t think in Centigrade, then apply the formula to convert to Fahrenheit).
If you wish, you can certainly add a display (like we did last month) to provide the reading without having to have Thonny (or your IDE of choice) visible all of the time.
Now that we have that done, let’s move on to downloading the MQTT software project.
Part 2 - Setting up the ESP8266
You can download the software that goes on both the ESP8266 and the Pico from https://github.com/peterhinch/micropython-mqtt. Go ahead and download the zip file or clone the repository. If you download the zip file, unpack it somewhere convenient. Once it’s unpacked, you will want to go into the main folder and find the sub folder “bridge”. This is where the software for both the Pico (host folder) and the ESP8266 (esp8266 folder) will be found. The other thing that you need to do is to open the file BRIDGE.md. This file contains all the information that you should need to get things up and running.
You know me, though. I’ll distill it down as much as I can to get you running as quickly as possible, but you really should read through the md file. If you don’t yet have a .md file reader, I suggest Typora which you can find at typora.io. I’ve tried countless .md readers and editors and this is by far the best one that I’ve found.
The first thing that you need to do is flash the bridge software onto the ESP8266. To do this you need to use a tool called esptool. There are various ways to install esptool, but the easiest way for Python programmers is to use pip (or pip3).
pip install esptool
or
pip3 install esptool
Once you have esptool installed, you will need to connect your ESP8266 board to your computer’s USB port. Just for safety’s sake, make sure that there are no other development boards (like the Pico) connected to your computer AND make sure that Thonny is closed. (If not, the flash might not work.) Once it’s powered up, you need to find out what port your linux machine sees the board connected to. In a terminal, type:
ls /dev/tty*
On my machine, I get a list that is 17 rows long and 6 columns wide. Buried around the middle is the actual port that I’m connected to – which, for me, is dev/ttyACM0. It’s important to know this port name, since you need to use it when you enter the CLI command lines. There are two steps, the first is to erase the existing flash memory contents, and the second is to load the modified firmware.
Now, using the same terminal that we just used to find the serial port, enter in the following command, replacing the port with that of your machine.
esptool.py –port /dev/ttyACM0 –baud 115200 erase_flash
This usually takes about a minute or so to complete. You should see something like this…
esptool.py v3.0 Serial port /dev/ttyUSB0 Connecting…. Detecting chip type… ESP8266 Chip is ESP8266EX Features: WiFi Crystal is 26MHz MAC: 8c:aa:b5:59:40:93 Uploading stub… Running stub… Stub running… Erasing flash (this may take a while)… Chip erase completed successfully in 16.1s Hard resetting via RTS pin…
Once the memory is erased, we need to load the new firmware. In the terminal, make sure that you are in the bridge folder and enter the following command (again replacing the port definition with that of your own)…
esptool.py –port /dev/ttyACM0 –baud 115200 write_flash –verify –flash_size=detect -fm qio 0 firmware-combined.bin
The terminal output should look something like this…
esptool.py v3.0 Serial port /dev/ttyUSB0 Connecting…. Detecting chip type… ESP8266 Chip is ESP8266EX Features: WiFi Crystal is 26MHz MAC: 8c:aa:b5:59:40:93 Uploading stub… Running stub… Stub running… Configuring flash size… Auto-detected Flash size: 4MB Flash params set to 0x0040 Compressed 622784 bytes to 409382… Wrote 622784 bytes (409382 compressed) at 0x00000000 in 36.1 seconds (effective 137.8 kbit/s)… Hash of data verified.
Leaving… Verifying just-written flash… (This option is deprecated, flash contents are now always read back after flashing.) Flash params set to 0x0040 Verifying 0x980c0 (622784) bytes @ 0x00000000 in flash against firmware-combined.bin… – verify OK (digest matched) Hard resetting via RTS pin…
During the flash process, there should be an LED flashing on the ESP8266 board as blocks of the firmware are being written. When the process is finished, the LED should stop flashing. If it continues to flash, something happened and you need to start again by erasing the firmware and re-installing it.
Now we can move on to making the connections to our Pico.
Part 3 - Connecting the Pico to the ESP8266
For whatever device you are going to use as the ESP8266 board, you should make sure you download the latest pinout for that board, since the various manufacturers can change the pinouts. In my case, the pinout for the NodeMCU ESP8266 board was found at https://components101.com/development-boards/nodemcu-esp8266-pinout-features-and-datasheet .
Now be sure to orient the board and the pinout and begin to place your jumpers. Luckily, the data pins on my NodeMCU board are all marked and they match up with the pins for the Mini in the table below. I verified the wires that I connected to the NodeMCU board at least three times then I made the connections to the breadboard that I had the Pico mounted on and verified them again. What can I say? I HATE to blow up boards. Of course, I did this with the boards all unplugged. I’ve copied the table here (left) just to make it easy for you.
Host and target must share a common ground. They need not share a common power
source - the order in which they are powered up is not critical. The 5V link enables a USB connection on the host to power the ESP8266.
We will be providing the power for the ESP8266 directly from the Pico. You can see from the wiring diagram on the next page, the 5 volts to power the ESP8266 comes from physical pin 40 – which is VBUS. VBUS provides +5Vdc directly from the Pico’s USB connection with your computer. This is important to remember if you ever want to make this a standalone project. You will have to provide the +5Vdc for the ESP8266 from another source.
So now the hard part is done.
Part 4 - The Pico side of things
Now, we can start to work on the Pico part of the project. There will be two files that we need to load and modify. The first file is net_local.py that is located in the bridge/host folder. You can think of this as your secrets file where you store your network router address, network password, and the location of your broker. Here’s what it looks like (without the comments). See code top right.
Set the ssid field to your network name. Change the password to the one you use to connect your computer to the network. Finally, for this test, set the broker field to “test.mosquitto.org”. Save the file. It should look something like the code shown middle right.
Now you need to load the file pico_simple.py from the bridge/host/generic folder. We won’t be changing too much, but we will make a couple of changes. I’ll present the entire file (minus the comments) and will put only the lines that need to be changed or added in bold.
First the import section. There is only one additional import needed here…
import uasyncio as asyncio
from pbmqtt import MQTTlink
import hw_pico as hardware # Pin definitions. Heartbeat on Pico LED.
import net_local # WiFi credentials
from utime import localtime, gmtime, time
The next line doesn’t get changed.
qos = 1 # for test all messages have the same qos.
Next, we will add a function to read the Pico internal temperature sensor (next page, bottom left). It’s almost the same as the test program we did in part 1 above. The only differences are that we are adding a call to printline, I’ve commented the 2 second sleep statement since we don’t need that and then the return temperaturef to the calling function. If you want to send out temperatures in Celsius, then return the variable temperature.
The publish function is where we actually send data out to the MQTT server. There are only two lines that need to be added. The first line prints the fact that we are sending something out and the second line actually publishes the internal temperature. Notice that this line is all one line (right).
There is one point that I want to make here. The line above – await asyncio.sleep(10) – sets the delay between the publish messages. If you want to speed it up, then set the sleep value to less than 10. If you want a longer delay between the publish messages, make it a bigger value.
MQTTlink.will('result', 'simple client died')
mqtt_link = MQTTlink(hardware.d, net_local.d, wifi_handler=(cbnet,()), verbose=True) #, debug=True
try:
asyncio.run(main(mqtt_link))
finally:
asyncio.new_event_loop()
When you run the program, you should see the onboard LED flash about every second, and in the shell window you should see…
%Run -c $EDITOR_CONTENT
initiator resetting target… initiator awaiting sync… initiator synchronised. Starting… 13:52:01 Status: Will registered 13:52:01 Status: awaiting default network 13:52:06 Status: awaiting broker 13:52:07 Status: connected to broker 13:52:07 Status: running About to run user program. cbnet: network is up 13:52:07 Status: WiFi up 13:52:07 Status: publish OK Sending 2 13:52:07 80.67992 Sending 3 13:52:18 78.9946
If you want to verify the fact that you are actually sending the messages out to the Broker, open a terminal on your computer (assuming you’ve installed the mosquitto packages) and type:
mosquitto_sub -h test.mosquitto.org -t InternalTemperature
Nothing will happen until you actually start sending, but when you are, here’s what it will look like.
greg@earth:~$ mosquitto_sub -h 192.168.1.67 -t InternalTemperature 79.83727 78.15195 78.9946 78.9946 78.9946
One word of warning. I’ve noticed that every time I have to stop the program to make a change or just to restart it, I have to unplug the Pico, wait a few seconds, then plug it back in. I’m not quite sure why.
I’d suggest that you consider setting up a MQTT server on another machine, like a Raspberry Pi. It’s simple to do. I previously wrote a three-part article in Full Circle issues 132, 133 and 134 which will get you going if you need it.
BONUS Part 6 - Monitoring your MQTT Communications
Yes, I’m providing a bonus part this month. I’m going to explain how to get and use a fantastic program called MQTT Explorer to monitor the communications between your Pico and the MQTT Server, wherever it is located.
You can find it at http://mqtt-explorer.com/ and download it as an AppImage from: https://github.com/thomasnordquist/MQTT-Explorer/releases/download/0.0.0-0.4.0-beta1/MQTT-Explorer-0.4.0-beta1.AppImage
It’s really easy to get set up and start monitoring your communications to the MQTT server. Since all we are sending is temperature values, you can also see the data as a graph.
You can find the code we’ve written and modified at my github repository at https://github.com/gregwa1953/FCM169_MicroThisMicroThat
Final Thoughts
Just so you know, I’m going to put the RPi Pico “on pause” so to speak, and look at another popular microcontroller, the ESP-32. This will be in the form of the SparkFun Thing Plus ESP-32 WROOM (https://www.sparkfun.com/products/15663) which you can pick up for around $21.00 USD. You can find other clone type boards for around $11.00 USD if your budget just won’t go the extra cost. We’ll be using a SSD1306 OLED display as well as the BMP180 and an Adafruit SI7021 Temperature/Humidity module (https://www.adafruit.com/product/3251 – about $9.00 USD) to show the different ways of programming the two modules. While you are thinking about things, you might consider getting a few Stemma QT/Qwiic cables. There are two types I would suggest: • The first has the molex on both ends, which makes quick work of connecting I2C devices to the Thing Plus (https://www.adafruit.com/product/4210) and other types of microcontrollers. • The other has the molex plug on one end and regular male pins for use on a breadboard (https://www.adafruit.com/product/4209).
We’ll be coming back to the RPi Pico in a couple of months, since I’ve got LOTS of goodies that can be done with the Pico.
Also, I’m working on a list of “important must have” sensors and displays along with sourcing and packaging. I’ll try to get that started for you in next month’s article as well.
Well, I’ve taken up way too many pages of the magazine this month, so I'm going to wish you luck and happy times.
Until next time, as always; stay safe, healthy, positive and creative!