# Pinwheel

Intended to use rotational speed on pinwheel to measure wind speed by converting angular velocity of the pinwheel to linear velocity. Looking back, I’m not sure how accurate this way of measuring wind speed is, considering properties of the pinwheel (such as friction).

Angular velocity is calculated by using a photocell to detect when a blade of the pinwheel passes over.

What it looks like:

A simple demo video that shows it working:

Code:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | #include <wire .h> #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" Adafruit_7segment matrix = Adafruit_7segment(); int historyLength = 100; float sensorHistory[100]; float runningL; float runningMaxL; float runningMinL; float threshhold; boolean covered; int speedHistLen = 400; float speedHistory[400]; // the setup routine runs once when you press reset: void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); matrix.begin(0x70); for (int i=0; i<historylength ; i++) { sensorHistory[i] = 0; } for (int j=0; j<speedHistLen; j++) { speedHistory[j] = 0; } threshhold = 0.75; covered = false; } void loop() { // read the input on analog pin 0: int sensorValue = analogRead(A0); float currL = (float)sensorValue; for (int i=historyLength; i>0; i-- ){ sensorHistory[i] = sensorHistory[i-1]; } sensorHistory[0] = sensorValue; float currMax = -9999; float currMin = 9999; for (int i=0; i</historylength><historylength ; i++) { float ith = sensorHistory[i]; if (ith>currMax) { currMax = ith; } if (ith<currmin ) { currMin = ith; } } float A = 0.96; float B = 1.0-A; runningL = A*runningL + B*currL; runningMinL = A*runningMinL + B*currMin; runningMaxL = A*runningMaxL + B*currMax; float currRange = runningMaxL - runningMinL; float halfRange = currRange/2; unsigned long currMillis = millis(); if (currRange>15.0) { if (!covered && currL< (runningL-threshhold*halfRange)) { //If sensor is NOT covered and current sensor value falls below threshhold, //then a blade is currently passing over updateLinearSpeed(0); covered = true; } else if (covered && currL>(runningL+threshhold*halfRange)) { //If sensor IS covered and current sensor value falls above threshhold, //then a blade just passed over, so update speed updateLinearSpeed(1); covered = false; } else { updateLinearSpeed(0); } } delay(1); } int nBlades = 8; float radius = 0.085; //in meters void updateLinearSpeed(int n) { int totalPasses = 0; for (int i=speedHistLen-1; i>0; i-- ){ speedHistory[i] = speedHistory[i-1]; totalPasses+=speedHistory[i]; } speedHistory[0] = n; totalPasses+=n; float spinSpeed = 2.0*PI/nBlades*radius*((float)totalPasses)/((float)speedHistLen); Serial.println(spinSpeed); int displayed = (int)spinSpeed*100; int tens = displayed/1000; int ones = (displayed/100)%10; int tenths = (displayed/10)%10; int hundredths = displayed%10; matrix.writeDigitNum(0,tens,false); matrix.writeDigitNum(1,ones,true); matrix.drawColon(false); matrix.writeDigitNum(3,tenths,false); matrix.writeDigitNum(4,hundredths,false); matrix.writeDisplay(); } </currmin></historylength></wire> |