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 main.py 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 boot.py 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 boot.py, 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 main.py when you hit F5 as doing that with boot.py 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"""
anvil.server.call('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: https://big-tinted-jump.anvil.app. 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 main.py 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, reading_date_time=datetime.now())
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):
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.