Introduction to Microcontrollers and the Pi Pico W

Page against the machine
12 min readJun 30, 2022

--

This post is about MongoDB, the Internet of Things, and connecting a Raspberry Pi Pico W to MongoDB Atlas. But first, a little backstory about the new Pico W you should read first in case you don’t know it already.

Raspberry Pi made their name creating and selling cheap, single-board computers (SBC) as an affordable way for people to get a first desktop computer and to encourage children to learn to code in a world where consoles dominated the home market. These diminutive Linux PCs which could connect to a monitor or a television cost just $25 plus the cost of an SD card, keyboard, and mouse. Raspberry Pis rapidly became popular with hobbyists as an additional computer for projects due not only to the low price but also the exposed I/O pins which encouraged experimenting with homemade peripherals in a way an expensive desktop Windows PC never could.

A Raspberry Pi Single Board Computer
A Raspberry Pi Linux desktop computer.

Since 2014, Raspberry Pi has added new models to their range, from the tiny $5 pi zero — which was just as powerful as the original $25 model — right up to the 8GB, quad-core, 64 bit Pi 4, which is a very capable desktop replacement.

In 2021, the good people at Pi announced a new string to their bow. They had added an ASIC team to the workforce and then designed and built their first in-house chip (much the same way Apple added Apple Silicon to their devices). This chip, the rp2040, is a powerful modern microcontroller available both as a raw chip and as a development board, the Raspberry Pi Pico.

Unlike the Original RaspberryPi, which is essentially a small desktop PC, a microcontroller (MCU) is a whole computer on a single chip with program storage, RAM, and CPU all included. Microcontrollers don’t have an OS but rather run a single program written to them which they execute immediately on startup. That program normally has a dedicated purpose and without the distraction of an OS runs very much in real time. They are used for dedicated, critical compute tasks. Microcontrollers are all around us. A modern car will have dozens, managing the engine and other features. They exist in toys, smart light bulbs and kitchen tools, and even modern computer keyboards and mice have one inside.

As a “computer on a chip,” some older microcontrollers (like the ATTINY25 below) require almost no additional circuitry. I once created a pocket electronic game (Simon) using one eight legged MCU, four pushbuttons, four LEDs, a Buzzer, and a AA battery holder — nothing more. One enterprising user used one of these chip, wires, and nothing more to generate and transmit a TV signal to a nearby television!

A small black silicon chip with 8 legs
A Microcontroller from the 2000s with 2K of RAM

Modern MCUs like the RP2040, however, are tiny surface mount components, have many tiny pins, and require some supporting peripherals for stable power and USB support. Because of this, Raspberry Pi launched the Pi Pico — an RP2040 pre-soldered to a board with a USB port, timing, power circuitry, an LED, and the I/O pins attached to nice, easily-soldered holes. This development board meets the needs of the hobbyist and allows companies designing custom systems around the chip to experiment before building custom circuit boards.

A Raspberry Pi Pico board
A Pi Pico — a 2020s Microcontroller

That takes us to today, and my personal journey. Despite it having some interesting and unique features — including dual CPU cores (unusual in an MCU) and dedicated I/O sub processors — I’ve not experimented with the Pi Pico before now because I love small computers, but I almost always want to connect them to a larger universe.

The original Pi Pico development board did not include any networking capability and that was a roadblock for me moving to using it. I’m delighted, though, to hear that Raspberry Pi has now released the Pi Pico W. Following the naming convention from the Pi Zeros, the W means it has on-board Wi-Fi (and also bluetooth, but software support is not available at launch). Wi-Fi is provided by means of an external chip on the board. It’s not inside the RP2040 itself, but this means I can now have a powerful microcontroller with USB and Wi-Fi for $6 and that is definitely worthy of experimenting with. Also, the nice folks at Raspberry Pi gave me one in advance of the public launch to let me test it with MongoDB.

So, what are the advantages of an MCU over a small PC? What does adding Wi-Fi mean and where and how would I use this with Cloud — specifically MongoDB Atlas?

Microcontrollers have four advantages over small single board computers like the Pi Zero.

  1. Price: The Pico W is $6 versus $10 + SD card for the Zero W. This doesn’t seem like much but would be at manufacturing scale. Also, if manufacturing a product, you would likely put in just the RP2040 chip, which is $1. One dollar for a whole usable computer (that can play Doom!) is a bargain.
  2. Security: A computer with one program written to ROM is far harder for an external party to interfere with than something with a standard, well known OS and programs read from an SD card, especially when connected to Wi-Fi.
  3. Performance: This may seem counterintuitive as the Pico runs at 133 Mhz maximum. How can that be fast? An MCU has a single purpose, so it’s ability to respond to inputs and produce output quickly is enough to manage internal combustion engine timing and similar. Imagine doing that with a Windows PC! The RP2040 also has dedicated I/O coprocessors that allow it to, for example, generate video signals in real time without a dedicated graphics card or using its CPUs.
  4. Power usage: MCUs typically use far less power than a normal computer when running. The Pico uses 95mA (Compared to 250mA for a Pi Zero) at most but is also able to “sleep” and use <1mA when not being woken by a timer or hardware event. Firing up the Wi-Fi chip is slightly more power-hungry, so in a power-limited setting — for example, using a battery or solar power — we should use Wi-Fi only when required, not continuously.

When I got it, the Pico had MicroPython firmware installed. This single preloaded program is a Python interpreter which reads and runs Python files from the flash memory on the Pico.The Pico also offers a C SDK to write closer to the hardware (i.e., your own firmware), and I’m happy to use either. But this time, I chose Python. To use Python with a Pico, attach the Pico using USB, fire up the Thonny editor, write Python code, and click Run. Saving your Python as main.py on the device will make it start on boot.

I started off by calling the MongoDB Atlas Data API. The Atlas Data API is a sessionless subset of MongoDB’s excellent Query API exposed via HTTPS rather than using a driver library. It’s perfect for serverless environments or microcontrollers where no driver library is available.

Enabling the Atlas Data API to call from a Pi Pico

To enable the Atlas Data API, I logged into MongoDB Atlas at cloud.mongodb.com. (You can get a low-powered but free high-availability cluster forever to play about with.)

I created a free tier cluster (M0) and clicked “Data API” on the left-hand side to enable it.

A screenshot showing which link to click in MongoDB Atlas

On the next screen, I changed Cluster0 (my unimaginatively named database cluster) from “No Access” to “Read and Write” and took a copy of my URL endpoint (used to connect).

The MongoDB Atlas User Interface to get an API Key

I then clicked Create API Key on the left, gave my new key a name, and copied down the key it gave me.

Calling the Atlas Data API from the Pi Pico W

Calling the Atlas Data API from the Pi Pico W needs just a little Python to connect to Wi-Fi and make the HTTPS call using the urequests library. I opened up the Thonny IDE and ran this code by pressing “run.” Every time I run, it adds a new record to my deviceReadings collection.

Code running in the Thonny Editor

Save money and the planet with MongoDB and a Pi Pico W

Whilst it’s true that we can reduce energy and emissions by walking, cycling, and taking public transport pragmatically, many of us will continue to drive now and then. The price of vehicle fuel has also skyrocketed, so reducing our fuel consumption can help both the planet and our pockets. Most people care about at least one of those things. I personally changed my tires, removed my bike rack from the roof of my car, and started driving more carefully. By doing so, I moved from an average of 32 to 41 MPG (Imperial Gallon, 2 litre Diesel 4x4), so I am acutely aware there are savings to be had by better driving.

Regardless of your car, basic physics says that energy is used for acceleration, either in road speed or to combat gravity and drag. The faster you accelerate, the more fuel you burn. Conversely, rapid deceleration is normally throwing away stored potential energy in heat in the brakes. So logically, the less you accelerate and decelerate, the more energy-efficient you are. I appreciate this isn’t consistent — regenerative braking, for example, does not waste as much as brake pads, but the principle holds.

Whilst writing this article, I changed my car to an older and less economic model because it has more seats and carrying capacity. It doesn’t have an MPG meter though, and whilst I plan to make one using the CANBUS on the vehicle, that’s a future project. For now, I want to make a “How’s My Driving?” indicator that’s universal across vehicles and also reports your score to a centralised scoreboard so everyone can compete to be a smoother and more economic driver.

This is very similar to the telemetry devices fitted to vehicles either by the owners (in the case of vehicles driven by employees) or by car insurance companies offering discounts based on how well you drive.

Materials

For this project, I need a Pi Pico W, some kind of numeric display, and an accelerometer to measure how I’m driving. I’m also planning to power this from a USB battery pack but have that plugged into the car or a solar cell to continuously charge.

I will have this track the acceleration and deceleration, record them in a buffer, and then, when these drop to zero for a while (indicating the vehicle has parked), attempt to connect to Wi-Fi and upload data. My thinking is when I (or you) get home, it will connect to the home Wi-Fi. If you are like me and you have your mobile phone hotspot with the same credentials as your home Wi-Fi, it can also report through your phone when you park elsewhere.

I needed a simple visual display to give me a current score for my driving on this trip. For that, I’ve chosen one of my favourite components, a tm1638 board. These boards give you eight push buttons, eight LEDs, and eight 7-Segment Led Displays. Most use SPI to connect, so only three wires as well as power and earth are needed. I also had one sitting in my parts box not doing anything.

Also in my parts box, I see I have a few GY-521 modules left over from early versions of my Pi 4-based exercise bike/Playstation controller before I made it all bluetooth. These are very cheap at ~$3 each, so I will use one of these to measure acceleration. They can also measure gyroscopic precession and direction but I don’t need that. They need only two wires plus power as they are I2C-based.

I put these together on a small breadboard wired like this.

A diagram showing the circuit, components and connections.
A photograph of the completed telemetry device.

Code for the telemetry device with MicroPython and Thonny

The code is relatively simple MicroPython, although I did learn you need to explicitly call the garbage collector when fetching a lot of I2C data so as to not run out of RAM. The code reads 20 samples over one second and takes the average, which it then adds to a large buffer of most recent values. I’ve set this to hold two hours of data before overwriting older data. This should fit easily in the ~170KB of RAM I have available.

I use the forwards dimension of the accelerometer to determine the acceleration and braking of the vehicle. I also look at the vertical acceleration to determine when the vehicle is in motion versus when it’s parked. There is little or no vertical acceleration change in a stationary vehicle with the engine off.

When it’s stationary, it counts up to 30 seconds before attempting to upload data.

I also set it to go into a dormant state to preserve battery after 60 seconds and wake when I push a button.

The code for the device is here. It’s not beautiful but it’s fun to be able to build something so quickly in Python to run on a device. I usually build a messy imperative first version to test a concept. Then, if it becomes long-lived, rewrite as proper classes. This is my first time using Thonny and Python and I must say, I love it. Pi Picos will likely become my go-to MCU in future.

Easy code in the Cloud with Atlas Application Services

I was originally planning to have the device upload data to MongoDB using the Data API. However, I wanted to give you all access to write to my cluster securely and so decided on a customer HTTPS endpoint instead.

My endpoint has some additional authentication and verification requirements. I wanted to have users be able to specify a username and password (In the headers variable in the code) and have the back end verify that the password is the same one previously used with that username, effectively creating an application user on first login. I also calculate server time and add it, which is less easy in the Data API.

I’m also forcing a specific record format and making sure no one is writing to (or reading) other people’s data. All that is possible to configure in the Data API but far more complex than just creating a single custom function and endpoint as below.

The device sends a JSON array to the HTTPS endpoint rather than a document. This contains a set of readings. The server then verifies the credentials from the HTTPS header and records the user, readings, and date into a MongoDB Atlas cluster as a document with the following Atlas Serverless Function.

It’s configured from the HTTPS endpoints tab like this (and again, set to run the function as system):

The MongoDB Atlas User Interface to configure an HTTPS Endpoint

Using MongoDB Charts to visualise driving telemetry

I then used MongoDB Charts to generate a dashboard, which you can see here, with a High Score table of the best drivers out there as well as telemetry data for individual drivers. Feel free to build this and contribute/play along. I’m aware you could upload fake data but that’s not in the maker spirit. It would be great if someone else built one of these but in the meantime, it can keep me driving smoothly. You can learn about building charts.

View the live dashboard and see how folks are driving.:

It looks like this:

A dashboard showing the best drivers and telemetry from all drivers.

Conclusion

I’ve waited a while for the Pi Pico W. Thank you to Raspberry Pi for giving me one a little early. I love the Python_Thonny interface and this could definitely wean me off ESP32 boards simply because of the simplified developer experience.

Next step is to look at that complex but cool looking programmable IO (and build a CANBUS MGP meter).

MongoDB — well for me, with a little experience, it was trivial to record and graph this data. I hope you find it delightfully simple too.

--

--

Page against the machine

John Page is a Document database veteran, who after 18 years building full-stack document database technologies for the Intelligence community joined MongoDB.