Anemometer Wind Speed Sensor
A cup anemometer measures wind speed using three or four cups mounted on horizontal arms attached to a vertical shaft. As the wind rotates the cups, a magnet attached to the shaft passes a reed switch or hall effect sensor, generating a pulse per revolution. By counting pulses over a known time period and applying the sensor’s calibration factor, the wind speed in m/s, km/h, or mph can be calculated. These sensors are widely used in weather stations, wind resource assessment, and environmental monitoring.
For this interfacing you need the following components:
- Arduino board (Uno, Nano, Mega, etc.)
- 3-cup anemometer with reed switch or hall effect output (e.g., Davis, Inspeed, or generic)
- 10 kΩ pull-up resistor (only needed for reed switch sensors)
- Breadboard and jumper wires
- USB cable to connect Arduino to your computer
Schematic
Connect the anemometer to the Arduino as follows:
Anemometer Arduino
---------- -------
VCC (red) --> 5V
GND (black) --> GND
Signal (yellow) --> Digital Pin 2 (interrupt-capable)
10 kΩ resistor between Signal and VCC (pull-up, if using reed switch)
Pin 2 is an interrupt-capable pin on the Uno/Nano, which is essential for accurate pulse counting without missing edges.
Hall effect vs reed switch
| Sensor Type | Output | Pull-up Needed | Notes |
|---|---|---|---|
| Reed switch | Open/close | Yes (10 kΩ) | Mechanical contact, bounces |
| Hall effect | Digital (0/5V) | No | No bounce, no wear |
Most generic anemometers use a reed switch. High-end models use a hall effect sensor.
Pin Map
| Anemometer Wire | Name | Arduino Connection |
|---|---|---|
| Red | VCC | 5V |
| Black | GND | GND |
| Yellow/White | Signal | Digital Pin 2 (interrupt) |
Some anemometers use different wire colours — check your specific model’s documentation.
Install necessary Library
No external library is required. Pulse counting uses attachInterrupt() and micros() built into Arduino.
For anemometers with analog output (0–5V proportional to wind speed), use standard analogRead().
Code with complete explanation
This sketch measures wind speed by counting pulses from the anemometer over a 3-second sampling window and calculates the speed in m/s, km/h, and mph.
const int sensorPin = 2;
volatile unsigned long pulseCount = 0;
// Calibration factor: pulses per second per m/s
// Typical values: 0.5 to 2.5 (check your anemometer datasheet)
// Example: Anemometer with 1 pulse per revolution, 0.75 m/s per revolution = 1.333 Hz per m/s
const float PULSES_PER_MPS = 1.33;
unsigned long lastSampleTime = 0;
const unsigned long SAMPLE_INTERVAL = 3000; // ms
void setup()
{
Serial.begin(9600);
pinMode(sensorPin, INPUT_PULLUP);
// Attach interrupt on FALLING edge (reed switch closes = signal goes LOW)
attachInterrupt(digitalPinToInterrupt(sensorPin), countPulse, FALLING);
Serial.println("Anemometer Wind Speed Test");
Serial.println();
}
void loop()
{
unsigned long now = millis();
if (now - lastSampleTime >= SAMPLE_INTERVAL)
{
// Disable interrupt during calculation
detachInterrupt(digitalPinToInterrupt(sensorPin));
unsigned long count = pulseCount;
pulseCount = 0;
// Re-enable interrupt
attachInterrupt(digitalPinToInterrupt(sensorPin), countPulse, FALLING);
lastSampleTime = now;
// Calculate wind speed
float frequency = count / (SAMPLE_INTERVAL / 1000.0); // Hz (pulses per second)
float speedMps = frequency / PULSES_PER_MPS; // m/s
float speedKmh = speedMps * 3.6; // km/h
float speedMph = speedMps * 2.237; // mph
Serial.print("Pulses: ");
Serial.print(count);
Serial.print(" Freq: ");
Serial.print(frequency, 1);
Serial.print(" Hz");
Serial.print(" Speed: ");
Serial.print(speedMps, 2);
Serial.print(" m/s ");
Serial.print(speedKmh, 1);
Serial.print(" km/h ");
Serial.print(speedMph, 1);
Serial.println(" mph");
}
}
void countPulse()
{
pulseCount++;
}
Code breakdown
attachInterrupt(pin, ISR, mode)— attaches an interrupt service routine to the specified pin.FALLINGmode triggers on HIGH→LOW transitions (reed switch closure or hall sensor falling edge).digitalPinToInterrupt(sensorPin)— converts a digital pin number to its interrupt number. On Uno/Nano, pin 2 = interrupt 0, pin 3 = interrupt 1.volatile unsigned long pulseCount— the ISR increments this variable. Thevolatilekeyword tells the compiler that this variable can change outside the normal program flow (inside an ISR).detachInterrupt()/re-attachInterrupt()— the interrupt is briefly disabled while copying and resetting the counter to prevent race conditions.count / (SAMPLE_INTERVAL / 1000.0)— converts the pulse count to frequency (Hz).frequency / PULSES_PER_MPS— converts frequency to wind speed using the anemometer’s calibration factor. For a typical cup anemometer, 1 Hz ≈ 0.75–2 m/s.
Calculating the calibration factor
Check your anemometer datasheet for the exact calibration. Common methods:
- From specs: “1 pulse per second = 1.492 km/h” → 1.492 / 3.6 = 0.414 m/s per Hz → PULSES_PER_MPS = 1 / 0.414 ≈ 2.41.
- From measurement: Hold the sensor out of a car window at a known speed (e.g., 20 km/h), record the frequency, then divide. E.g., 20 km/h = 5.56 m/s, measured 13.2 Hz → 13.2 / 5.56 = 2.37 pulses/m.
Using RISING edge (hall effect sensors)
For hall effect sensors that output a clean HIGH pulse:
attachInterrupt(digitalPinToInterrupt(sensorPin), countPulse, RISING);
Analog anemometers
Some anemometers output 0–5V proportional to wind speed. The generic LV interface:
const int analogPin = A0;
void loop()
{
int raw = analogRead(analogPin);
float voltage = raw * (5.0 / 1023.0);
// Calibration: 0V = 0 m/s, 5V = 30 m/s (example)
float speedMps = (voltage / 5.0) * 30.0;
Serial.print(speedMps);
Serial.println(" m/s");
delay(1000);
}
Steps to perform this interfacing
- Connect the anemometer to the Arduino as shown in the schematic. Use pin 2 (interrupt-capable) for the signal.
- If using a reed switch anemometer, add a 10 kΩ pull-up resistor between the signal wire and VCC.
- Look up your anemometer’s calibration factor and update
PULSES_PER_MPSin the code. - Copy the code into the Arduino IDE.
- Select the correct board and port (
Tools > BoardandTools > Port). - Upload the sketch to the Arduino.
- Open the Serial Monitor (
Tools > Serial Monitor, set baud rate to 9600). - Wait 3 seconds for the first sample. If the anemometer is spinning (e.g., blow on it or use a fan), the wind speed will be displayed.
- If the reading shows zero, check that the interrupt pin matches and the pull-up resistor is correctly connected.
Caution
- Interrupt pin required: The anemometer signal must be connected to an interrupt-capable pin for reliable pulse counting. On Uno/Nano, only pins 2 and 3 support interrupts. On Mega, pins 2, 3, 18, 19, 20, 21 support interrupts. Using a non-interrupt pin with
digitalRead()in a loop will miss pulses at moderate wind speeds. - Bounce filtering: Reed switch anemometers produce contact bounce (multiple on/off transitions per revolution). Most generic anemometers include a small capacitor across the switch to filter this. If you see excessive counts, add a 10–100 nF capacitor between the signal pin and GND, and use the
FALLINGmode with a 5 ms debounce in the ISR. - Calibration accuracy: The calibration factor varies between anemometer models and even between individual units. For accurate measurements, compare your readings against a calibrated anemometer or use the manufacturer’s calibration certificate. The factor may also change slightly as the bearings wear over time.
- Exposure: Anemometers are designed for outdoor use, but the electronics (reed switch or hall sensor) are not waterproof. If using a non-sealed anemometer (e.g., a DIY model), protect the sensor housing from rain ingress or mount it inside a weather shield with only the cups exposed.
- Mounting height: Standard meteorological practice places anemometers at 10 m above ground in open terrain. Lower mounting heights under-report wind speed due to ground friction. For accurate readings, mount the anemometer at least 2 m above any nearby obstructions.
- Sampling interval: A 3-second sampling window is adequate for average wind speed. For gust measurement (peak 3-second wind), sample every 1 second or use the
micros()function inside the ISR to record the interval between pulses and compute instantaneous speed.