 # How can I smooth out a variable

Hello,

Currently, I'm working on a speedometer with Hall Effect sensor, and I have a variable which is the velocity.
I want to smooth out the sharp changes in the variable. For example: The wheel stands still, the value of the variable is 0. Then, I spin the wheel immediately, and it jumps up from 0 to like 20. What I'm trying to do is to make that jump a lot smoother, like it counts up to 20. Whenever a change occurs in the variable, I don't want to happen instantly. Another case: The wheel is spinning, the value is 20, then I hit the brake a little, and it goes down to 15. But that change is really sharp. Can it count down from 20 to 15?
Edit: it counts up to 20.

You have almost answered your own question. At any one time the actual speed will have a current value, say 20, and the displayed speed will have a value, say 0.

Now suppose that you want to display the speed every second. If every second you added 1 to the displayed speed then you will achieve the sort of effect you want. Of course, 1 second is probably too long but it will do as an example

So, the question is, how do you know that 1 seconds has elapsed whilst still measuring the speed ? The answer is not the delay() function, rather you can use the millis() function and arrange things so that operation of the program is not blocked as would be the case if the delay() function were used.

Take a look at Using millis() for timing. A beginners guide, Several things at the same time and look at the BlinkWithoutDelay example in the IDE to see how to do it.

Store the last 5-10 readings and calculate the average of those readings.

``````#define NUM_READINGS 10;

{
static byte index = 0;
if (index >= NUM_READINGS) index = 0;
int result = 0;
for (byte i = 0; i < NUM_READINGS; i++) result += values[i];
}
``````

Or add one eighth of the current reading to seven eighths of the running total. ( Or one quarter to three quarters etc etc)

SwengX:
Currently, I'm working on a speedometer with Hall Effect sensor, and I have a variable which is the velocity.
I want to smooth out the sharp changes in the variable.

I always like the software low-pass filter.

``````int reading;

void loop() {
if(its time to take another reading) {
}
}
``````

It's important pay attention to timing - to take a reading only every 10ms, or whatever. That way the smoothed_reading approaches the current reading in a predictable way.

You can also do things like having two smoothed variables, one reacting quicker than the other. This will tell you something about the rate of change of the data.

I did a tacho thing myself, and I also used a ring buffer to smooth things out. Code is here.

Or, optimizing the math:

``````int reading;

void loop() {
if(its time to take another reading) {
}
}
``````

Regards,
Ray L.

I edited the post, so you can see it clearly what I'm saying.

SwengX:
I edited the post, so you can see it clearly what I'm saying.

You have received multiple sollutions to your question, have you tried to implement either and how did it work for you?

The image in the first post shows the behavior of a simple moving average filter, and this is what the code posted by Danois implements.
Here's another more efficient implementation with an explanation and an Arduino example: Simple Moving Average example

The code posted by PaulMurrayCbr and RayLivingston implements an exponential moving average filter. It has an exponential step response, while the simple moving average filter has a linear step response.

A comparison between the two is shown here.

A more efficient integer implementation of the EMA can be found here: Exponential Moving Average example

Pieter

RayLivingston:
Or, optimizing the math:

``````    smoothed_reading += (reading - smoothed_reading) * .05;
``````

Nice. Kinda expresses the idea that we are gradually sneaking up onto the new value, whereas my (less efficient) code more expresses the idea of a recursive filter Recursive Implementation. The numbers come out identically, sans floating point rounding.

PaulMurrayCbr:
Nice. Kinda expresses the idea that we are gradually sneaking up onto the new value, whereas my (less efficient) code more expresses the idea of a recursive filter Recursive Implementation. The numbers come out identically, sans floating point rounding.

And, if efficiency is a concern, you can use 32-bit integers, and fractional math, with power-of-twos coefficients to make it faster, by converting the multiplies to shifts, as long as you're careful about the dynamic range, and don't make the coefficient too small. In many cases, this will give even better precision than single-precision floats, with much less overhead, both in code size and speed.

Regards,
Ray L.

Hi, In your Arduino.IDE go to:
Sketch>include library>Library Manager
and find
Simple Kalman Filter
(Install it)
Or:

This is the easiest way to achieve what you want...

So this code works like a charm, but when I use it around a huge code, it messes up the values

It’s hard to imagine another sentence containing so little information.