Devices & Components
Grove - 4-Digit Display
Arduino Nano
Vertical Slide Switch
Speed Sensor/Tacho Sensor (Slot-Type Optocoupler)
aluminium tube 5.7 OD, 4.7 ID or similar
Hardware & Tools
3d Printer
Software & Tools
Arduino IDE
Project description
Code
Anemometer_2
css
This version shows the wind speed in m/sec
1#include <Wire.h> 2 3#include <Wire.h> 4#include <TM1637Display.h> 5 6// TM1637 displays 7#define CLK_TIME 8 8#define DIO_TIME 7 9 10TM1637Display dispSpeed(CLK_TIME, DIO_TIME); 11 12volatile unsigned long pulseCount = 0; 13 14#include <TM1637Display.h> 15 16// TM1637 displays 17#define CLK_TIME 8 18#define DIO_TIME 7 19 20TM1637Display dispSpeed(CLK_TIME, DIO_TIME); 21 22volatile unsigned long pulseCount = 0; 23 24unsigned long lastMeasure = 0; 25static unsigned long lastPulseTime = 0; 26const int pulsesPerRevolution = 8; 27const float radius = 0.09; // meters (90 mm) 28 29bool showKmh = true; 30unsigned long lastToggle = 0; 31 32float v_kmh = 0; 33float v_ms = 0; 34float v_kmh_filtered = 0; 35float v_ms_filtered = 0; 36 37void setup() { 38 Serial.begin(115200); 39 pinMode(2, INPUT_PULLUP); 40 attachInterrupt(digitalPinToInterrupt(2), countPulse, FALLING); 41 42 // init your display here if needed 43 dispSpeed.setBrightness(0x0f); 44 45 Serial.print("Test started"); 46 Serial.println(" LastSecond: "); 47} 48 49void loop() { 50 unsigned long now = millis(); 51 52 if (now - lastMeasure >= 1000) { // every 1 second 53 noInterrupts(); 54 unsigned long count = pulseCount; 55 pulseCount = 0; 56 interrupts(); 57 58 if (millis() - lastPulseTime > 1500) { 59 v_kmh = 0; 60 v_kmh_filtered = 0; 61 } 62 63 if (millis() - lastToggle >= 2000) { 64 showKmh = !showKmh; 65 lastToggle = millis(); 66 } 67 68 if (count < 2) { 69 v_kmh = 0; 70 v_kmh_filtered = 0; // ← force immediate zero 71 } else { 72 // rotations per second 73 float rps = count / (float)pulsesPerRevolution; 74 // linear speed of cups 75 float v_cups = 2 * PI * radius * rps; 76 // estimated wind speed 77 float v_wind = v_cups / 0.7; 78 v_kmh = v_wind * 3.6; 79 v_ms = v_kmh / 3.6; 80 // apply smoothing ONLY when moving 81 v_kmh_filtered = 0.7 * v_kmh_filtered + 0.3 * v_kmh; 82 v_ms_filtered = v_kmh_filtered / 3.6; 83 } 84 85 // simple smoothing (important for display stability) 86 v_kmh_filtered = 0.7 * v_kmh_filtered + 0.3 * v_kmh; 87 v_ms_filtered = 0.7 * v_ms_filtered + 0.3 * v_ms; 88 89 int whole_k = (int)v_kmh_filtered; 90 int whole_m = (int)v_ms_filtered; 91 int decimals_k = (int)((v_kmh_filtered - whole_k) * 100 + 0.5); 92 int decimals_m = (int)((v_ms_filtered - whole_m) * 100 + 0.5); 93 94 if (decimals_k >= 100) { 95 whole_k++; 96 decimals_k = 0; 97 } 98 if (decimals_m >= 100) { 99 whole_m++; 100 decimals_m = 0; 101 } 102 // convert for display (XX:YY) 103 int displayValue_k = whole_k * 100 + decimals_k; 104 int displayValue_m = whole_m * 100 + decimals_m; 105 106 // show 00:00 if stopped 107 if (v_kmh_filtered < 0.1) { 108 displayValue_k = 0; 109 displayValue_m = 0; 110 v_ms_filtered = 0; 111 } 112 113 if (v_ms_filtered < 0.1) { 114 115 } 116 117 // show with colon 118 dispSpeed.showNumberDecEx(displayValue_m, 0b01000000, false); 119 120 Serial.print("Wind speed: "); 121 Serial.print(v_ms_filtered); 122 Serial.print(" m/s \t"); 123 Serial.print(v_kmh_filtered); 124 Serial.println(" km/h"); 125 126 lastMeasure = now; 127 } 128} 129 130void countPulse() { 131 pulseCount++; 132 lastPulseTime = millis(); 133}
Downloadable files
Anemometer_2
Solidworks image of the assembly
Anemometer_2.jpg

ArmCenter
Arm center
ArmCenter.STL
BaseBox
BaseBox.STL
CoverBox
CoverBox.STL
Cup
Cup.STL
Sonic_Wheel_1
Sonic_Wheel_1.STL
TachoClockHolder
TachoClockHolder.STL
Comments
Only logged in users can leave comments