Stuck in gust reading from wind sensor

Hi all,

I'm using the following sketch to evaluate the wind speed and overall the Gust.

What I want to do: Read the wind sensor each second during 10 seconds

What result I want: the average speed during this period and gust speed

What problem do I have? I don't knot how to erase the array after publishing and this average is not working

I simulated a random reading from 0 to 5 because I have not here the sensor

thank's for your help guys I'm very stuck

Eduard

//Global Variables
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

byte seconds_10s; //Keeps track of the "wind speed/dir avg" over last 10 seconds array of data
byte windspdavg[120]; //120 bytes to keep track of 10 seconds average
float windgust_10s[10]; //10 floats to keep track of 10 seconds max
float i;

float windspdkph_avg2m;
//These are all the weather values

float windspeedkph = 0; // [mph instantaneous wind speed]
float windgustkph = 0; // [mph past 10 second wind gust kph ]
long lastWindCheck = 0;


int AnemometerPin = 5;



int count = 0;
// volatiles are subject to modification by IRQs
volatile long lastWindIRQ = 0;
volatile byte windClicks = 0;






void wspeedIRQ()
// Activated by the magnet in the anemometer (2 ticks per rotation), attached to input AnemometerPin D5
{
  if (millis() - lastWindIRQ > 10) // Ignore switch-bounce glitches less than 10ms (228KPH max reading) after the reed switch closes
  {
    lastWindIRQ = millis(); //Grab the current time
    windClicks++; //There is 2.4011412KPH for each click per second.
  }
}



//---------------------------------------------------------------
void setup()
{

  ///////////////////WindMeter///////////////////////////


  pinMode(AnemometerPin, INPUT_PULLUP); // input from wind meters windspeed sensor
  Serial.begin(9600);   // open serial over USB




  // attach external interrupt pins to IRQ functions
  attachInterrupt(AnemometerPin, wspeedIRQ, FALLING);

  // turn on interrupts
  interrupts();
}
//---------------------------------------------------------------
void loop()
{

  for (int i = 0; i < 10 ; i++) {
    //Take a speed and direction reading every second for 10 seconds average
    //if (++seconds_10s > 10) seconds_10s = 0;

    //Calc the wind speed and direction every second for 10 second to get 10 seconds average
    //float currentSpeed = get_wind_speed();
    float currentSpeed = random(0, 5); //For testing
    Serial.println();
    Serial.print("currentSpeed:");
    Serial.println(currentSpeed);
    windspdavg[i] = (int)currentSpeed;

    //if(seconds_10s % 10 == 0) displayArrays(); //For testing

    //Check to see if this is a gust for the 10 seconds reading time
    if (currentSpeed > windgust_10s[i])
    {
      //windgust_10s[seconds_10s] = currentSpeed;
      windgust_10s[i] = currentSpeed;

    }

    delay(1000);
  }

 

  //Get readings from all sensors
  getWeather();
  //Rather than use a delay, keeping track of a counter allows the photon to
  // still take readings and do work in between printing out data.
  //This function prints the weather data out to the default Serial Port
  Serial.println("Data to send ----------------");



  Serial.print("windspeedkph=");
  Serial.print(windspdkph_avg2m);
  Serial.print(",");

  Serial.print("windgustkph=");
  Serial.print(windgustkph);
  Serial.print(",");

  Serial.println("");

   if (i > 10) i = 0;

//  windgust_10s = 0; //Zero out this minute's gust

  delay(5000);
}


//---------------------------------------------------------------
//Returns the instataneous wind speed
float get_wind_speed()
{
  float deltaTime = millis() - lastWindCheck; //750ms

  deltaTime /= 1000.0; //Covert to seconds

  float windSpeed = (float)windClicks / deltaTime; //3 / 0.750s = 4

  windClicks = 0; //Reset and start watching for new wind
  lastWindCheck = millis();

  windSpeed *= 2.4011412;

  Serial.println();
  Serial.print("Windspeed:");
  Serial.println(windSpeed);

  return (windSpeed);
}


//---------------------------------------------------------------
void getWeather()
{

  //Calc windspeed
  windspeedkph = get_wind_speed();

  //Calc windspdkph_avg2m
      float temp = 0;
     for(int y = 0 ; y < 10 ; y++)
       temp += windspdavg[y];
     temp /= 10.0;
     float windspdkph_avg2m = temp; 




  //Find the largest windgust in the last 10 seconds
    for (int x = 0; x < 10 ; x++)
    {
      if (windgust_10s[x] > windgustkph)
      {
        windgustkph = windgust_10s[x];
  
      }
    }


}

You have two different variables named windspdkph_avg2m. One local to the getWeather() and one global

Do you need to erase the array as you are going to write over it anyway ?
If you do then a for loop would be the easy way.

Hi @UKHeliBob

I'm really sorry, but I don't understand. Did I define the same variable twice? the loop is just for the test, the script will be fit in a deep sleep sketch that reboots after 15 minutes

thank's

Did I define the same variable twice?

It's slightly more subtle than that

You define a global variable at the start of the program

float windspdkph_avg2m;

Because it is a global its value will default to zero

You define and initialise a local variable in the getWeather() function

 float windspdkph_avg2m = temp;

They have the same name but are different variables with different scopes

Once the function is finished and the program returns to where it was called the windspdkph_avg2m variable declared in the function no longer exists so when you do

  Serial.print("windspeedkph=");
  Serial.print(windspdkph_avg2m);

you are printing the value of the global variable which has never changed from zero

GREAT!!! IT WORKS!!!!

thank you very much for your help

best

Eduard

Hi,

My last question, I see that the arrays after every loop are not clean, I tried to clean the array using this function but did not works

for( int a = 0; a < sizeof(windgust_10s); ++a )
windgust_10s[10] = (char)0;

Anyone could help to me to clean the arrays after every loop?

Thank you
Eduard

for( int a = 0; a < sizeof(windgust_10s);  ++a )
    windgust_10s[10] = (char)0;

Close, but no cigar !

1 - the windgust_10s array is declared as float. sizeof() returns the number bytes used by the array, not the number of elements. Divide the number returned by

sizeof(windgust_10s [0])

to get the number of elements

2 - why are you using ++a and not a++ ? Do you understand the difference ?

3 - you are only ever writing to element 10 of the array which does not exist. You should be writing to windgust_10s[a]

4 - why are you putting chars in the array ?

UKHeliBob:

for( int a = 0; a < sizeof(windgust_10s);  ++a )

windgust_10s[10] = (char)0;



Close, but no cigar !

1 - the windgust_10s array is declared as float. sizeof() returns the number bytes used by the array, not the number of elements. Divide the number returned by


sizeof(windgust_10s [0])



to get the number of elements

2 - why are you using ++a and not a++ ? Do you understand the difference ?

3 - you are only ever writing to element 10 of the array which does not exist. You should be writing to windgust_10s[a]

4 - why are you putting chars in the array ?

Hi @UKHeliBob

answering your questions:

1º ok

2º No I don't...I read this solution in a Forum
3º ok
4º you are right I erased the arrays and I did some averages

Thank's for your help

//Global Variables
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
float Racha;
float WindAcc;
float WindAVG;
float i;
long lastWindCheck = 0;

int AnemometerPin = 5;

// volatiles are subject to modification by IRQs
volatile long lastWindIRQ = 0;
volatile byte windClicks = 0;

void wspeedIRQ()
// Activated by the magnet in the anemometer (2 ticks per rotation), attached to input AnemometerPin D5
{
if (millis() - lastWindIRQ > 10) // Ignore switch-bounce glitches less than 10ms (228KPH max reading) after the reed switch closes
{
lastWindIRQ = millis(); //Grab the current time
windClicks++; //There is 2.4011412KPH for each click per second.
}
}

//---------------------------------------------------------------
void setup()
{
///////////////////WindMeter///////////////////////////

pinMode(AnemometerPin, INPUT_PULLUP); // input from wind meters windspeed sensor
Serial.begin(9600); // open serial over USB

// attach external interrupt pins to IRQ functions
// turn on interrupts
attachInterrupt(AnemometerPin, wspeedIRQ, FALLING);
interrupts();
}
//---------------------------------------------------------------
void loop()
{

for (int i = 0; i < 10 ; i++) {
//Take a speed and direction reading every second for 10 seconds average
//if (++seconds_10s > 10) seconds_10s = 0;

//Calc the wind speed and direction every second for 10 second to get 10 seconds average
//float currentSpeed = get_wind_speed();
float currentSpeed = random(0, 105); //For testing
Serial.println();
Serial.print("currentSpeed:");
Serial.println(currentSpeed);

WindAcc = WindAcc + currentSpeed;
WindAVG = WindAcc / (i + 1);

Serial.print("Accum:");
Serial.println(WindAcc);
Serial.print("Average:");
Serial.println(WindAVG);
Serial.print("Iteracio:");
Serial.println(i + 1);

delay(1000);

//Check to see if this is a gust for the 10 seconds reading time
if (currentSpeed > Racha) //windgust_10s[10])
{
Racha = currentSpeed;

}
}

//Rather than use a delay, keeping track of a counter allows the photon to
// still take readings and do work in between printing out data.
//This function prints the weather data out to the default Serial Port
Serial.println("Data to send ----------------");

Serial.print("windspeedavg=");
Serial.print(WindAVG);
Serial.print(",");

Serial.print("windgustkph=");
Serial.print(Racha);
Serial.print(",");

Serial.println("");
Racha = 0;
WindAcc = 0;
WindAVG = 0;

delay(5000);
}

//---------------------------------------------------------------
//Returns the instataneous wind speed
float get_wind_speed()
{
float deltaTime = millis() - lastWindCheck; //750ms

deltaTime /= 1000.0; //Covert to seconds

float windSpeed = (float)windClicks / deltaTime; //3 / 0.750s = 4

windClicks = 0; //Reset and start watching for new wind
lastWindCheck = millis();

windSpeed *= 2.4011412;

Serial.println();
Serial.print("Windspeed:");
Serial.println(windSpeed);

return (windSpeed);
}

//---------------------------------------------------------------

2º No I don't...I read this solution in a Forum

++a  //increment the value before using it
a++  //use the value then increment it

Think carefully what difference that would make in a for loop

Hi,
Looking at your program, it looks like you have an anemometer head like mine. The rotating magnet is centered directly over the reed switch so the switch closes twice per magnet revolution. As the bar magnet is exactly in line with the metal reeds of the switch, it is impossible for the switch to bounce.

If your device is as I described, you can take out the de-bounce code and the interrupts will occur perfectly.

Paul

Paul_KD7HB:
it is impossible for the switch to bounce.

That good sir is the funniest thing I have read all day, thank you.

Of course reed switches can and do bounce on opening and closing, you likely have some delay after the first “contact hit” that makes the bounce irelevant.

Paul_KD7HB:
Hi,
Looking at your program, it looks like you have an anemometer head like mine. The rotating magnet is centered directly over the reed switch so the switch closes twice per magnet revolution. As the bar magnet is exactly in line with the metal reeds of the switch, it is impossible for the switch to bounce.

If your device is as I described, you can take out the de-bounce code and the interrupts will occur perfectly.

Paul

Hi Paul_KD7HB

I'm really sorry, but I did not understand anything :slight_smile: ....I'm using this anemometer:

ecabanas:
Hi Paul_KD7HB

I'm really sorry, but I did not understand anything :slight_smile: ....I'm using this anemometer:

Weather Meter Kit - SEN-15901 - SparkFun Electronics

I guess if you did not take the thing apart, you could not see how it it made. I seem to always need to see the insides of things.

Paul

Slumpert:
That good sir is the funniest thing I have read all day, thank you.

Of course reed switches can and do bounce on opening and closing, you likely have some delay after the first “contact hit” that makes the bounce irelevant.

Reed switches were used LONG before solid state devices existed and if properly installed never had a bounce problem. Do you see reed relays being used with bouncing contacts?

The magnetic lines follow the reeds. One North pole, one South pole when they approach each other, the magnetic attraction force will not allow bounce.

When reed switches are used with other than bar magnets that are parallel to the axis of the reed switch then you get bounce.

Paul