# Smoothing hx711 readings with atmega328

I am making a 50kg weighing scale using HX711 ADC. My project includes Atmega328 along with 74HC595 for driving 5 7segment displays(multiplexed). I am using the function `scale.get_units()`to fetch the data and the values are very well displayed on the 7segments. The problem I am facing is the readings on the 5th digit (right most 1's) are unstable. Now, if I use `scale.read_average(5)`, my display scanning gets slow. I was wondering if there is a way to average the readings in a loop like the conventional way. I tried it but with no luck! It keeps showing random added numbers. Any help would be highly appriciated. Below is the code inside the loop. Let me know if full code is needed. Thanx in advance!

``````if (scale.is_ready()) {
weight = scale.get_units();
finalWeight = weight * 1000;
}
for (int i = 0; i < 10 ;i++) {
sum += finalWeight;
}
average = sum / 10;
if (average < 0) {
break_number(0);
} else {
break_number(average);
}
display_number();
delay(1);
``````

First of all, this code:

``````for (int i = 0; i < 10 ;i++) {
sum += finalWeight;
}
average = sum / 10;
``````

does not average multiple readings. Instead, it takes the single reading stored in `finalWeight`, multiplies it by ten (by means of successive additions), then divides it by ten to get back the same value.

If you want to reduce the noise, you have to take multiple readings and average them. The reading-taking code must thus be inside the loop. A simple option may be like this:

``````void loop() {
sum = 0;
for (int i = 0; i < 10; i++) {
sum += scale.get_units();
}
weight = sum / 10;  // compute the average
display(weight);    // and display it
}
``````

Note that I have simplified things a bit by removing the scaling factors. You can take this as simple inspiration and adapt to your specific needs.

The code above has one problem though: as the code is blocking while waiting for the scale to be ready, the display is not refreshed. You could fix this by explicitly refreshing the display within the waiting loop:

``````void loop() {
sum = 0;
for (int i = 0; i < 10; i++) {
display(weight);         // ...while refreshing the display
}
sum += scale.get_units();
}
weight = sum / 10;
display(weight);
}
``````

This should work, but I would however suggest instead a third approach: write non-blocking code. This is code that never blocks: instead, if something can be done right now, it does it. If not, it moves along:

``````void loop() {
if (scale.is_ready()) {  // if something useful can be done NOW:
sum += scale.get_units();
count++;
if (count >= 10) {
weight = sum / count;  // update the value to be displayed
sum = 0;               // reset the averaging variables
count = 0;
}
}

display(weight);  // unconditionally refresh the display
}
``````

This way, your `loop()` always runs fast, and you can add code that will not be blocked by the stuff you wrote earlier.

Edit: As suggested by chrisl in a comment, a moving average may better serve your needs. I would try the exponentially-weighted version, as it is lightweight and simpler to implement. You may want to explore this path.

• In addition: Here a moving average might be a good choice, like in the second answer to this question Jun 21 at 9:26
• Thanx a lot!! I will try it. Jun 22 at 3:31