Using MicroPython and Cloud Services
This project shows you how to measure some environmental data from a sensor and send it to a cloud server using the latest WiFi-enabled Raspberry Pi Pico W board. MicroPython makes this process easy.
When the Raspberry Pi Pico board was launched early last year, I was impressed by the amount of documentation for it, and the possibility of developing with MicroPython. The price was also impressive (less than $5), and it had a decent amount of I/O pins. But at the time, I was using the dual-core ESP32 SoC with built-in Wi-Fi, and that was something the Pico did not have, so I ignored it.
I later learned that the Pico had some additional tricks up its sleeve: The programmable I/O controllers acted as coprocessors, so the main core could offload some of the I/O complexity to help different devices and communication protocols. Not bad.
So, when the Raspberry Pi Pico W (Figure 1) was launched this past summer, I wasted no time before ordering some units. It seems Raspberri Pi orchestrated a well-thought-out release, with inventory in many countries across the globe—and they did that in the middle of a chip-shortage crisis. I guess congratulations are in order here.
I paid roughly $6 per unit, and I bought the Pico W because it included a built-in Wi-Fi interface, using the same form factor as the original Pico. I wanted to get first-hand experience with this board, not only because it was more powerful than other microcontroller boards, but also because it might be a better fit for my students. I teach a Physical Computing course for a Master’s degree program at a local university, and I am always willing to try what is new.
We have been using Arduino boards for many years with excellent results, but student projects often require wireless communication and Internet access. That is possible with some of the new Arduino boards (one includes the RP2040 chip, the same one that powers the Pico), but it is cumbersome with the older Arduino boards, namely the Arduino UNO and others.
MAKING THE MOVE
We have moved away from C++ for a couple of years and started using MicroPython with the ESP32. In short, beginners can experiment while learning more easily with interpreted languages. So, while many students have no previous knowledge of Python, it seems they get familiar with MicroPython very quickly. One of the reasons is our development tool—the open-source Python IDE called “Thonny,” developed at Tartu University, Estonia (Figure 2).
Once you develop in MicroPython, code can easily move from one architecture to another. I developed some lessons for the ESP32, but almost no changes are needed to use those with the Pico W. Please note that ESP32 does include some built-in peripherals that are not present on the Pico W. This article is not about comparing these two architectures, though.
SETTING UP THE PICO W
The board needs to get MicroPython interpreter code installed before we can use it to write code. If Thonny is the development tool, that setup process is quite simple. First you need to figure out what serial port the Pico W board uses. How you do that depends on your operating system in the development computer. Windows users can use the Device Administrative Tool to see what new serial port appears when connecting the Pico W board. OSX and Linux users can look for the new device that pops up on the “/dev” folder when connecting the board to the computer USB port.
You can skip this first step and let Thonny software figure out the Pico’s serial port. You go to the “Run/Select interpreter” menu and select that you have a Pico board. (There is not a Pico W option at the moment, but the Raspberry Pi Pico option will be fine.)
A binary file containing MicroPython firmware can be downloaded from MicroPython’s website , where you can find several recent versions of it. Just get the latest by downloading the UF2 file onto your computer. The firmware file is burned into the Pico board very simply: unplug the board and plug it back in while you press the BOOTSEL button. A new flash disk drive named “RPI-RP2” will appear in your system. Copy the UF2 file you just downloaded to the root folder of that drive. The Pico board will automatically burn it to its flash memory, and it will reboot the Pico board. (Then the flash drive will disappear.)
If all goes well, you will be able to see a banner on the “Shell” pane of the Thonny software with the version and date of the installed firmware (Figure 3). From then on, you can type direct Python commands in the pane, and they will be executed immediately by the interpreter code running on the Pico. If you do not get anything, or there is a warning message in red, try pressing the red “Stop” icon on the Thonny top toolbar. That would reset the Pico W and reconnect the Shell pane showing the MicroPython banner.
IT IS ALIVE
Once you have successfully installed MicroPython on the Pico W board, you can start testing all the different features. You can use the Shell pane to send commands that will be answered right away; there’s no need to write a program or compile it. Try typing “3+4” to get the answer as soon as you press the “Enter” key.
The commands shown in Figure 4 will activate the Wi-Fi interface as a regular station, performing a network scan that will show you the available networks in your neighborhood. It should not be much different than your computer’s list (in case it is equipped with Wi-Fi).
CONNECTING THE PICO W TO YOUR HOME WI-FI NETWORK
Connecting to your home network is a task you most likely will want the Pico W to do often, so you may want to write it down as a program you can invoke any time, without repeatedly typing the command sequence. But if you have already typed the network scan commands above, you can add w.connect(“your_wifi_ssid”,” your_wifi_password”) to connect the board to your Wi-Fi network. You can check the successful connection with the command w.ifconfig() that will print out the Pico’s IP address, network mask, gateway, and DNS server.
A code snippet that packs all that plus some additional error checking in case things do not work correctly is shown in Figure 5.
Once your board is connected to your home network, and assuming it has Internet connectivity, it is possible to install new libraries onto the board, as shown in Figure 6. You can check the /lib folder inside your Pico W board storage afterward.
This brings up an important point. You can store multiple files (usually Python code) onto the Pico board storage space. Every time you want to save a new program file created with Thonny software, you are asked whether the file will be saved onto the computer or on the Pico board. All the files stored on the board can be read or written by MicroPython code. Local storage comes in handy if your code needs to read or write any data, such as a look-up table, a list, or a certificate.
CONNECTING SOME ADDITIONAL HARDWARE
In our project, that additional hardware is a Bosch BME680 environmental sensor, which can measure temperature, barometric pressure, relative humidity, and air quality. The latter requires some processing that the sensor manufacturer does not explain, but binary code for specific architectures is provided. We will ignore that for the moment, and refer to it just as a fourth measured environmental factor.
The BME680 features an I2C interface and works at 3.3V, so the connection is quite straightforward, needing just power and two additional I/O for SDA and SCL I2C signals.
As shown in the Pico W pinout diagram (Figure 7), the two built-in I2C ports can be assigned to different pins. Our sample code uses I2C1 port with pins GP2 (4) as SDA and GP3 (5) as SCL.
Additional devices, such as an I2C display or any additional I2C sensors, could be connected using the same I2C bus, but for the sake of simplicity, only one device is used in this project.
It is convenient when we can use an existing library to handle a device, so we do not need to study the details on the sensor’s datasheet. There is also a risk that the code we use might be buggy. A quick Google search led me to an existing library made by Adafruit and ported to MicroPython (Figure 8). And I was getting sensor values in no time.
CONNECTING TO THE CLOUD
Data could be stored in the board’s flash memory for a while, but it has a limited capacity. We might want to be able to access the data without being in the same network as the board, and that might present an additional challenge. A simple solution is to avoid local data storage, and use cloud services for data storage and Internet access. Many different choices in the Internet of Things (IoT) scene offer free and premium services that will store and create graphs with your data in a customizable dashboard.
You need to set up an account to begin streaming sensor data. I have used the ThingSpeak service that calls itself “The IoT Platform with MATLAB Analytics.” They offer a free service (for non-commercial applications), with limits on how long data will be held and how often sensors can be updated. If you need more than that, you can buy a subscription. It is straightforward to get up and running with it. Once you have an account, you need to create a new channel and obtain your API write key, which is required for sensor values updates sent from your board (Figure 9).
Relying on a third party is unnecessary if you already have a server that can handle the additional task of storing and serving your data, but that could be enough for another project.
Please note that sending data to the server can be done with a simple HTTP GET request with the syntax detailed in the “Write a Channel Feed” box. Also, note that you can request new API keys as needed. Again, we could write the sockets code to perform the HTTP GET request, but we can use a library instead. In our case, the urequests library encapsulates a GET request in a single function.
I have set up the channel with four data fields that will store Temperature, Humidity, Pressure, and Air Quality values. Each update message will send the four fields packed inside an HTTP GET request. The default channel dashboard will show graphs of these four fields, with the last 60 values of each sensor variable. Depending on how often your board performs the updates, the dashboard will represent a different length of time.
Before going further, we will use dummy data to ensure the updates are working (Figure 10). We can use this sample code that uploads fixed values to the channel. Please note there is a message counter in the channel dashboard that counts the number of update messages received. Initially, it shows “Entries: 0,” and it will increase as successful updates are performed. For the code to be able to update your channel, it is imperative to change the API key value.
If all goes well, you should see that the number of received messages increases due to running the program shown in Figure 11. Each successful request should print a 200 status code. Once you have verified that all is working correctly with your account, we can move to integrate all the components into a single program.
PUTTING IT ALL TOGETHER
We want a program to perform sensor measurements and send the gathered data to the cloud periodically, as shown in Figure 12. The program needs to have Internet access through the Wi-Fi connection, and I2C communication with the BME680 sensor. The Pico W board might be powered by a phone charger with a micro USB plug, or with a power bank, in case we need it to be mobile. Batteries might not last a long time using the current code, however, since no effort has been made to reduce power consumption.
Please note that the connection code to the Wi-Fi network is included inside the Wi-Fi module that is imported. Once the network is up, the code connects to the I2C bus and the BME680, and then it sends a message update every 60 seconds.
It may look like all is done, but there are still a couple of details to take care of. We want this program to run every time the Pico W is powered. For this to happen, we need to name the program “main.py,” so it will be run after each reset. Another important aspect is that the “wifi.py” file has to be in the root folder of the Pico W storage with our correct Wi-Fi network name and password for it to connect. And do not forget to place the correct API write key on the “main.py” program. With all these details, you should be sending values to the cloud as soon as you power-up the board.
WHAT TO DO NEXT
I have presented this example as a way to introduce the use of the Pico W to send sensor data to an Internet server. What sensor you use and where and how you send that information may change widely. However, the underlying ideas might be pretty similar.
Others may require a different protocol. For example, you might set up a Mosquitto broker, and want the Pico W to send sensor updates using the MQTT protocol instead of HTTP. Or maybe your provider wants you to use HTTPS instead of HTTP. Most of the answers to what you may need are just a Google query away.
The beauty of the MicroPython approach is that the same code could work on a different processor with only minor changes (I/O pin numbers might need changing).
 MicroPython firmware download:
PUBLISHED IN CIRCUIT CELLAR MAGAZINE • NOVEMBER 2022 #388 – Get a PDF of the issueSponsor this Article