Overview
This wind speed sensor is a classic three-cup anemometer with a built-in signal conditioner: as wind spins the cups, the sensor converts the rotation into a clean 0-5V analog voltage that rises linearly with wind speed across its 0-30 m/s range. There is no bus protocol, no library, and no timing-critical pulse counting — one analog read and one multiplication give you the wind speed, which makes it one of the friendliest outdoor sensors you can add to a weather station.
The sealed housing and cup rotor are engineering plastic built for continuous outdoor exposure, with a shielded three-wire cable: brown is power, blue is the 0-5V signal, and black is ground. Note the supply requirement — the electronics inside want 7-24V DC (a 12V adapter or battery is the sweet spot), not the 5V or 3.3V from your microcontroller. The signal line, on the other hand, never exceeds 5V, so an Arduino reads it directly, while 3.3V boards like the ESP32 and Pico just need a two-resistor divider (the Raspberry Pi adds an external ADC, since it has no analog inputs).
Converting the voltage is one line of math: wind speed in m/s equals the output voltage times 6 (5V corresponds to 30 m/s). Cup anemometers need a light breeze of roughly 0.4-0.8 m/s to start turning, and this unit survives gusts far beyond its 30 m/s measurement ceiling. Typical builds include home weather stations, sailing and kite-field wind meters, high-wind alarms for awnings and drones, and long-term wind logging for solar or agricultural sites.
At a Glance
Specifications
| Parameter | Value |
| Sensor Type | Three-cup rotary anemometer with analog conditioner |
| Output Signal | 0 - 5V DC analog, linear with wind speed |
| Measurement Range | 0 - 30 m/s (0 - 67 mph) |
| Conversion Formula | Wind speed (m/s) = Vout x 6 |
| Resolution | ~0.1 m/s |
| Accuracy | ±(0.3 + 0.03 x reading) m/s |
| Start Wind Speed | 0.4 - 0.8 m/s |
| Supply Voltage | 7 - 24V DC (12V recommended) |
| Survivable Wind | Up to ~70 m/s structurally |
| Operating Temperature | -40°C to +80°C |
| Cable | 3-wire shielded: brown (power), blue (signal), black (ground) |
| Housing | Weather-resistant engineering plastic, aviation connector |
Pinout Diagram
The three wires do exactly what their labels say. Brown is the positive supply — connect it to a 7-24V DC source such as a 12V adapter. Black is ground, and it must be shared between the power supply and your microcontroller so the signal has a common reference. Blue is the analog output: 0V in still air rising linearly to 5V at 30 m/s. The blue wire sources a voltage, never draws meaningful current, so it connects straight to an ADC input (through a divider on 3.3V boards).
Wiring Guide
Arduino Wiring
The Arduino's 5V-tolerant analog inputs read the signal wire directly. The sensor itself is powered from a separate 12V supply (or the Arduino's VIN pin if the board runs from a 9-12V adapter), with grounds tied together.
| Sensor Wire | Connects To | Details |
|---|---|---|
| Brown (Power) | 12V DC supply + | 7-24V range; VIN works on a 9-12V powered board |
| Black (GND) | Supply - and Arduino GND | Common ground is required |
| Blue (Signal) | A0 | 0-5V, direct |
ESP32 Wiring
ESP32 GPIO tops out at 3.3V, and the signal wire can reach 5V in strong wind — so the blue wire goes through a voltage divider (10k + 20k) that scales 0-5V down to 0-3.3V.
| Sensor Wire | Connects To | Details |
|---|---|---|
| Brown (Power) | 12V DC supply + | 7-24V range |
| Black (GND) | Supply - and ESP32 GND | Common ground is required |
| Blue (Signal) | GPIO 34 | Via 10k/20k divider; ADC1 input-only pin |
Raspberry Pi Wiring
The Pi has no analog inputs, so an ADS1115 I2C ADC reads the sensor. Divide the signal down to the 0-3.3V range first, then feed it to the ADS1115 running from the Pi's 3.3V rail.
| Wire / Pin | Connects To | Details |
|---|---|---|
| Brown (Power) | 12V DC supply + | 7-24V range |
| Black (GND) | Supply - and Pi Pin 6 (GND) | Common ground is required |
| Blue (Signal) | ADS1115 A0 | Via 10k/20k divider |
| ADS1115 VDD | Pin 1 (3.3V) | |
| ADS1115 GND | Pin 6 (GND) | |
| ADS1115 SDA | Pin 3 (GPIO 2) | I2C data |
| ADS1115 SCL | Pin 5 (GPIO 3) | I2C clock |
Raspberry Pi Pico Wiring
The Pico's built-in ADC reads the divided signal directly — same divider as the ESP32, landing on ADC0.
| Sensor Wire | Connects To | Details |
|---|---|---|
| Brown (Power) | 12V DC supply + | 7-24V range |
| Black (GND) | Supply - and Pico GND (pin 38) | Common ground is required |
| Blue (Signal) | GP26 (physical pin 31) | Via 10k/20k divider; ADC0 |
Code Examples
Arduino
// Wind Speed Sensor (0-5V Anemometer) - Arduino Example
// Blue signal -> A0 (direct), Brown -> 12V supply, Black -> GND (shared)
// Wind speed (m/s) = Vout x 6 (5V = 30 m/s)
const int windPin = A0;
const int numSamples = 16;
void setup() {
Serial.begin(9600);
}
void loop() {
// Average several readings to steady the value in gusty air
long total = 0;
for (int i = 0; i < numSamples; i++) {
total += analogRead(windPin);
delay(5);
}
float raw = total / (float)numSamples;
// Convert the 10-bit reading (0-1023) to volts (5V reference)
float volts = raw * (5.0 / 1023.0);
// Convert volts to wind speed
float windMs = volts * 6.0; // meters per second
float windMph = windMs * 2.237; // miles per hour
Serial.print("Signal: ");
Serial.print(volts, 2);
Serial.print(" V | Wind: ");
Serial.print(windMs, 1);
Serial.print(" m/s (");
Serial.print(windMph, 1);
Serial.println(" mph)");
delay(1000);
}
ESP32 (MicroPython)
# Wind Speed Sensor (0-5V Anemometer) - ESP32 MicroPython Example
# Blue signal -> 10k/20k divider -> GPIO 34, Brown -> 12V, Black -> GND (shared)
# Divider scales 5V -> 3.33V, so multiply the measured volts by 1.5
from machine import ADC, Pin
import time
adc = ADC(Pin(34)) # ADC1 channel - keeps working with Wi-Fi on
adc.atten(ADC.ATTN_11DB) # Full 0-3.3V input range
DIVIDER_RATIO = 1.5 # (10k + 20k) / 20k
while True:
# Average several readings to steady the value in gusty air
total_uv = 0
for _ in range(16):
total_uv += adc.read_uv() # calibrated reading in microvolts
time.sleep_ms(5)
volts_at_pin = total_uv / 16 / 1_000_000
# Undo the divider, then convert to wind speed
signal_volts = volts_at_pin * DIVIDER_RATIO
wind_ms = signal_volts * 6.0
wind_mph = wind_ms * 2.237
print("Signal: {:.2f} V | Wind: {:.1f} m/s ({:.1f} mph)".format(
signal_volts, wind_ms, wind_mph))
time.sleep(1)
Raspberry Pi (Python + ADS1115)
#!/usr/bin/env python3
# Wind Speed Sensor (0-5V Anemometer) - Raspberry Pi + ADS1115 Example
# Blue signal -> 10k/20k divider -> ADS1115 A0, SDA/SCL -> GPIO 2/3
# Install: pip3 install adafruit-circuitpython-ads1x15
import time
import board
import busio
import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn
DIVIDER_RATIO = 1.5 # (10k + 20k) / 20k
i2c = busio.I2C(board.SCL, board.SDA)
ads = ADS.ADS1115(i2c)
ads.gain = 1 # +/-4.096V range covers the divided 0-3.33V signal
channel = AnalogIn(ads, ADS.P0)
try:
while True:
signal_volts = channel.voltage * DIVIDER_RATIO
wind_ms = signal_volts * 6.0
wind_mph = wind_ms * 2.237
print("Signal: {:.2f} V | Wind: {:.1f} m/s ({:.1f} mph)".format(
signal_volts, wind_ms, wind_mph))
time.sleep(1)
except KeyboardInterrupt:
print("Measurement stopped by user")
Raspberry Pi Pico (MicroPython)
# Wind Speed Sensor (0-5V Anemometer) - Pico MicroPython Example
# Blue signal -> 10k/20k divider -> GP26 (ADC0), Brown -> 12V, Black -> GND
# Divider scales 5V -> 3.33V, so multiply the measured volts by 1.5
from machine import ADC
import time
adc = ADC(26) # GP26 = ADC0
CONVERSION = 3.3 / 65535 # read_u16() spans 0-65535 across 0-3.3V
DIVIDER_RATIO = 1.5 # (10k + 20k) / 20k
while True:
# Average several readings to steady the value in gusty air
total = 0
for _ in range(16):
total += adc.read_u16()
time.sleep_ms(5)
volts_at_pin = (total / 16) * CONVERSION
signal_volts = volts_at_pin * DIVIDER_RATIO
wind_ms = signal_volts * 6.0
wind_mph = wind_ms * 2.237
print("Signal: {:.2f} V | Wind: {:.1f} m/s ({:.1f} mph)".format(
signal_volts, wind_ms, wind_mph))
time.sleep(1)