Anemometer

I had an anemometer laying around for quite some time and i decided to use it in arduino project …weather station(someday) but first i just want to acurate measure wind speed. My anemometer is almost the same as this one from SparkFun http://www.sparkfun.com/products/8942. Only diference is that my uses Hall switch and gives one pulse per revolution(when magnet passes Hall, output goes high and when it is away from Hall it goes low).

I did some googling and searching and I found similar project but suthor used QRD1114 IR Sensor for reading encoded wheel in anemometer http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1282599142. I modified his code a bit, but i get inacurate readings when comparing to my GPS(driwing with car and anemometer on the roof).
Could someone take a look and helped me.

I almost forgot to tell that im verrrrrrrry new to programming and Arduino.

[quote]// Pin definitions
# define Hall sensor 2		     // Receive the data from sensor

// Constants definitions
const float pi = 3.14159265;           // pi number
int period = 5000;	             // Measurement period (miliseconds)
int delaytime = 2000;	            // Time between samples (miliseconds)
int radius = 69;		   // Radius from vertical anemometer axis to a cup center (mm)

// Variable definitions
unsigned int Sample = 0;	 // Sample number
unsigned int counter = 0;	// magnet counter for sensor
unsigned int RPM = 0;	         // Revolutions per minute
float speedwind = 0;	       // Wind speed (m/s)
float windspeed = 0;           // Wind speed (km/h)



void setup()
{
  // Set the pins
  pinMode(2, INPUT);
  digitalWrite(2, HIGH);     //internall pull-up active
    
  //Start serial 
  Serial.begin(9600);       // sets the serial port to 9600 baud
  }

void loop()
{
  Sample++;
  Serial.print(Sample);
  Serial.print(": Start measurement...");
  windvelocity();
  Serial.println("   finished.");
  Serial.print("Counter: ");
  Serial.print(counter);
  Serial.print(";  RPM: ");
  RPMcalc();
  Serial.print(RPM);
  Serial.print(";  Wind speed: ");
  
//*****************************************************************
//print m/s  
  WindSpeed();
  Serial.print(windspeed);
  Serial.print(" [m/s] ");              
  
//*****************************************************************
//print km/h  
  SpeedWind();
  Serial.print(speedwind);
  Serial.print(" [km/h] ");  
  Serial.println();


  delay(delaytime);                        //delay between prints
}



// Measure wind speed
void windvelocity(){
  speedwind = 0;
  windspeed = 0;
  
  counter = 0;  
  attachInterrupt(0, addcount, CHANGE);
  unsigned long millis();			  
  long startTime = millis();
  while(millis() < startTime + period) {
  }
}


void RPMcalc(){
  RPM=((counter*2)*60)/(period/1000);  // Calculate revolutions per minute (RPM)
}

void WindSpeed(){
  windspeed = ((2 * pi * radius * RPM)/60) / 1000;  // Calculate wind speed on m/s
 
}

void SpeedWind(){
  speedwind = (((2 * pi * radius * RPM)/60) / 1000)*3.6;  // Calculate wind speed on km/h
 
}

void addcount(){
  counter++;
} 


[/quote]

i get inacurate readings when comparing to my GPS(driwing with car and anemometer on the roof).

Are you doing this on a completely windless day? Why do you say your anemometer readings are inaccurate? How are you getting a wind speed reading from your GPS? How does your anemometer reading compare to your speedometer reading if you drive at a constant speed?

Sorry for all the questions - don''t crash trying to answer them.

radman:

i get inacurate readings when comparing to my GPS(driwing with car and anemometer on the roof).

Are you doing this on a completely windless day? Why do you say your anemometer readings are inaccurate? How are you getting a wind speed reading from your GPS? How does your anemometer reading compare to your speedometer reading if you drive at a constant speed?

Sorry for all the questions - don''t crash trying to answer them.

He's using the GPS's speed output to verify the wind speed- which will also vary with an existing head/tail/side wind plus vehicle speed.

Your readings would be nice to see so we can know the current discrepancy.

I expected this questions :)

radman: Are you doing this on a completely windless day? Why do you say your anemometer readings are inaccurate? How are you getting a wind speed reading from your GPS? How does your anemometer reading compare to your speedometer reading if you drive at a constant speed?

1.) No it was a little windy but just a litle, anemometer sitting on car roof was still(car was not moving) so i think that it is ok for testing. 3.) Im driving my car at constant and using GPS speed to compare readings(my car spedo shows 5km/h more then real). And as much as i know if you are driving in car at 50km/h wind moving past you is also 50km/h 4.)My anemometer readings are around 10km/h higher than GPS.

Tomorrow i will try with different GPS, because today i was using GPS on my phone. I will also try to post readings from gps and anemometer.

Did anyone check my code for any mistakes/bugs

in practice, my phone GPS is almost always on-par with my dad’s Garmin.

Let’s pick thru the code in pieces:

// Pin definitions
# define Hall sensor 2		     // Receive the data from sensor

// Constants definitions
const float pi = 3.14159265;           // pi number
int period = 5000;	             // Measurement period (miliseconds)
int delaytime = 2000;	            // Time between samples (miliseconds)
int radius = 69;		   // Radius from vertical anemometer axis to a cup center (mm)

// Variable definitions
unsigned int Sample = 0;	 // Sample number
unsigned int counter = 0;	// magnet counter for sensor
unsigned int RPM = 0;	         // Revolutions per minute
float speedwind = 0;	       // Wind speed (m/s)
float windspeed = 0;           // Wind speed (km/h)

So we’re measuring for 5 seconds and waiting 2 seconds between measurements

void setup()
{
  // Set the pins
  pinMode(2, INPUT);
  digitalWrite(2, HIGH);     //internall pull-up active
    
  //Start serial 
  Serial.begin(9600);       // sets the serial port to 9600 baud
  }

void loop()
{
  Sample++;
  Serial.print(Sample);
  Serial.print(": Start measurement...");
  windvelocity();
  Serial.println("   finished.");
  Serial.print("Counter: ");
  Serial.print(counter);
  Serial.print(";  RPM: ");
  RPMcalc();
  Serial.print(RPM);
  Serial.print(";  Wind speed: ");
  
//*****************************************************************
//print m/s  
  WindSpeed();
  Serial.print(windspeed);
  Serial.print(" [m/s] ");              
  
//*****************************************************************
//print km/h  
  SpeedWind();
  Serial.print(speedwind);
  Serial.print(" [km/h] ");  
  Serial.println();


  delay(delaytime);                        //delay between prints
}

so we have windvelocity(), counter, RPMcalc(), and RPM and inputs to loop().

// Measure wind speed
void windvelocity(){
  speedwind = 0;
  windspeed = 0;
  
  counter = 0;  
  attachInterrupt(0, addcount, CHANGE);
  unsigned long millis();			  
  long startTime = millis();
  while(millis() < startTime + period) {
  }
}

everytime pin 0 changes state, you call addcount, which increases the counter, I.O.W, this is counting the pulses, and counts twice per pulse: change from LOW to HIGH, change from HIGH to LOW

What is the while loop doing?!?!

void RPMcalc(){
  RPM=((counter*2)*60)/(period/1000);  // Calculate revolutions per minute (RPM)
}

Not sure what is going on here. RPM should be # of rotations per 60 seconds, or (rotations/5)60 or rotations12 equivocally. Since you’re counting pulses twice per revolution, you would do rotations = counter/2

you’re doing # of rotations times 240, divided by 5 seconds. Which is equivocal to # of rotations times 48 or (counter/2)*48 or counter * 24

void WindSpeed(){
  windspeed = ((2 * pi * radius * RPM)/60) / 1000;  // Calculate wind speed on m/s
 
}

Taking circumference of the cup region, times RPM, divided by 60 seconds, divided by 1000 to get meters. IE, the tangential speed of the cups = windspeed

void SpeedWind(){
  speedwind = (((2 * pi * radius * RPM)/60) / 1000)*3.6;  // Calculate wind speed on km/h
 
}
void addcount(){
  counter++;
}

If you are driving 50 Km/h, that’s (50,000 m / 3600 s) = 13.89 metres per second.

RPM of a 69mm radius @ 13.89 metres per second = ((2 * pi * 69 * RPM)/60) / 1000 = ((RPM * 433.54) / 60) / 1000 = (RPM * 433.54) / (60 * 1000) = (RPM * 433.54) / 60,000 = 13.89

13.89 = (RPM * 433.54) / 60,000
13.89 * 60,000 = (RPM * 433.54)
833,400 = (RPM * 433.54)
833,400 / 433.54 = RPM
1922 = RPM

Since you’re reading over 5 seconds, 1922 RPM divided by 12 is 160.192 rotations per 5 seconds, which is 160.192 pulses per 5 seconds at one pulse per revolution. At 50 Km/h.

If you are reading 32 RPM at 50 kph then your assumption that cup center moves at wind speed is close. But you should know that the 69mm radius is assumed and work corrections from there?

The anemometer is not frictionless and probably the slower you go the less accurate it measures.

if you are driving in car at 50km/h wind moving past you is also 50km/h My anemometer readings are around 10km/h higher than GPS

Try driving your car at a constant 50km/h with the anemometer on the roof. Then try again with the anemometer at the far end of long wooden plank sticking out of the side window (obviously you do this somewhere where it is safe to drive with a long wooden plank sticking out of the side of your car!). I bet it reads higher on the roof – maybe 10km/h higher.

Your car may be say 3m long, but the distance from the front to the back following the body over the roof will be longer. When the car is moving the air is not going through it, it is flowing over the bodywork which is a longer path. Since it is going further the air is going faster than the car.

I think your anemometer is demonstrating the aerodynamics that generate the lift which helps keep planes in the air. That is a good sign that the anemometer is functioning correctly (I have not checked the code). If the reading on the plank matches the car speed then it is probably also reasonably accurate.

D'oh! You hit the nail on the head Radman! He could raise the thing and project it forward about 1m.

He could raise the thing and project it forward about 1m

That is a million times better than my idea of sticking a plank out the window!

Today i was testing with different GPS and i got same readings (10km/h higher than real). And believe it or not i was thinking the same as thing that Radman. Tomorrow i will try moving my anemometer away from the car and we will se if readings change.

radman:

He could raise the thing and project it forward about 1m

That is a million times better than my idea of sticking a plank out the window!

I don't think so. It would be easier to find places to test with is all. Anyway, you made the right analysis. It would be better to put the anemometer out of disturbed air is why I suggest forward, like they do on planes. And that leads to mounting the thing for use monitoring wind, are they usually mounted on poles?

GoForSmoke:

radman:

He could raise the thing and project it forward about 1m

That is a million times better than my idea of sticking a plank out the window!

I don't think so. It would be easier to find places to test with is all. Anyway, you made the right analysis. It would be better to put the anemometer out of disturbed air is why I suggest forward, like they do on planes. And that leads to mounting the thing for use monitoring wind, are they usually mounted on poles?

I agree. I had thought about it, but didn't feel like making an airflow analysis of a car...

Anemometer testings are on hold, its blowing like hell here. Meanwhile im trying to understand code for reading RPM from Arduino playgraund.

 volatile byte rpmcount;

 unsigned int rpm;

 unsigned long timeold;

 void setup()
 {
   Serial.begin(9600);
   attachInterrupt(0, rpm_fun, RISING);

   rpmcount = 0;
   rpm = 0;
   timeold = 0;
 }

 void loop()
 {
   if (rpmcount >= 20) { 
     //Update RPM every 20 counts, increase this for better RPM resolution,
     //decrease for faster update
     rpm = 30*1000/(millis() - timeold)*rpmcount;
     timeold = millis();
     rpmcount = 0;
     Serial.println(rpm,DEC);
   }
 }

 void rpm_fun()
 {
   rpmcount++;
   //Each rotation, this interrupt function is run twice
 }

And im pretty much interested in this part

 if (rpmcount >= 20) { 
     //Update RPM every 20 counts, increase this for better RPM resolution,
     //decrease for faster update
     rpm = 30*1000/(millis() - timeold)*rpmcount;
     timeold = millis();
     rpmcount = 0;
     Serial.println(rpm,DEC);

As i understand this part of code starts to run only if we get more or equal 20 pulses from anemometer (1pulse per rev.).

But i dont understand what the next line is doing?

rpm = 30*1000/(millis() - timeold)*rpmcount;

we calculate RPM from pulses in given time period wich is (millis()-timeold) times number of pulses in this pereiod. But what is that 30 in there, shouldnt there be 60 ? is that maybe used if we change interrupt mode in CHANGE (LOW=>HIGH ==>HIGH=>LOW) and 60 is for interuupt modes FALLING and RISING

Sorry for my crappy english:=)

 void rpm_fun()
 {
   rpmcount++;
   //Each rotation, this interrupt function is run twice
 }