Measuring wind run from anemometer, similar to odometer

I've got a cup anemometer which produces an output voltage according to the wind speed.

0V meaning no wind and 5V meaning wind at 180kph
The output voltage is lineair to the wind speed.
I've got it all running but would like to add the functionality of measuring wind run.
The wind run is the distance covered by the wind in a 24 hr period.

So, basically this is like an odometer with a reset to zero at midnight.
I am using a DS3231 RTC and I've got that working.

I am just confused how to do this.; Anybody out there who can give me an idea?

You can integrate particle velocity with respect to time (sum up individual v*t measurements) to get distance traveled. Example: if the wind is constant at 10 kph for one hour, wind run= 10 km.

How will you deal with wind direction changes?

Thanks jremington,
but I'm not sure what you mean by this; could you please elaborate on this a bit more?

The change of wind direction is not important.
The measured wind run is a good indication how windy a particular day was and is independent of the wind direction.

I'm not sure what you mean by this;

What do you mean by "this"?

The measured wind run is a good indication how windy a particular day

So is the average wind speed, which is much the same thing as "wind run".

Sorry jremington, let me explain a bit more:

With wind run we measure the total distance of the wind traveled during a period of 24 hours and the unit is expressed in kilometers.

A calm day would be in the order of say 100 km. A very windy day could be easily 1500 km.

I was thinking of sampling wind speed every second or say, then put it in an array and add these values together.
However, the array would become rather big as there would be 60 sample points every minute, 3600 sample points each hour and then 86,400 sample points for the day.

I just don't know where to start.

A calm day would be in the order of say 100 km. A very windy day could be easily 1500 km.

So a calm, 24 hour day would have an average wind speed of 100 km/24 h = 4.2 km/h (a very light breeze).

And a very windy, 24 hour day would have an average wind speed of 1500 km/24 h = 62.5 km/h (a few trees blow down).

To me, those statements are equally informative.

However, if you really want to calculate wind run, you MUST use averages of some sort. You could, for example, measure the wind speed every second for 60 seconds, total up the 60 values and divide by 60. That gives you the average wind speed during that minute, in km/h if that is what the anemometer reports.

The total distance in km that the wind travels during that minute is (average wind speed in km/h)*(1/60 hour). Note: (1/60 hour) = 0.01667 hours.

Do that 1440 times, adding up the intermediate results, and you get wind run per day.
.

You could use a university coarde in digital integration algorithms like Runge Kutta, and a few more. Using very small measuring intervals, like seconds, sometimes gives a less accurate result than other methods.

float currentWindSpeed, windRun;
unsigned long totalWindSpeed;

void loop() {
  if (onesecondhaspassed) {
    currentWindSpeed = analogRead(A0) * 0.176; // in km/h
    totalWindSpeed += currentWindSpeed; // add each new value
  }
  if (midnight) {
    windRun = totalWindSpeed / 20460; // in km
    totalWindSpeed = 0; // reset
  }
}

Edit: corrected calc.

Shouldn't the divisor be 86400, the number of seconds in 24 h?

Max A/D value (1023) * seconds per day (86400) is a value of 88387200.
That, divided by 20460, is 4320 (km).
Which is the max value of the sensor (180km/h) * 24h.
Leo..

But you aren't averaging ADC values, you are averaging km/h values, each with a weight of 1 second. Sum of the weights is 86400.

jremington:
But you aren't averaging ADC values, you are averaging km/h values, each with a weight of 1 second.

Duhh, you're right. I wanted to average A/D values, and did so in my mind.
+1 for pointing that out.
Hope this sketch is correct now.
Leo..

int rawValue;
float currentWindSpeed, windRun;
unsigned long totalWindSpeed;

void loop() {
  if (onesecondhaspassed) {
    rawValue = analogRead(A0);
    currentWindSpeed = rawValue * 0.176; // in km/h
    totalWindSpeed += rawValue; // add each new value
  }
  if (midnight) {
    windRun = totalWindSpeed / 20460; // in km
    totalWindSpeed = 0; // reset
  }
}

Did you post the old file?

Hi to all participants to this discussion.
I have been following this with interest and like the the different thinking processes.

After taking all this information in consideration I came up with following thinking process:

Every second we measure the wind speed.
Say the first second we measure 20 kph. This is equal to 20,000 meters / 3600 = 5.55 meters traveled in one second
After two seconds we measure current wind speed at 18 kph. This is equal to 18,000 / 3600 = 5.00 meters traveled in one second.
Total wind run after two seconds is now 10.55 meters or 0.01055 km
If we keep doing this for 24 hours than we will have the total wind run for the day. At midnight we do a reset and start again.
The beauty of this is that we can see the the wind run at any given time during the day.

So, I will need three variables one for the amount of meters traveled in one second, the total accumulation of distance so far and the seconds which needs to be incremented each time we take a sample.
I will just need to maintain accurate timing, however, with a DS3231 RTC that won't be a big issue.

Your thoughts please on this reasoning process.
Thank you for your input and karma updated for all!

Your reasoning seems correct to me. To store or add together numbers like 5.55 and 5.00, you need a float variable.

Wawa's outline program could be modified as follows:

float currentWindSpeed, windRun=0.0, scale = 1./3600.;

void loop() {
  if (onesecondhaspassed) {
    currentWindSpeed = analogRead(A0)*0.176;; // in km/h
    windRun += currentWindSpeed*scale; // add new distance (km)
  }
  if (midnight) {
    Serial.println(windRun);
    windRun = 0.0; // reset
  }
}

Caveat: adding lots of small numbers leads to rounding errors, so you might want to take the measurement each minute instead and use scale = 1./60.0.

Seems to me that measuring to a fraction of a mph and every second is over kill - I would use integer mph and no oftener than once a minute - the wind gusts a bit but not every second and are your cups calibrated to a fraction of a mph??

I think I've got the code I wanted. :grinning:
It works great.
Here's my code:

/*Experimental code to measure wind run over a perid of 24 hours.
In this code I substitute the anemometer output with a random value generated by a floating pin A0
 */
float windSpeed = 0;
float distanceTraveled;
float windRun = 0;
long count = 0;

void setup() {
  Serial.begin(9600);
  randomSeed(analogRead(0)); //Relies on the floating input of analog pin A0
}

void loop() {

  windSpeed = random(0, 50); //Gives a random integer between 0 and 50, multiplied by 1000 to convert to meters, to simulate wind speed from anemometer
  distanceTraveled = windSpeed * 1000 / 3600; // Gives wind speed in meters per hour and then converts it to meters traveled in one second
  
  windRun = windRun + distanceTraveled;
  Serial.print(count);
  Serial.print(" | ");
  Serial.print(windSpeed);
  Serial.print(" | ");
  Serial.print(abs (distanceTraveled)); //Absolute value of random number, sometimes there were negatives
  Serial.print(" | ");
  Serial.println(windRun);
  count++;
  delay(1000); //Will be substituted by reading the SD3231 RTC every second)
  if(count == 31) //This will reset the code every 30 seconds, in reality it should be reset every 86400 seconds = 24 hours
  {
    Serial.print("Windrun for the day is: ");
    Serial.println(windRun);
    count = 0;
    distanceTraveled = 0;
    windRun = 0;
  }
  }

It is soo simple! I wonder why it took me that long to come up with this. That's why this forum is so great; An opinion on the problem by somebody else can be very helpful.

Thanks to all participating for all your help!

Could have a circular buffer that contains the last 60 samples.
Then you can display true, and calculate min max and average windspeed of the last minute from that.
Leo..

Hi Leo,

thanks for that but I've got separate code for that.
In my wind speed measurements I read the current wind speed, the maximum gust, the average wind speed over the last 10 minutes, the maximum wind gust for the day, etc.

This post is just about the wind run and that's why I didn't want to include it. Otherwise it would become too complex to deal with all these different variables all at once.

A float has a resolution of only about 6 digits - wouldn't it be possible for the float value to become so great that the small individual additions get lost in rounding?