Creating an anemometer (wind speed)

Hello everybody, I’m creating an anemometer to measure the wind speed.
I’m facing with a problem, maybe if we think all togheter we can find a solution :stuck_out_tongue_closed_eyes:

This is the project: http://www.xunga.eu/wp-content/uploads/2014/06/DSC0301.jpg

So i have a disk with an hole that rounds on a stick by a ball bearing in order to have the least possible friction. Under the disk there is a LED and upper the disk there is a photoresistor.

So I record how many times the disk does a turn in 1 second and I do this formula: [km/h]= ((2pir)/interval*3600)*turns

pi=3.14;
r=3,6 cm → 0.00036 km;
interval= 1 s;

the point is that I don’t get a realiable value.

What i’m doing wrong? here is my code:

#include "DHT.h"
#define ledPin 13  //LED connesso al pin digitale 13
#define interval 500//Intervallo di tempo per  far lampeggiare il LED(millisecondi)

DHT dht;
int max=60;
unsigned long previousMills = 0;  //Memorizza l'ultima volta che il led è stato aggiornato
int turn=0;
float result=0;
int light;

void setup()
{
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);  //Impostiamo il led come output
  digitalWrite(ledPin, HIGH); 
    dht.setup(12);
}

void loop()
{

  turn=0;
  light =0;
  result =0;
  do{
    light = analogRead(A0);

    if (light > max){
      turn++;

    }
  }
  while (millis() -  previousMills <= interval );
  previousMills = millis();  

  result=((2*3.14*0.00036  )/interval*3600)*turn;

    float humidity = dht.getHumidity();
    float temperature = dht.getTemperature();
    Serial.print("h:");
    Serial.print(humidity);
    Serial.print(";t:");
    Serial.print(temperature);
    Serial.print(";v:"); 
    Serial.println(result);
  
}

Hi mrxd

Could you post a sample of the results you get. In what way are they not reliable?

Also, I think you should move this statement to just before the "do" loop.

previousMills = millis();

In your code, the statements after the do loop are being included in the sample period.

Regards

Ray

Hello again, mrxd.

I believe that now you are "facing" the problem. So, why did you say that r=3,6 cm? It sounds to me a very small value.
You may change interval to 1s instead of 500s.

Hackscribble:
Hi mrxd

Could you post a sample of the results you get. In what way are they not reliable?

Also, I think you should move this statement to just before the “do” loop.

previousMills = millis();

In your code, the statements after the do loop are being included in the sample period.

Regards

Ray

Moved the prviousMills=millis();

I say that is not reliable because I tested it with an hairdryer and it shows at speed 1: around 4-5km/h and at speed 2 I recive something like 4-5-6 km/h.

here is a try:
v:3.55
v:6.74
v:3.17
v:6.51
v:6.51
v:3.27
v:5.86
v:5.50
v:5.31
v:5.50
v:5.70
v:2.85
v:3.01
v:5.37

I think an hair dryer should go much faster no?

luisilva:
Hello again, mrxd.

I believe that now you are “facing” the problem. So, why did you say that r=3,6 cm? It sounds to me a very small value.
You may change interval to 1s instead of 500s.

Hello again Luis :slight_smile: Maybe you are right… I’ve changed it and it displays hair dryer 11km/h, but my blow is around 13-17-36km/h. Am I stronger than an hair dryer?

I believe that r=3,6cm is wrong.
I believe that interval in seconds = 500s is wrong.
I believe that:

    light = analogRead(A0);

    if (light > max){
      turn++;

    }

is wrong, like I said in the other tread.

Why don’t do something like:

int trigger = 1;
(...)

    light = analogRead(A0);

    if (light > max && trigger == 1){
      turn++;
      trigger = 0;
    }
   if (light < min ) {
      trigger = 1;
   }

r=3,6 cm -> 0.00036 km;

3.6cm = 0.036m = 0.000036km. One more decimal place than your constant :slight_smile:

luisilva:
I believe that r=3,6cm is wrong.

why? 3,6 cm is the distance from the center to the border. You say that is too much small?

luisilva:
I believe that interval in seconds = 500s is wrong.
I believe that:

    light = analogRead(A0);

if (light > max){
     turn++;

}




is wrong, like I said in the other tread.

Why don't do something like:


int trigger = 1;
(…)

light = analogRead(A0);

if (light > max && trigger == 1){
     turn++;
     trigger = 0;
   }
  if (light < min ) {
     trigger = 1;
  }

That is a smart idea! For sure will make the result more realiable, but i’m still doing something wrong, something wrong, hair dryer max speed now results 13 km/h :frowning:

Hackscribble:
3.6cm = 0.036m = 0.000036km. One more decimal place than your constant :slight_smile:

upsss :*

Why are you double posting. It wastes everone's time.

I will recommend to the Moderator that this be merged with your other Thread

...R

Robin2 is right. One of the rules of the forum is "don't cross post".

That is a smart idea!

I said this from the very first time:

  result=((2*3.14*0.00036  )/interval*3600)*turn;

You have interval in milliseconds and 3600"s/h" in seconds. You must change one. Or you define another variable to hold the value of the interval in seconds and after the while cycle you calculate the interval in seconds or you use 3600000 "ms/h".

EDIT: I forgot this part:

why? 3,6 cm is the distance from the center to the border. You say that is too much small?

It must be the distance form the centre to the centre of the cup that catches the wind, and it seems to me a small value. Remember that you want the velocity of the wind and not the velocity of the disk with the hole.

This formula is wrong…

result=((2*3.14*0.00036  )/interval*3600)*turn;

You need to multiply by the number of milliseconds in an hour, not the number of seconds.

This does not count the number of turns…

  do{
    light = analogRead(A0);

    if (light > max){
      turn++;

    }
  }
  while (millis() -  previousMills <= interval );

You want to count the number of light pulses. Which means the rising edge. If light was less than max and is now greater than max, you have a rising edge. If light was greater than max and is still greater than max, you’re still looking at the same pass of the hole.

Robin2:
Why are you double posting. It wastes everone’s time.

.

luisilva:
Robin2 is right. One of the rules of the forum is “don’t cross post”.

Sorry, I was thinking that the topic was different (before, I was stuck in the cycle, now I’m blocked with something else)
.

luisilva:

I said this from the very first time:
http://forum.arduino.cc/index.php?topic=245027.msg1752915#msg1752915

I didn’t get it before… now with the trigger I understood :slight_smile: obrigado!

luisilva:

  result=((2*3.14*0.00036  )/interval*3600)*turn;

You have interval in milliseconds and 3600"s/h" in seconds. You must change one. Or you define another variable to hold the value of the interval in seconds and after the while cycle you calculate the interval in seconds or you use 3600000 “ms/h”.

DavidOConnor:
This formula is wrong…

result=((2*3.14*0.00036  )/interval*3600)*turn;

You need to multiply by the number of milliseconds in an hour, not the number of seconds.

so result=((2*3.14*0.000065  )/0.5*7200)*turn; OR result=((2*3.14*0.000065  )/1*3600)*turn; should be right?

luisilva:
EDIT: I forgot this part:

why? 3,6 cm is the distance from the center to the border. You say that is too much small?

It must be the distance form the centre to the centre of the cup that catches the wind, and it seems to me a small value. Remember that you want the velocity of the wind and not the velocity of the disk with the hole.

mmmh right so it’s 6,5 cm…

By the way, the formula:

result=((2*3.14*0.00036  )/interval*3600)*turn;

converts "rps" (rotations per second) to km/h (kilometres per hour). So you need to convert rotations to kilometres and seconds to hours. The part of the formula that multiplies by "2 * pi * r" converts the rotations to kilometres (or length, because you are calculating the perimeter of the circle of radius "r" and you are using the value of the radius in kilometres). The part of the formula that multiplies by "3600/interval" must convert seconds to hours.

Because you are using the value of interval in milliseconds, in the last part you think you are converting seconds to hours, but you are converting milliseconds to other thing!

I hope the explanation is clear now.

The tangential speed of the rotor is not the same as the wind speed. You will need to calibrate. You could assume a linear error and apply a gain and offset to your result.

DavidOConnor is right, the error depends of the bearings that you are using.

luisilva:
DavidOConnor is right, the error depends of the bearings that you are using.

And the aerodynamics of the blades. And the orientation of the rotor. And the turbulence of the air flow. And the dimensional asymmetry of the rotor. And the fouling of the blades.

It is silly to have a calculation like this in your program

result=((2*3.14*0.00036  )/interval*3600)*turn;

Get out your calculator and simplify it to 8.139 / interval * turn (hope my maths is correct)

Add a comment to remind you how the 8.139 was derived.

I would also look for a way to eliminate floating point calcs - perhaps multiply everything by 1000 and use LONGs

...R

Hi, using BODMAS, I agree..

Tom.... :slight_smile:

TomGeorge:
BODMAS.

I guess that shows our age :slight_smile:

...R