Use Adafruit IO with a Raspberry Pi Pico W to create IoT dashboards using MQTT

I decided recently to set up a string of temperature sensors around our house to work out the temperature profile of different rooms.

With the recent release of the Pico W, I realised that I could do this quite simply, as long as I could find a way to “nicely” display the data.

You’ll have read my exploits with Anvil last week, I expect, and saw that I didn’t have much luck. However, I knew that Adafruit had their very own IoT platform – Adafruit IO – and that it had been around awhile, so I thought I’d give that a try and document it.

Set-up your Adafruit account

Go to and register an account if you don’t have one. You’ll be creating Feeds and Dashboards in a bit.

Assemble your hardware

For this project, I’m using:

  • A Raspberry Pi PicoW
  • An Adafruit AHT20 I2C temperature and humidity sensor

As you can see, I’ve soldered them together. I’ll put a 3D printed case together at some point, I’m sure.

Assemble your software

For this project, I’ve used Micropython for the PicoW and then loaded the Pico up with an MQTT client and an AHT library as follows:

The code

The code is in several files and can be found on my GitHub repository.

  • – the main code that holds it all together
  • – defines the “name of the device” by way of a “feed prefix” which is used to tie the Adafruit IO feeds together with the device.
  • – credentials etc. There’s a sample secrets file in the repository so you know what to put in it.
  • The two libraries as mentioned above.

Adafruit IO set-up

Set-up your with a feed prefix – this can be anything by mine’s called temp_sensor_1.

Then, create two feeds in Adafruit IO: <prefix>_temperature and <prefix>_humidity. For example, temp_sensor_1_temperature etc.

Create a dashboard by adding Graph boxes that bring in those feeds.


In theory, running the script through Thonny should show you the sensor readings as well as connection success/failure for wifi and notification of when the readings are published via MQTT to Adafruit IO.

You should end up with something like this on Adafruit:


If you’re trying to do this, you probably have questions – leave a comment and I’ll try and get back to you! 🙂

Use the Anvil IoT service to collect data from your Raspberry Pi Pico W

Anvil is a web app builder website that has just launched a new “IoT Toolkit” for the Raspberry Pi Pico W called the Pico Uplink. By downloading their UF2 image (which is MicroPython-based), you will be able to send data to their site and then create your own dashboard to view the data that has been collected.

What do I do?

First of all, take a look at their announcement blog post. This will give you a fair indication of whether their offering is suitable for what you’re trying to do. After that, take a look at their Pico page here.

You will need to sign up to Anvil – it is free to start with, but there are Pricing plans to take a look at if you’re going to use it in anger.

The following steps are part of their Get Started guide. I’ll write my observations as we go.

Get the firmware

Once you’ve confirmed your email address, you will need to download their UF2 firmware for the Pico W.

Make sure that you download the “complete” UF2 initially, then the Firmware only version after you’ve started writing your custom code.

Put your Pico W into bootloader mode (pull the power cable, press BOOTSEL and then plug it back in) and then drag the UF2 file to your Pico “drive”.

Interestingly, this gives you a PICO_W drive showing the code. This is how CircuitPython works, so it’s interesting to see this variant of MicroPython do that, too. Normally, you can only access it using Thonny, but this looks like you can get to the files through your File Explorer. For now, we’ll just use Thonny and see how we go!

Now, we’re going to use the Anvil Editor to build our “app”. This is using the beta version of their new version, so it will be interesting to see if it works! 🙂

As instructed, I created a Blank App using the Material Design theme.

I clicked the + icon, chose Uplink and then clicked Enable server Uplink. This gave me a long Uplink key. I copied this and pasted it into on the Pico W for safe keeping. Later on, I suspect I will want to put it into a config file and use a .gitignore file so that it’s hidden from GitHub.

For now, I’m ignoring the Python examples, but it could be potentially confusing if you’re not using full Python to see that!

Connecting to wi-fi and to Anvil

As instructed, I opened up and put in my wi-fi SSID and password. (This gave me something of a dilemma as my wi-fi is a bit spotty in the office!)

Having already put my Uplink key in, I knew I was ready to go.

I pulled the power and then re-inserted it. The LED went solid then flashed rapidly. This, according to the instructions, is what I was looking for as it means the wi-fi connection and the Anvil Uplink both work.

If you want to re-run the code in Thonny, make sure you’re on when you hit F5 as doing that with means it doesn’t “move on”.

Create an action button

In the Anvil editor, I dragged a button into the main window and gave it the code as instructed:

def button_1_click(self, **event_args):
  """This method is called when the button is clicked"""'pico_fn', 18) # Choose any number you like!

I then ran the Anvil app, clicked the button on the right hand side and saw the Pico’s onboard LED flash rapidly! That’s exciting – clearly the Pico W is polling Anvil somehow to see if something’s been clicked to activate the code.

Publishing the app

I want this on the web as a public app. I clicked Publish and then chose to get a Public URL. It gave me the URL, bizarrely and randomly: Apparently, you can change that to something else if you want, which is neat.

I then accessed that public URL and, lo and behold, by button flashes my Pico W LED.

What next? Internet of Things data display!

Well, that’s interesting and simple, but it’s not really “Internet of Things” as I understand it. For that, I need sensors to be sending data to Anvil, store it there and display it on a dashboard.

Fortunately, the Pico has an on-board temperature sensor. Now, it’s not great for taking the temperature of the surrounding air, but it will give you a reading of the temperature of the board itself. Here’s the code:

from machine import ADC

sensor = ADC(4)
conversion_factor = 3.3 / 65535
temp_reading = sensor.read_u16() * conversion_factor
real_temperature = 27 - (temp_reading - 0.706) / 0.001721

So, I added that to my and it printed out 29.85… which is a reading, ignoring how accurate for a moment.

How do I get that to Anvil?

First of all, in the Default Database, I created a new table called temperature_readings with three fields: source, temperature_reading and reading_date_time.

Then, I added a new Server Module and wrote a new function based on the Advanced Tips page.

def record_temperature(source, temperature_reading):
  app_tables.temperature_readings.add_row(source=source, temperature_reading=temperature_reading,

This should, if I’m correct, be a function which records into the new table anything I ask it to. I included the “source” column so that I could have multiple temperature sensors stored in the same table. I’m hoping that’s the write approach!

I then created a button which would call the Pico and tell it to get the temperature sensor data from the Pico and put it in a table:

def button_1_click(self, **event_args):'record_visitor')

This is great, of course, but what I really want is for the Pico to push the data to Anvil, not do it “on request”.

So, I think what I need is some kind of scheduler on the Anvil side to poll the Pico. Let’s see, what can I find with a quick Google:

Ah. Scheduled Tasks. From reading the page, it’s clear that that is what I want – to poll a sensor using the Uplink functionality. BUT!

Scheduled Tasks are available on the Personal Plan and above. £10 a month. Oh. Guess I won’t be able to then! Oh well. It’s useful, then, if you just want to poll-on-request, but not for gathering data… At least, not unless you pay.

Create an access point with the Raspberry Pi Pico W, serve a web-page and flash the on-board LED

Following various examples, I’ve created a MicroPython script that does the following:

  • Create an access point on the Raspberry Pi Pico W.
  • Create a web server.
  • Serve a simple page on that web server.
  • Toggle/flash the on-board LED when that page is loaded/refreshed.

TL;DR – see the code here

Download MicroPython and install it

First of all, you’ll need to download the latest MicroPython UF2. The one I’m using is v1.19.1-108-g474c47d59 (2022-07-08) .uf2 from this page. I found out via the Raspberry Pi forums that there was something broken on versions earlier than the 07-05 one – check out the thread here.

Next, you will need to put the Pico into bootloader mode and then drag the UF2 file to the external device that comes up.

Initial access point

Use Thonny to program the initial code:

import socket
import network

ssid = "PicoW"
password = "123456789"

ap = network.WLAN(network.AP_IF)
ap.config(essid=ssid, password=password)

while == False:

print("Access point active")

Despite setting the SSID, to start with I got a generic wi-fi name starting with “PICO”. In order to get PicoW working, I had to power cycle the Pico (rather than just CTRL-D and run again). This is behaviour described here on the RP forums.

I tried connecting to it using my mobile and success – I could connect to the access point, but had no Internet (as expected, obviously).

Serving a web page

Now, I want to serve a web page of some kind from the Pico W, otherwise it’s pretty useless. What’s the point in having an access point that does nothing?

I found this MicroPython library called tinyweb which is like Flask, but for MicroPython instead of full-blown Python. This I can use to establish “routes” which will deliver specific content via the web browser.

tinyweb requires, as it says in the README, the logging library. I had to scratch around to find that, so here it is.

I uploaded the tinyweb folder and the file to the PicoW and added

import tinyweb

at the top of the code. This ran correctly, so I then looked at the tinyweb documentation for how to create a web server.

I added some more code (which you can see on my own GitHub repo – WordPress is doing VERY weird things if I paste it in here!)

I connected to the AP again using my phone, turned off mobile data to make sure it didn’t try and serve content from the Internet, and then accessed (which had been printed to the REPL which I could see because I was using Thonny).

To my surprise, I got Hello world! on the browser. Yay! It works!

Flash the onboard LED

I added the definition of the onboard LED:

led = Pin("LED", Pin.OUT)

and set the / path of the tinyweb web server to toggle it on and off.

Now, when I refresh the Hello World page, the LED goes on and off. Wonderful!

See the code on GitHub.

Raspberry Pi Pico W launched – build your Internet of Things projects much easier!

Image from Raspberry Pi

Raspberry Pi has today launched the Raspberry Pi Pico W (see the official announcement here).

This uses the same RP2040 chip as the regular Pico but has wi-fi built into it! This is going to get eaten up by the Internet of Things crowd and, at $6 (£6 ish), it is incredibly good value for money!

You can buy a Pico W from Pimoroni and of course from The Pi Hut and there are other resellers out there too.

Pimoroni have got ahead of the game (as usual) by developing several Pico-with-wireless boards and add-ons. My favourite is the Inventor 2040 W which has motor drivers, audio and breakouts (as well as wi-fi) onboard. Good job, folks! There are also other sensor/IoT based boards in the works and the e-ink boards are already available. Best place to go is the New Products page.

You can read a review of the Pico W by Les Pounder here and there’s a new issue of The MagPi out covering the launch. If you’re on Twitter, other coverage will come out over the day, I’m sure.


£6? That’s ridiculous for an IoT platform with the kind of support and quality that Raspberry Pi puts out. The RP2040 is a great chip and the 2MB of onboard memory is just enough for most uses, although 4MB wouldn’t have gone amiss (I appreciate it wouldn’t have been £6 then, but I can wish!) Go and buy one if you need the wi-fi connectivity or a cheap Bluetooth device (when the software catches up). Well done, Raspberry Pi – this one is going to go like hotcakes!

Raspberry Pi Zero 2 W launched! More processor power in a small package!

Raspberry Pi Zero 2 close-up, front side

Fans of the Raspberry Pi Zero can today get excited about a new Raspberry Pi product – the Raspberry Pi Zero 2 W.

TL;DR – it’s got the Pi 3B processor, 512MB of RAM and is a lot speedier than the original Zero/Zero W.

New processor

The big headline improvement to the Zero is that the Pi Zero 2 W uses the same processor as the Raspberry Pi 3.

In technical terms, RP3A0 is a SiP that combines the BCM2710A1 die used in BCM2837A1 – which was used in the Raspberry Pi 3 – and a 4Gbit Micron LPDDR2 die along with the decoupling capacitors required to smooth the core supply voltage.

Raspberry Pi Zero 2 - chip package

The new Zero 2 chip is a quad-core, 64-bit processor, a massive increase in processor power over the original Zero/Zero W which uses the single core Raspberry Pi 1 processor. The processor is only set to 1 GHz to avoid overheating issues, but could be overclocked to 1.4 GHz (the same as the Pi 3B) with adequate heat dissipation. I’m sure someone will come out with a case that will allow you to do just that!

Same memory size, new package

Also on-board is 512MB of RAM. This has been packed into a new “substrate package” developed by Raspberry Pi to allow it to work with the new processor, making it their second home-grown silicon package (after the Raspberry Pi Pico).

The Pi Zero 2 W has WiFi onboard, but this time it is packaged into a “can” which means the whole Pi Zero 2 is conformance-tested, making it much easier to develop full products with the Zero 2 W embedded. As you can see from the image above, because the silicon package was developed by Raspberry Pi, you get the Pi logo on top, which is nice.

The board comes without a 40-pin header (so blame me for the soldering below!).

Raspberry Pi Zero 2 close up, reverse

Same form-factor

The form-factor of the Pi Zero 2 W is the same, although some components have moved so cases that expect components not to move (like the Pimoroni PiBow) might not fit properly. My usual choice for the Zero (the £6 “Premium Raspberry Pi Zero Case” from The Pi Hut) housed the new board nicely, however, because it allows for flexibility of components.

I was also happy to see the continued inclusion of the Zero-sized camera connector. This is still a very fragile connector, although necessary because of the board size.

Existing models

It’s expected that the original Pi Zero and Pi Zero W will still be available to purchase for the near future.

Cost and getting the board

The baseline price of the Raspberry Pi Zero 2 W is $15 (because they source the parts in dollars, in case you didn’t know!). That works out to just over £13 in the UK. They are limited to one-per-customer, as per usual with the Zero. This stops eBay scammers grabbing them all and makes things fairer, although this may be frustrating for some people, also as per usual with the Zero.

For those buying in the UK:

For those buying in the EU:

For those buying in North America:

For those buying in the Rest of the World

(I will add other resellers as I pick up their website addresses).


In practice

When I used the Pi Zero 2 W, I first of all did a full update/upgrade. Once that was done, it took less than 30 seconds to boot up into the desktop. Impressive considering the amount of memory on-board. Web browsing felt sluggish (because of the lack of memory), but I’m told that the Zero 2 isn’t really built for that (although it would do it at a push – I managed to post to the Raspberry Pi Forums from it without much bother!). I tested out the GPIO pins, including an I2C and SPI test and everything “just worked”.

I do wish that the Pi Zero 2 had 1GB, but maybe that would make it “too capable” and eat into the usage and sales of the Pi 4.

Bottom line: A very nice little board and is well worth the extra cost.

Other opinions and blog posts

As usual, I’ll pick up other coverage and link to it as the day progresses. Check back later for links to more opinions!

Review of the Cytron Technologies Maker Pi RP2040 – a motor controller board at the start of your robotics journey

Last in my mailbag of Cytron Technologies goodies, this is the Maker Pi RP2040. It has clearly been designed to get you going with your robotics journey and to give you the ability to add all sorts of inputs and outputs into a project, centered around the new RP2040 microcontroller chip from Raspberry Pi.

TL;DR – great for beginners, plenty of inputs and outputs, easy to power. Another winner from Cytron.

What’s in the box?

You get the Maker Pi RP2040 board and also 4 Grove-to-female-header cables, some rubber feet and, handily, a small Phillips screwdriver – that saved me digging my own screwdriver out, and it’s a nice something for the newbies who don’t have a collection of tools.

What can the board do?

Let’s first of all look at your input/output options:

  • 7 x Grove sockets – you can plug in any compatible Grove modules, or you can use the four included cables to hook up any generic sensors, outputs, inputs, whatever you like!
  • 2 x DC motor outputs – allowing you to drive 2 motor outputs forwards and backwards independently at up to 1A per channel (1.5A peak). Also on-board are four test buttons that allow you to get your motors moving and check they work without any programming.
  • 4 x servo motor outputs – for fine motor control.
  • 1 x piezo buzzer – so you can play beeps and other sounds (this can be disabled completely by an on-board switch).
  • 2 x Neopixel-style user-controllable RGB LEDs.
  • A collection of low-power LEDs in-line with all the input/output ports so that you know what has been activated (and who doesn’t like blinkies?)
  • 2 x user-defined buttons – perhaps you can use these to put your robot into different modes…?
  • A Run/reset button and a Boot button.

If you want to take a look at the Datasheet, you can find it here.

Let’s talk about power

In terms of powering the board and the motors, you have three options:

  1. Supply power through the microUSB socket (very handy when you’re testing things out and programming at the same time).
  2. Supply power via a single-cell 3.7V LiPo battery. (The microUSB input will charge your LiPo as well, with overcharge and undercharge protection built-in).
  3. Supply power via the screw terminals between 3.6V and 6V (the max is equivalent to 4 x non-rechargeable AA batteries, but you can, of course, use rechargeable ones instead).

All the power is handily isolated by an on-board power switch so if you just need to shut the thing off, one click and you’re done.

Having a play

I hooked up two 6V DC motors to the board using the screw terminals (thanks again for the screwdriver!) then used the test buttons to make them run. Excitingly, it “just worked”. I then used the pre-loaded demo script to automatically “turn the robot on the spot” (which it would have done had I not elevated the wheels before I hit the button!). You can see a short demo video of it working below:


I also hooked up a servo and used the demo script to turn it back and forth. These are small steps, but vital ones, as it proves that everything works and you’re ready to embark on your future exploits.

Speaking of which, Cytron have provided a GitHub repository to help you, full of demo scripts for both CircuitPython (which is pre-installed) and MicroPython.

You can see the code for the pre-loaded demo here. As you can see, for DC motors you simply use the pwmio library to define the motors and then trigger them. For servos, they are using Adafruit’s adafruit_motor/servo library. Normally, I’d criticise them for not building their own library, except a) why re-invent the wheel? and b) they’re using CircuitPython for this anyway, and Adafruit invented that!

What did I think?

I think this is an excellent board for beginners. With the ability to hook motors up, provide power and then just click a button to test the motors out, you get the instant gratification that both kids and adults love. Programming the RP2040 is easy (especially using CircuitPython) and if you added on, say, a Cytron line following sensor (which might be a bit “cable-y” using the Grove sockets, admittedly), it’s clear to see how you could create a line following robot, as an example, quite simply.

The only caveat I really have with the board is that, because it’s all very centred around the 7 Grove sockets, there’s no direct access to the GPIO ports. Sometimes, you just want to hook something up without needing a special cable to do it. Now, they obviously provide 4 of these “special cables” to enable you to do that, which is very handy, but having (even unpopulated) headers for the pins might’ve made things even more flexible. Of course, the board is 85mm x 60mm (approx), and that small size is very attractive. There are always trade-offs, though, in any product, and it doesn’t stop me recommending it, it’s just something to be aware of.

The three power options are very flexible, and it’s good to see a LiPo port on there, even if beginners probably shouldn’t use them to start with. Adding the charging circuitry in, though? Very good move from Cytron, there.

I do keep mentioning that it is for beginners. Well, at 1A per channel, it’s not going to blow anyone away in terms of sheer power. Having said that, as a trade-off, you can run 6 motors independently, so one shouldn’t complain! They have a lovely range of other motor controller boards able to provide more grunt, so there is a clear path to change your method later when you get more advanced.

Overall, it’s a solid 9/10, I think, and a great use of the RP2040 chip.

Another winner from Cytron – highly recommended.

For another take on the same board, I suggest having a look at Les Pounder’s review over at Tom’s Hardware.

Where can I get it?

In Malaysia and surrounding countries, go directly to the Cytron website where the board is available for $9.90.

In the UK, I recommend The Pi Hut where it is listed at £9, but I notice they are currently out of stock. There is a notification email list, though.

In the USA, I suggest Adafruit who I believe are getting stock in very soon and selling for $12.50.

Other resellers are listed on the Cytron page near the bottom, above the reviews.