ESP8266 IoT project. A connected Anemometer and Wind Vane

Table of Contents

In this tutorial we will make a connected anemometer with a wind vane based on a ESP8266 WiFi module. If you have a 3D printer, you just need to print mechanical components of this projects with your printer. You can find all STL files on github.


GitHub logo

Source Code


For the anemometer, we will use a hall effect sensor. The hall effect sensor allow to count the turn of the anemometer propeller. To find to wind direction, we will make an optical encoder based on led and phototransistors. For the Arduino part, i used an ESP8266 module. I like the Wemos d1 mini because it is really small and cheap (about 5€).

BOM : what do you need for the project

All design are ready for the Wemos d1 mini module. If you choose the module, you probably need to update the design. Chose a ESP-12E or ESP-12F module.For this project, you will need :

The cost of this project (with 3D printed parts) is about 30€.


The circuit is composed by two functions:

  • The first function is the angular encoder. We need 5 led and 5 phototransistors. The phototransistor is like a switch. Each time a phototransistor detect the light of the led, the state of the bit associated change (LOW or HIGH). We need a 10 kΩ  resistor for each phototransistor between +5V and the smallest pin. Connect the longest pin to GND.
  • The second function is the turn counter. The us1881 hall effect sensor is composed by 3 pins (angled corners in front of you).
    • Left pin <=> +5V
    • Middle pin <=> GND
    • Right pin <=> signal
    • Connect a 10 kΩ between right and left pins

Do not sold directly the Wemos d1 mini on the circuit to be able to remove it. Some time, it’s not possible to upload the Arduino program. You need to remove the Wemos before.

Follow the wiring diagram for making the circuit.

circuit anemometre girouette esp8266 wemos phototransistor us1881_bb

3D parts

I use Autodesk Fusion 360 to design this project. Fusion 360 is free for students and teachers (3 years). You will find Fusion 360 and STEP files on GitHub here.

Part Design
Anemometer propeller 1. anemometre connecte helices
Anemometer housing 2. boitier anemometre esp8266 axe avec support aimant
Support of the us1881 hall effect sensor 5. anemometre support capteur effet hall us1881
Connecting plate (anemometer and wind vane housing)

Connect the wind vane and anemometer housing

Hall for phototransistors

6. liaison anemometre girouette
Central ball bearing housing 6.1 Support central roulements
Wind vane housing 7. Boitier girouette
Led support 8. support encodeur optique position girouette
Encoding disk (gray code) 9. disque encodeur
Wind vane 10 girouette

You will need about 62 meters of PLA and about 11 hours to produce all 3D parts.

Arduino code compatible ESP8266

Download and open the Arduino code into your IDE. Modify the following variables before downloading the program. If you don’t publish data on a MQTT broker, comment all pubsub lines. Modify the pins adresses of the phototransistors if needed.

#define wifi_ssid “SSID”
#define wifi_password “PASSWORD”
#define mqtt_server “IP_MQTT_BROKER”
#define mqtt_user “guest”
#define mqtt_password “guest”

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

#define wifi_ssid "enter_our_ssid"
#define wifi_password "enter_your_password"
#define mqtt_server "IP_MQTT"
#define mqtt_user "guest"     
#define mqtt_password "guest" 

long lastMsg = 0;     
long lastRecu = 0;

#define vitessems_topic "anemometre/vitesseVentMS"    // Wind speed in m/s
#define vitessekmh_topic "anemometre/vitesseVentKMH"  // Wind speed in km/h
#define direction_topic "anemometre/directionVent"    // Wind Direction 
WiFiClient espClient;
PubSubClient client(espClient);

volatile int rpmcount = 0;
volatile float vitVentMS = 0;
volatile float vitVentKMH = 0;
int rpm = 0;
unsigned long lastmillis = 0;
bool debug = false;

int pinBit0 = D7;
int pinBit1 = D6;
int pinBit2 = D5;
int pinBit3 = D4;
int pinBit4 = D3;
int pinHall = D2;

int bit0 = 0;
int bit1 = 0;
int bit2 = 0;
int bit3 = 0;
int bit4 = 0;

int dureeMesVitVent = 5000; // en ms, durée de mesure de la vitesse du vent. Choisir un multiple de 1000 pour le calcul de la vitesse du vent

byte girouette = 0;
String dirVent = "N";

void setup() {
  // put your setup code here, to run once:
  attachInterrupt(pinHall, rpm_vent, FALLING);
  pinMode(pinBit0, INPUT);
  pinMode(pinBit1, INPUT);
  pinMode(pinBit2, INPUT);
  pinMode(pinBit3, INPUT);
  pinMode(pinBit4, INPUT);
  //attachInterrupt(D7, bit0, FALLING);  

  client.setServer(mqtt_server, 1883);   // Connect to MQTT broker

void setup_wifi() {
  Serial.print("Connexion to ");

  WiFi.begin(wifi_ssid, wifi_password);

  while (WiFi.status() != WL_CONNECTED) {

  Serial.print("Connected with IP ");

void reconnect() {
  while (!client.connected()) {
    Serial.print("Connexion to MQTT...");
    if (client.connect("ESP8266Client", mqtt_user, mqtt_password)) {
    } else {
      Serial.print("KO, erreur : ");
      Serial.println(" Wait 5 secondes before restart");

void loop() {
  if (!client.connected()) {
  client.publish(vitessems_topic, String(vitVentMS).c_str(), true);   // Publie la vitesse du vent en m/s
  client.publish(vitessekmh_topic, String(vitVentKMH).c_str(), true); // La vitesse du vent en km/h
  client.publish(direction_topic, String(dirVent).c_str(), true);     // La direction du vent
  //ESP.deepSleep(1000000 * 10, WAKE_NO_RFCAL); //Pour la prochaine version futur 
  //delay(500); //attente activation du deep sleep

void getVitesseVent() {
  if (millis() - lastmillis >= dureeMesVitVent ){ 

    rpm = rpmcount * ( 60 / ( dureeMesVitVent / 1000 ) ); 
    if ( rpm > 0 ) {
      vitVentKMH = ( rpm + 6.174 ) / 8.367;
      vitVentMS = ( ( ( rpm + 6.174 ) / 8.367 ) * 1000 ) / 3600; 
    } else {
      vitVentKMH = 0;
      vitVentMS = 0;

    rpmcount = 0;           
    lastmillis = millis();  
    attachInterrupt(pinHall, rpm_vent, FALLING); 

void getDirVent(){
  bit0 = not(digitalRead(pinBit0));
  bit1 = not(digitalRead(pinBit1));
  bit2 = not(digitalRead(pinBit2));
  bit3 = not(digitalRead(pinBit3));
  bit4 = not(digitalRead(pinBit4));
  girouette =  (bit4 * 16) + (bit3 * 8) + (bit2 * 4) + (bit1 * 2) + bit0;

  Serial.print(bit0); Serial.print(bit1); Serial.print(bit2); Serial.print(bit3); Serial.print(bit4);
  Serial.print(" => ");
  Serial.print(" Orientation");
  switch (girouette) {
    case 24: dirVent="N"; break;
    case 10: dirVent="NE"; break;
    case 18: dirVent="E"; break;
    //case 18: dirVent="SE"; break;
    case 16: dirVent="S"; break;
    case 2: dirVent="SW"; break;
    case 26: dirVent="O"; break;
    case 8: dirVent="NO"; break;
    default: dirVent="N"; break; 

void rpm_vent(){ 

void callback(char* topic, byte* payload, unsigned int length) {


Step Picture
Assembling subsets

  1. Wind vane
  2. Anemometer propeller
  3. Magnets
  4. Ball bearing
Hélice + capot anémomètre
Wind vane assembly Girouette assemblée
Wind vane encoder assembly 2. Girouette assemblée
Insert the us1881 sensor support us1881
ESP8266 assembly into anemometer housing

Anémomètre - vue du dessus

Top vue

All finish objet connecte projet diy anemometre girouette esp8266 wemos d1 mini

Anemometer calibration

If like me you don’t have a laboratory wind tunnel, you need to use your care to make the calibration of the anemometer. Make several records at different speeds to find the relation between car speed and number of turns of the propeller.

If you don’t modify 3D parts of the propeller, you don’t need to calibrate the anemometer. be careful if you use your car for calibration like me !

This anemometer can :

  • Measure wind speed from 8km/h (about 2m/s)
  • Up to 100 km/h
  • Use this relation to calculate wind speed. WindSpeed = (NumberOfTurns + 6,174 ) / 8,367

Wind vane calibration

In this version, i don’t develop any calibration code for the wind vane. Simply use your smartphone to find the index of the wind direction and update the program.


iot connected object anemometer wind vane esp8266 wemos d1 mini mqtt broker

I hope you enjoyed this tutorial. This is the first version we can improve :

  • Firstly, the design to make it weather resistant.
  • Replace the optical encoder by a magnetic sensor uses less power than LED and easier to program and possible to use with a battery.

Feel free to leave me your comments or questions in the comments.

Click to rate this post!
[Total: 3 Average: 4.3]

Thanks for your reading

Did you like this project ? Don't miss any more projects by subscribing to our weekly newsletter!

Are you having a problem with this topic?

Maybe someone has already found the solution, visit the forum before asking your question
  1. Amazing ! its a pity that i don’t own a 3d printer . i really like to make a small weather station with windspeeds/direction and temp/bar/uv/light to be readable in the home automation software domoticz. Would be great if it is using mqtt then it will be widely usable with many devices/programs. Great build !

  2. For those of us who don’t own a 3D printer or know someone with one, does anyone sell the plastic parts? Or how about a non 3D print alternative?

  3. perfect, thanks for the share.. sick simple design 🙂

  4. ESP-12F variant improved the wifi signal strength or reduced noise.

  5. How does the sensor handle rain, freezing temperatures etc ?

Leave a Reply

Read more
DIY Projects
DIY Projects
%d bloggers like this: