I'm new to Arduino, but see many possibilities that I'm dying to experiment with. However, I have one immediate project that I'm hoping that I can make a reality. I've checked out quite a few posts and videos on this so far and know that I can do most of what I'm needing to accomplish, which is measuring and displaying the rising edge to rising edge timing. What I can't find any reference to is, is there a way to AVERAGE the last 4 or 5 measurements and display it? What would be even better is to be able to see the last 4 or 5 readings, along with the average. If there's no capability for an averaging, I'll stop wasting my time trying to find info on how to do it and just focus on the sequential readings. Any help would be greatly appreciated.
Store (for example) 5 elements in an array, add them up and divide by 5 to get the average.
For a moving average, most people use a "circular buffer" of the last five readings. Here is an inefficient way of doing that:
int array[5]; //declare array
int index =0; //array index
...
void loop() {
...
array[index++] = new_value; //store new reading
if(index > 4) index = 0; //circular buffer pointer cycles around
int avg = 0;
for (int i=0; i<5; i++) avg += array[i]; //add all five elements
avg = avg/5;
Serial.print(" Avg =");
Serial.println(avg);
...
Okay, so there is capability to do this and display it? If so, I'll keep researching. I just didn't want to keep searching for a capability that doesn't exist. I hadn't had any luck finding any averaging info so far, so I thought I might be wasting my time to continue down that path.
Which is better but resource costly.
Excellent, thank you!
Serial.print(), see above.
You really should spend some time studying the examples that come with the Arduino IDE, in order to learn the programming language and special features of Arduino.
Perhaps the problem is you do not yet, understand that if you can think how you can average something, you can put those thoughts into program code to get the same results as if you did the calculation with pencil and paper. That applies to not just averaging, but EVERY thing that you might want a computer to do for you.
I fully intend to now that I know that the capabilities are there to do everything I need on the very first project. Subsequent projects will be a bit more challenging, but I've already seen enough so far to know that the capabilities I need for those exist and I should be able to work my way through those too. Now, it's time for a deep dive into what I'll be working with. Thanks for your help!
It's a very simple computing task, but I just hadn't found any direct info on being able to display that while measuring frequency. I simply wanted to be sure that was a possibility before wasting any more valuable time trying to confirm the capability. Now that I know that it can be done with these, I'll make it a reality.
Aside from the class cruft, it isn't resource costly. That filter is a simple exponentially weighted moving average:
It is less resource and time costly than averaging an array. (and because of Arduino-library-github-version reasons, it won't calculate the error estimate in a normal install)
You can get the same results with a subtraction, a multiplication, and an addition:
freqEWMA += alpha * (freq - freqEWMA);
To get the period from "rising edge" to "rising edge" I and many others compute a "zero line". Take a bunch of readings, at least 2x or greater than the expected frequency. Add them together and divide by the number of readings. This is your zero line. While reading the data, determine if you are above or below the zero line. If above watch until you cross the zero line then continue until you cross it from below. Mark this point as the start time. Watch the data until you again go negative and again go positive. The difference between the start time and this time is used to calculate the RE to RE timing.
What is the frequency source?
What is the frequency range?
Answers to these questions could help determine how stable the frequency input will be and help determine the best measurement method.
For example, 1-10000 rpm:
- Use an interrupt.
- Use micros() for timing measurements of rising edge to rising edge for best accuracy.
- If actual rpm smoothly increases and decreases, no need for averaging.
- Can get fast readings (1 per pulse period).
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.