0
votes

I am trying to get my arduino mega to run a function in the background while it is also running a bunch of other functions.

The function that I am trying to run in the background is a function to determine wind speed from an anemometer. The way it processes the data is similar to that of an odometer in that it reads the number of turns that the anemometer makes during a set time period and then takes that number of turns over the time to determine the wind speed. The longer time period that i have it run over the more accurate data i receive as there is more data to average.

The problem that i have is there is a bunch of other data that i am also reading in to the arduino which i would like to be reading in once a second. This one second time interval is too short for me to get accurate wind readings as not enough revolutions are being completed by the anemometer to give high accuracy wind data.

Is there a way to have the wind sensor function run in the background and update a global variable once every 5 seconds or so while the rest of my program is running simultaneously and updating the other data every second.

Here is the code that i have for reading the data from the wind sensor. Every time the wind sensor makes a revolution there is a portion where the signal reads in as 0, otherwise the sensor reads in as a integer larger than 0.

 void windmeterturns(){
     startime = millis();
     endtime = startime + 5000;
     windturncounter = 0;
     turned = false;
     int terminate = startime;
     while(terminate <= endtime){
           terminate = millis();
           windreading = analogRead(windvelocityPin);
           if(windreading == 0){
               if(turned == true){
                   windturncounter = windturncounter + 1;
                   turned = false;
               }
           }
           else if(windreading >= 1){
               turned = true;
           }
           delay(5);
     }
 }

The rest of the processing of takes place in another function but this is the one that I am currently struggling with. Posting the whole code would not really be reasonable here as it is close to a 1000 lines.

The rest of the functions run with a 1 second delay in the loop but as i have found through trial and error the delay along with the processing of the other functions make it so that the delay is actually longer than a second and it varies based off of what kind of data i am reading in from the other sensors so a 5 loop counter for timing i do not think will work here

2
Couldn't you simply increase a static counter in your 1-second timer and run the windmeter code only if the counter reaches 5 and then reset it to 0?Blutkoete
unfortunately the rest of the code does not precisely run once ever second as there is a one second delay for each loop but the running of the other functions makes the timing slightly more than a second. the delay is enough to make it so the timing is not precise enough to use it as a timer for the wind sensoruser3754203

2 Answers

2
votes

Let Interrupts do the work for you.

In short, I recommend using a Timer Interrupt to generate a periodic interrupt that measures the analog reading in the background. Subsequently this can update a static volatile variable.

See my answer here as it is a similar scenario, detailing how to use the timer interrupt. Where you can replace the callback() with your above analogread and increment.

0
votes

Without seeing how the rest of your code is set up, I would try having windturncounter as a global variable, and add another integer that is iterated every second your main program loops. Then:

// in the main loop
if(iteratorVariable >= 5){
  iteratorVariable = 0;
  // take your windreading and implement logic here
} else {
  iteratorVariable++;
}

I'm not sure how your anemometer stores data or what other challenges you might be facing, so this may not be a 100% solution, but it would allow you to run the logic from your original post every five seconds.