In this guide, you’ll learn how to interface an anemometer with the ESP32 to measure wind speed. We’ll cover how to power and connect the sensor to the ESP32 board, and write a simple code to get wind speed values in different units.
We have a similar guide for the ESP8266 board with an Anemometer: Measure Wind Speed (Arduino IDE)
Table of Contents:
Throughout this guide, we’ll cover the following topics:
- Introducing the Anemometer
- Anemometer Pinout
- Connecting the Anemometer to the ESP32
- ESP32 with the Anemometer – Measure Wind Speed Code
Introducing the Anemometer
An anemometer is a device that allows us to measure wind speed. It is commonly used in weather stations.
Using this sensor is quite easy. It outputs an analog signal, whose voltage is proportional to the wind speed. We’re using an anemometer with three cups like the one in the picture below.
Anemometer Technical Details
Depending on the manufacturer, the anemometer may have different characteristics. For example, these are the characteristics of the anemometer used in this guide:
- Input voltage: 12-24V DC
- Output voltage: 0-5V
- Measurement range: 0-32.4m/s
- Resolution: +/- 0.3m/s
This means that when the analog signal is 0, the wind speed is 0. However, in my case, after powering the sensor and applying a voltage divider, I noticed that when the anemometer was not moving, the output voltage was 0,033V and not 0V.
So, I consider this to be the lowest value measured when the sensor is not moving. I recommend you do the same and figure out the minimum value read from the sensor using a multimeter.
These details might be different depending on the manufacturer. So, you need to take that into account when converting the analog signal to wind speed.
Anemometer Pinout
The anemometer comes with three wires:
Blue Wire | Signal |
Black Wire | GND |
Brown Wire | Power |
Connecting the Anemometer to the ESP32
The anemometer requires an input voltage of at least 12V. So, you can’t power it directly from the ESP32, you need an external power source.
We’re powering the sensor using a 12V power adapter and connecting it to the anemometer using a power jack. You can use any other suitable power source.
Converting the Data Signal from 5V to 3.3V
In the case of my sensor, it operates in the range of 0 to 5V. However, the ESP32 analog pins can only read a maximum of 3.3V. So, we need to convert the 5V signal to a 3.3V signal. To do that, we can use a voltage divider.
Note: if you’re using an anemometer like the one from Adafruit, you don’t need to worry about this because the maximum output voltage is 2V.
A voltage divider is a simple circuit that reduces a large voltage into a smaller one. Using 2 resistors and an input voltage, we can create an output voltage that is a fraction of the input. Below you can see the formula that you need to use to calculate the resistors that you need in your circuit:
If we use a 1k Ohm (R1) and a 2k Ohm (R2) resistor, we’ll get a maximum output of 3.3V, which is the maximum that the ESP32 can read.
So, here’s what the voltage divider circuit looks like (in which 5V is the maximum value of the sensor data pin):
You can use any other combination of resistors, but you need to take into account the maximum output voltage allowed by the combination of resistors used.
Learn more here: How to Level Shift 5V to 3.3V
Wiring the Circuit: ESP32 with Anemometer
Here’s a list of the parts you need for this tutorial:
- ESP32 board – read Best ESP32 development boards
- Anemometer Wind Speed Sensor
- 12V DC Power Adapter
- DC power jack adapter
- 1k Ohm resistor and 2k Ohm resistor
- Breadboard
- Jumper wires
- Multimeter
You can use the following diagram as a reference to wire the sensor to the ESP32. Don’t forget to connect the GND pins together:
If you’re using an anemometer like the one from Adafruit that outputs a maximum of 2V, you can connect the output pin directly to the ESP32 analog pin (you don’t need the voltage divider).
Black Wire | GND of the ESP32 and GND of the power source |
Blue Wire | Connect to ESP32 analog pin (via voltage divider, if needed), we’re using GPIO 34. |
Brown Wire | 12V power source (+) |
ESP32 with the Anemometer – Measure Wind Speed Code
The following code reads the analog signal from the anemometer and converts it into wind speed.
You can upload the following code to your ESP32. You may need to modify some of the variables depending on the parameters of your anemometer.
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-anemometer-wind-speed-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Softwar
*********/
// Constants (Change the following variables if needed)
const int anemometerPin = 34; // GPIO pin connected to anemometer (analog pin)
const float minVoltage = 0.033; // Voltage corresponding to 0 m/s
const float maxVoltage = 3.3; // Voltage corresponding to 32.4 m/s (max speed) (when using voltage divider)
const float maxWindSpeed = 32.4; // Maximum wind speed in m/s
// Conversion factors
const float mps_to_kmh = 3.6; // 1 m/s = 3.6 km/h
const float mps_to_mph = 2.23694; // 1 m/s = 2.23694 mph
void setup() {
Serial.begin(115200);
}
void loop() {
// Read analog value from anemometer (ADC value between 0-4095 on ESP32 for 0-3.3V)
int adcValue = analogRead(anemometerPin);
// Convert ADC value to voltage (ESP32 ADC range is 0-3.3V)
float voltage = (adcValue / 4095.00) * 3.3;
// Ensure the voltage is within the anemometer operating range
if (voltage < minVoltage) {
voltage = minVoltage;
} else if (voltage > maxVoltage) {
voltage = maxVoltage;
}
// Map the voltage to wind speed
float windSpeed_mps = ((voltage - minVoltage) / (maxVoltage - minVoltage)) * maxWindSpeed;
// Convert wind speed to km/h and mph
float windSpeed_kmh = windSpeed_mps * mps_to_kmh;
float windSpeed_mph = windSpeed_mps * mps_to_mph;
// Print wind speed
Serial.print("Wind Speed: ");
Serial.print(windSpeed_mps);
Serial.print(" m/s, ");
Serial.print(windSpeed_kmh);
Serial.print(" km/h, ");
Serial.print(windSpeed_mph);
Serial.println(" mph");
delay(1000);
}
How does the Code Work?
First, define the pin where you’re reading the sensor, the minimum and the maximum output voltage of the sensor, and the maximum wind speed.
// Constants (Change the following variables if needed)
const int anemometerPin = 34; // GPIO pin connected to anemometer (analog pin)
const float minVoltage = 0.033; // Voltage corresponding to 0 m/s
const float maxVoltage = 3.3; // Voltage corresponding to 32.4 m/s (max speed) (when using voltage divider)
const float maxWindSpeed = 32.4; // Maximum wind speed in m/s
These are the parameters for our sensor. Yours might be different. When we’re using the voltage divider, the maximum voltage that the ESP32 will read is 3.3V, which will correspond to the maximum wind speed. When the sensor is not moving, it outputs a voltage of 0.033 (read on the voltage divider output), so we consider that the minimum value.
Then, we have the conversion factors to convert the wind speed from m/s to km/h and mph.
// Conversion factors
const float mps_to_kmh = 3.6; // 1 m/s = 3.6 km/h
const float mps_to_mph = 2.23694; // 1 m/s = 2.23694 mph
In the setup(), we initialize the Serial Monitor.
void setup() {
Serial.begin(115200);
}
In the loop(), we get new readings from the sensor every second.
First, we read the value on the ADC pin and convert it to a voltage value. The maximum value read on the ESP32 ADC pin is 4095 that corresponds to 3.3V. So, we can convert the value to a voltage using the following line:
// Convert ADC value to voltage (ESP32 ADC range is 0-3.3V)
float voltage = (adcValue / 4095.00) * 3.3;
Related content: ESP32 ADC – Read Analog Values with Arduino IDE
Then, we have the following condition to check if the values read are within the defined range.
if (voltage < minVoltage) {
voltage = minVoltage;
} else if (voltage > maxVoltage) {
voltage = maxVoltage;
}
Next, we can easily map the obtained voltage to a wind speed value (alternatively, you can use the Arduino map() function).
float windSpeed_mps = ((voltage - minVoltage) / (maxVoltage - minVoltage)) * maxWindSpeed;
Then, we convert the values obtained to km/h and mph.
// Convert wind speed to km/h and mph
float windSpeed_kmh = windSpeed_mps * mps_to_kmh;
float windSpeed_mph = windSpeed_mps * mps_to_mph;
Finally, we print the obtained results.
// Print wind speed
Serial.print("Wind Speed: ");
Serial.print(windSpeed_mps);
Serial.print(" m/s, ");
Serial.print(windSpeed_kmh);
Serial.print(" km/h, ");
Serial.print(windSpeed_mph);
Serial.println(" mph");
delay(1000);
}
Testing the Code
Upload the code to your ESP32. Make sure you have the sensor wired and powered properly.
Open the Serial Monitor at a baud rate of 115200.
Spin the sensor to mimic some wind, and see the values being printed in the Serial Monitor every second.
And that’s it. Now, you can read the wind speed with your ESP32. You can now add an anemometer to your weather station.
Wrapping Up
In this tutorial, you learned how to interface an anemometer with your ESP32. This is a fundamental sensor to add to your weather station to get wind speed data.
We have tutorials for more than 20 sensors with the ESP32. You can check them below:
We hope you found this tutorial useful. You may also like other related tutorials:
- ESP32 Web Server with BME680 – Weather Station (Arduino IDE)
- DIY Cloud Weather Station with ESP32/ESP8266 (MySQL Database and PHP)
- ESP32 TFT with LVGL: Weather Station (Description, Temperature, Humidity)
Thanks for reading.
Hi,
Can you please explain what’s going on inside the anemometer?
How does it convert the 12V input to 5Vmax out? Is there a hall sensor in it?
Voltage 12V is needed only to supply .
When wind blows output changes from 0V to 5V max.
Interesting subject. Obviously the anemometer has some intelligence built in. For anemometers that simply have open and closed contacts, counting pulses would be the way to go
I wonder if there is an anemometer with digital output instead of analog? Over long distances, analog signals get distorted. And you have to run shielded wire from the anemometer to the board.
For example like the DS18B20 digital thermometer, which by the way has a crazy protocol, but works very well. I have one sensor that is about 20 meters of cabling through the house, where the cable is only 2-wires with no shielding and never had a problem in connecting and identifying the DS18B20. You get far more accuracy and stability with a digital sensor.