This document will provide a tutorial of how to build and program a wind measurer using an anemometer and a Raspberry pi pico W. The device receives an input from the connected anemometer and sends that data to a data feed that is hosted by Adafruit. On Adafruit the data is displayed and updated in real time every fourth second and every four minutes the average wind for that four minute duration is entered and displayed in a graph.
Building this device as a complete novice took a couple of weeks, but I also had to learn almost everything from the beginning due to my limited experience. By following this guide the project could most likely be completed in a few hours, assuming that all components are already present and the developer is experienced in IoT.
The device I constructed is very simple and similar projects have definitely been made before. However, I already knew this when I started the course. I recognized that there were several aspects of this type of development that I had little to no knowledge of. I had not worked with hardware in the form of breadboards, jumper wires or micro-controllers before and I also had to learn the basics of python in order to do this course. So I decided to aim for something that I knew that I would be able to finish and learn from. I did, however, decide on a wind measurer because the place where I live has very varying wind strengths. I was curious to receive and analyze the data to see what type of patterns it would show over time and therefore I decided on this specific type of sensor.
Since the current wind strength will be displayed on adafruit it will allow for me to estimate the weather conditions at home no matter where I am, as long as I have access to the internet. So for example if a storm or simillar were to appear while I'm on vacation, I would be able to see it from a distance and then call a neighbor to make sure things such as outside furniture are safely stored.
The long term data can also be analyzed in order to recognize patterns. Maybe there is a specific time of day where the weather tends to be less harsh? That data could then be used to for example plan dinners outside or find the optimal time to go for walks.
1 Raspberry pi pico W - Connects to the internet and executes code.
1 Breadboard - Connects all components and simplifies prototyping.
At least 5 Jumper Wires - Connects two components.
1 LED - A led lamp that blinks if the code is running. Just used to get a visual confirmation that the device is active.
1 Resistor - Regulates the current leading to the LED.
1 USB micro b cable - Needed to connect the pico to a computer or power supply.
1 Analog cup Anemometer - Outputs 0.4V - 2.0V depending on cup rotation speed.
(The one I used: https://www.electrokit.com/produkt/anemometer-vindsensor-analog-utgang/?gclid=CjwKCAjwkeqkBhAnEiwA5U-uM1SUfNbANyQp5mjjy9XUYjrgRbOakFi5SA4lGFm_T8t4EONr2nk8fBoC_CoQAvD_BwE)
The anemometer was bought from Electrokit.com and cost 775 SEK including delivery. The rest of the components were included in the Linnaeus University starting kit that cost 448 SEK including delivery.
The Pico is programmed with Python using Thonny. So that had to be downloaded in order to write scripts in Python. Micro Python also had to be downloaded and transferred to the Pico in order for it to be able to read the script. This was done by simply downloading Micro Python, plugging in the Pico to the computer while holding down the bootsel button and then dragging and dropping the downloaded Micro Python into the Pico memory that would show up like a flashdrive. If the Pico is connected to the computer, Thonny can recognize it and then save scripts directly to its memory. The script I created is called “Main.py”, which means that it will automatically run as soon as the Pico connects to a power source.
The anemometer has 3 wires. One black (GND), one brown (voltage) and one blue (output voltage). The 3 wires are connected to one row each on the breadboard and each of those rows is then connected to their respective position on the Pico by using jumper wires. The black wire connects to a ground pin, which in my case is pin 38. The brown wire has to connect to the 3v3(OUT) pin which is pin number 36. And finally the blue wire connects to any of the GP pins which can receive input data, and on my board that is GP26 which is pin number 31.
In addition to the anemometer, there is also a single LED connected to the Pico. The LED has only two purposes. To flash once whenever data from the anemometer is sent to the Adafruit data-feed and to show if a wifi connection is found. The negative side of the LED is connected to ground on pin number 3. The positive side is first connected to a resistor with 330 ohms resistance and then the resistor connects to GP7 on pin 10.
The current version of the device needs a few improvements if it’s to be used in production. The circuitry is currently exposed and will require some sort of protective chassis in order to function outside during harsh weather.
Since I knew that I would only require one type of data to get started with this project I decided to use Adafruit in order to gather and display it in two different ways. The current wind data that is updated every fourth second is displayed as a gauge and beside it a graph shows the average wind for each interval every four minutes.
Adafruit allows free use of a few feeds and dashboards but if additional ones are needed then the user has to pay for them. But simply using two feeds and one dashboard and saving their data on the Adafruit cloud worked for the purposes of my project. I was not planning on expanding on the project but if I were to do that an idea could be to gather wind data from several different locations and then display their correlation on different dashboards. In order to do this however, several more similar devices would have to be built. The device I already have could of course be expanded on with more sensors that can send additional data to Adafruit as well.
If the product were to be scaled with for example more sensors, and therefore more data, then a paid subscription to Adafruit might be required. 10 feeds and 5 dashboards are provided with the free version I used but if this project were to be expanded with the idea I mentioned about more devices over several areas then these 10 feeds might not be sufficient. Especially not if the actual devices also were to be expanded upon to output additional data. But for the purpose of the goals I set up for this course, the free version of Adafruit worked very well.
import network
import urequests
import time
import machine
import utime
# Wi-Fi settings
WIFI_NAME = 'Crossfire' # The Wifi name and password has to be written manually in this code
WIFI_PASSWORD = 'Do_Not_3ntR'
# Adafruit IO settings
ADAFRUIT_USERNAME = 'Sizzox' # Adafruit username
ADAFRUIT_KEY = 'aio_SOet48mPGcTlwBUGXDENO0H7aUjF' #Personal adafruit key
ADAFRUIT_FEED = 'vikhog-wind-feed' # adafruit feed key
ADAFRUIT_FEED_LIVE = 'vikhog-wind-feed-live'
# Anemometer variables
analog_pin = machine.ADC(0)
min_voltage = 0.4 # Minimum voltage (0 m/s)
max_voltage = 2.0 # Maximum voltage (32.4 m/s)
max_speed = 32.4
# LED pin
led = machine.Pin(7, machine.Pin.OUT)
# Connect to Wi-Fi
def connect_to_wifi():
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.connect(WIFI_NAME, WIFI_PASSWORD)
while not wifi.isconnected():
pass
print('Wi-Fi connected!')
print('IP address:', wifi.ifconfig()[0])
for i in range (0,6):
led.value(1)
utime.sleep(0.1)
led.value(0)
utime.sleep(0.1)
# Send data to Adafruit IO feed
def send_live_data_to_adafruit(value):
aio_url = 'https://io.adafruit.com/api/v2/webhooks/feed/piGaa5p1KWTHBpq3vYnnBmr9JSDp'
headers = {'X-AIO-Key': ADAFRUIT_KEY, 'Content-Type': 'application/json'}
data = '{"value": ' + str(value) + '}'
response = urequests.post(aio_url, headers=headers, data=data)
print('Data sent to Adafruit IO:', response.text)
response.close()
def send_data_to_adafruit(value):
aio_url = 'https://io.adafruit.com/api/v2/webhooks/feed/yBJikDqDEcMBRXScvjXKxsTeWdNd'
headers = {'X-AIO-Key': ADAFRUIT_KEY, 'Content-Type': 'application/json'}
data = '{"value": ' + str(value) + '}'
response = urequests.post(aio_url, headers=headers, data=data)
print('Data sent to Adafruit IO:', response.text)
response.close()
connect_to_wifi()
counter = 0
data_counter = 0
while True:
led.value(1)
voltage = analog_pin.read_u16() * 3.3 / 65535
wind_speed = (voltage - min_voltage) / (max_voltage - min_voltage) * max_speed
wind_speed = round(wind_speed, 4)
if wind_speed < 0:
wind_speed = 0.000
send_live_data_to_adafruit(wind_speed)
counter += 1
data_counter += wind_speed
if counter >= 60:
send_data_to_adafruit(data_counter / counter)
counter = 0
data_counter = 0
utime.sleep(0.5)
led.value(0)
utime.sleep(0.5)
At first I wanted the data to be shown on Adafruit in real time so I decided that showing the current wind output every new second would be the way to go.
The first thing the script does is connecting wirelessly to a WiFi. In order for this to happen, the main script needs to be edited to contain the name and password that allows for connection to a router within range.
When a connection has been made the script simply runs a while loop until the device is turned off again. The two functions in the code uses one webhook link each to send data to their respective adafruit feed.
The functions are called in the while loop and then towards the end of the loop the Pico script will sleep for a total of one second as well as turn off a LED to indicate that a loop is finished.
Each iteration of the loop also increases a counter variable by one and after 60 loops the average wind speed was also to be sent to an Adafruit feed connected to my dashboard graph.
The idea was for the data to transmit every second as well as every minute for the graph data, but probably due to some delay while sending the transmissions, each loop seems to take around 4 seconds instead of 1 which means that the adafruit feeds receive their data every 4 seconds and every 4 minutes.
However, since the data is sent constantly and since the time between updates is nothing game changing, I decided to keep it at 4 instead of changing it back.
The Adafruit dashboard.
Data is saved to the feed connected to left aproximately every fourth second and to the feed connected to the right it's saved aproximately every fourth minute.
The final device is attached to a long wooden pole. The Pico is contained inside an old plastic ice cream box on the poles side and on the box is a small hole where the Pico cables can exit. The anemometer is located on the top of the pole.
Some modifications can definetly be done to further expand upon the project. Sensors to measure temperature, rain, humidity or other simillar properties could have been added in order to make the device into a full weather station rather than just an anemometer.
There are probably a few code changes that can be done that will improve performance and speed, but I still belive I managed to make a fair solution for someone that is a beginner in Python programming.
There is obviously a lot of ways the data could have been sent and presented but I actually feel pretty satisfied with how it was handeled on Adafruit. The process was not very complicated and the exact data I was looking for was able to be displayable in a neat format.
Generally speaking, I am very proud of what I managed to accomplish with this project and it has really made me excited to work with more IoT projects in the future.
Underneath are a few pictures of the final result.
Pico and Anemometer connected.
Closer look on the Pico
Pico inside a protective plasctic container.
Container and Anemometer attached to a wooden pole.
Full device set up outside