Noise, noise, noise. At this point in the blog, it should be clear that in any electronic system one of the main problems is signal noise. In this context, we understand noise as high-frequency, random signals that interfere with the signal of interest.
Noise is a real and annoying reality when using sensors. Although the quality of the sensor significantly influences the amount of noise in the measurement, the truth is that all sensors have noise.
With the price range of sensors we buy for our home projects, sadly, noise in measurements will be a constant problem to deal with.
Sometimes we can incorporate some physical filtering system but, in general, if we want to seriously use sensors in our projects we will have to learn to handle and filter sensor measurement noise digitally.
Multiple Sampling to the Rescue
Assuming we have already done everything possible to improve the physics of the sensor and its environment, the problem reduces to the fact that we are going to acquire samples and these will not correctly reflect the measured magnitude.
Since the samples taken individually are not reliable and we have already done everything possible to improve them, it follows that the only possibility is to perform multiple sampling, that is, to acquire the sensor measurement several times.
Later we will have to apply some kind of algorithm to combine the samples and obtain a measurement with greater precision than the individual samples.
Imagine, for example, that we are measuring the temperature of an instance. When taking measurements from a temperature sensor we will receive a sequence that, for example, is 24.9, 24.8, 24.7, 24.8, 27, 24.8.
We see that there are small variations between samples (noise, oscillations) and one point (27) that at first glance seems “anomalous” (we will call these types of points spurious or outliers).
What is the temperature of the instance? Surely, as a first intuition, we would say about 24.8 degrees. But it’s worth reflecting for a second on this quick answer.
Before answering we should know, for example, the precision of the sensor, the time between samples, and the speed of the system we are measuring. Could it be that they were taken every 30 minutes, and we actually reached 27º at one point?
Measurement, sampling, and filtering are important, broad, and complex topics. There are many parameters to consider, and a huge variety of filtering algorithms (mean, median, exponential…) each with its advantages and disadvantages.
On the blog, we will see many ways to filter signals and, in particular, how to use them to reduce noise in sensor acquisition. For now, let’s start with two simple procedures to perform multiple sampling of a sensor.
Acquisition by Constant Samples
Probably the simplest way to perform multiple sampling is to measure a fixed number of times. For example, we have a sensor but instead of taking a single measurement we take 20, or 50, or 100 in a row.
The number of samples will depend on the speed of the sensor and the time we want to spend measuring.
Later we will have to process the data. In the example we are going to use the mean, because it is quick to calculate and does not require storing the measured values. In other posts we will see other filters.
float MeasureN(int samplesNumber, float (*funct)())
{
float sum;
for (int i = 0; i < samplesNumber; i++)
{
sum += funct();
}
return sum / samplesNumber;
}
// Function that simulates the measurement of a sensor
float getMeasure()
{
return 0.0;
}
void setup()
{
float measureN = MeasureN(100, getMeasure);
}
void loop()
{
}
Acquisition in Constant Time
A variation is to measure over a constant time interval. Example, we take a sensor and decide we want to take all possible measurements for 20, or 50 or 100 ms.
Again, the time depends on the speed of the sensor and the time we want to dedicate to the measurement, but in this case we have much greater control over the time we will be measuring. This makes it more convenient in many cases to integrate into our programs.
float MeasureT(int msInterval, float(*funct)())
{
float sum;
long startTime = millis();
int samplesNumber = 0;
while (millis() - startTime < msInterval)
{
samplesNumber++;
sum += getMeasure();
}
return sum / samplesNumber;
}
// Function that simulates the measurement of a sensor
float getMeasure()
{
return 0.0;
}
void setup()
{
float measureT = MeasureT(50, getMeasure);
}
void loop()
{
}
Adding Max, Min and Mid Points
Sometimes we not only want to obtain the filtered value (in this case the mean) of the sampling, but we are also interested in the variation range of the sample. For example, to determine if a process is within an adequate stability range.
With the presented algorithms, it is easy to make some modifications to obtain the minimum, maximum, and the midpoint between them. However, performing these calculations involves a small additional effort, so use them only if it is really necessary.
float min, max, mid;
float MeasureN(int samplesNumber, float(*funct)())
{
float value;
for (int i = 0; i < samplesNumber; i++)
{
value = funct();
if (value > max) max = value;
if (value < min) min = value;
}
mid = (max - min) / 2;
return sum / samplesNumber;
}
float MeasureT(int msInterval, float(*funct)())
{
float value;
long startTime = millis();
while (millis() - startTime < msInterval)
{
value = funct();
if (value > max) max = value;
if (value < min) min = value;
}
mid = (max - min) / 2;
return sum / samplesNumber;
}
float getMeasure()
{
return 0.0;
}
void setup()
{
MeasureN(100, getMeasure);
MeasureT(50, getMeasure);
}
void loop()
{
}
In future posts, we will see different advanced and efficient ways to filter sensor measurements, such as the mean, median, and exponential filters.
Download the Code
All the code from this post is available for download on Github.

