HX711 Fluctuating

Hello everyone,

So i'm doing a weighting scale project, and i hooked up a 5kg load cell to hx711, but i'm having a problem.
When there is no load on the scale i get fluctuation of the following results:

0,23
0,41
2,52
4,59
0,00
0,00
2,19

and so on. I've read many topics about this problem, but i cant seem to be able to figure it out and i need my scale to be a bit more accurate. I was looking for designing a low pass filter, but i'm puzzled how to do it exactly. Maybe filtering with capacitors as well, but i have no idea how to connect them as well.

I've twisted my load cell cables, check my pins voltage and which seems normal, i've put the scale on a sturdy platform, also powered up the arduino with 9V adapter and still the fluctuation persists.

So if anyone has any idea why this might be happening i would be very thankful.

So here is my code:

#include "HX711.h"
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <MFRC522.h>
#include <SD.h> // for the SD card
#include <Wire.h>
#include "MegunoLink.h"
#include "Filter.h"

ExponentialFilter<long> ADCFilter(5, 0);

#define SS_PIN 10
#define RST_PIN 9
#define CS_SD 2
float average;
float calibration_factor = -402.46;

const int buttonPin = 6;
const int buttonPin2 = 7; // the number of the pushbutton pin
int buttonState = 0;
int lastButtonState = 0;

// Create a file to store the data
File myFile;


MFRC522 mfrc522(SS_PIN, RST_PIN);

HX711 scale;
float elements; 

LiquidCrystal_I2C lcd(0x27,20,4);
String LCDLine1,LCDLine2;

int n;
float rounded;

void updateLCD () {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(LCDLine1);
  
  
  lcd.setCursor(0,1);
  lcd.print(LCDLine2);

}

void setup() {
  Serial.begin(9600);
  SPI.begin();      // Initiate  SPI bus
  mfrc522.PCD_Init();   // Initiate MFRC522
  pinMode (buttonPin, INPUT);
  lcd.init();
  lcd.backlight();
  
  LCDLine1="Welcome";
  LCDLine2="Scan your ID";
  updateLCD();

  
  if (SD.begin(CS_SD))
  {
    Serial.println("SD card is ready to use.");
  } else
  {
    Serial.println("SD card initialization failed");
    return;
  }

  while(true){
  // Look for new cards02`11
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
      continue;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) 
  { 
  digitalWrite(CS_SD,LOW); // enables the cs pin
 
  // If the file opened ok, write to it
    if (myFile) {
    Serial.println("Read:");
    // Reading the whole file
    while (myFile.available()) {
      Serial.write(myFile.read());
   }
    myFile.close();
  }
  else {
    Serial.println("error opening test.txt");
  } 
 
    digitalWrite(CS_SD,HIGH);
  }
    break;
  }
  
  void(* resetFunc) (void) = 0;
   
  while(true){
  //Show UID on serial monitor
  Serial.print("UID tag :");
  String content= "";
  byte letter;
   for (byte i = 0; i < mfrc522.uid.size; i++) 
  {
     Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
     Serial.print(mfrc522.uid.uidByte[i], HEX);
     content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
     content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  Serial.println();
  Serial.print("Message : ");
  content.toUpperCase();
  if (content.substring(1) == "9E 7E 85 89") //change here the UID of the card/cards that you want to give access
  {
    Serial.println("Authorized access");
    Serial.println();
    delay(3000);
    break;
  }
 
 else   {
    Serial.println(" Access denied");
    delay(3000);
    resetFunc();
  }
  }
  
  Serial.println("HX711 Demo");
  LCDLine1="Initializing ...";
  LCDLine2="";
  updateLCD();

  
  // parameter "gain" is ommited; the default value 128 is used by the library
  // HX711.DOUT  - pin #A1
  // HX711.PD_SCK - pin #A0
  scale.begin(A1,A0);
  scale.set_scale();                      // this value is obtained by calibrating the scale with known weights; see the README for details
  scale.tare();               // reset the scale to 0
            // by the SCALE parameter set with set_scale
  long zero_factor = scale.read_average(); //Get a baseline reading
  Serial.print("Zero factor: "); //This can be used to remove the need to tare the scale. Useful in permanent scale projects.
  Serial.println(zero_factor);
  Serial.println("Readings:");
}




void itemweight()
{
          
        elements = scale.get_units(10);
        Serial.print(" \t| Weight \t");
        Serial.print(elements);
        LCDLine1=String(elements,1) + "g";
        LCDLine2="";
        updateLCD();
    
  
}

void Scale() 
  { 
     
    scale.set_scale(calibration_factor);
    average = scale.get_units(),30;
    ADCFilter.Filter(average);
if (average < 0)
{
average = 0.00;
}
 

  float number =  scale.get_units()/elements;//divide the average of 20 readings with the elements value to get the number of elements
   n = round(number);
   //n = (int)number; // convert float into int
   
  Serial.print("\t| elements:\t");
  Serial.print(n); //serial monitor
  Serial.print("\t| average:\t");
  Serial.println(average);
  // lcd.clear();
       //set cursor first row
  LCDLine1=String(average)+" g"; //print on lcd average value from 10 raw readings 1 time
  LCDLine2=String(n)+" pcs";
  updateLCD();
 // serial monitor -||-
  
 
   //print PCS
  
  scale.power_down();             // put the ADC in sleep mode
  delay(1000);
  scale.power_up();
  updateLCD();
  } 
  
unsigned long getID(){
  if ( ! mfrc522.PICC_ReadCardSerial()) { //Since a PICC placed get Serial and continue
    return -1;
  }
  unsigned long hex_num;
  hex_num =  mfrc522.uid.uidByte[0] << 24;
  hex_num += mfrc522.uid.uidByte[1] << 16;
  hex_num += mfrc522.uid.uidByte[2] <<  8;
  hex_num += mfrc522.uid.uidByte[3];
  mfrc522.PICC_HaltA(); // Stop reading
  return hex_num;
}
void myFiles()
{
  buttonState = digitalRead(buttonPin2);
  if (buttonState == HIGH) {
  myFile = SD.open("opit7.txt", FILE_WRITE);
  myFile.println();
  myFile.println("User ID:");
  myFile.print(getID());
  myFile.println();
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("PCS:");
    myFile.print(n);
    myFile.println();
    myFile.close();
  }
  else {
  }
  }
}



void loop() {
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {
    float average = scale.get_units(10);
    LCDLine1="Place one item"; 
    LCDLine2=String(average,1)+" g";
    updateLCD(); 
    itemweight();
  }
  else {
       Scale();
       myFiles();
       updateLCD();
     //  saveandclose();
   
  }
 
}

What does it look like with a 200g load? Maybe you need to keep a constant preload on the scale and null it out with the tare function.

When i place 500g it fluctuates in the following way:

498,26
500,21
502,35
500,23
499,45
503,15

and so on. The fluctuation is the same no matter what kind of load i put on the load cell.

That's a lot of code; the part that reads the weight is I guess buried in there somewhere.

Start with a minimal sketch that just reads the scale and prints the result to the Serial monitor, no more no less. See if the problem persists. That'd be the code to post. I for one am not interested in digging through long sketches to find just a little bit, especially if not clear whether the problem is even in the software.

Next we need to see a complete schematic of your project, with clearly labelled part numbers. Photos of how it's built can also be helpful.

Hello again,

So since i bought a scale from the market and just took the load cell from it, I remembered that the load cell power supply was coming from a 3V CR2302 battery. So i switched the power supply for the load cell from the 5V pin to the 3.3V pin and now I'm getting more stable results. I have no idea why that happened. Anyway i switched up the codes. I'm posting pictures of my connections and load cell.

Here is the code:

/**
 *
 * HX711 library for Arduino - example file
 * https://github.com/bogde/HX711
 *
 * MIT License
 * (c) 2018 Bogdan Necula
 *
**/
#include "HX711.h"


// HX711 circuit wiring
const int LOADCELL_DOUT_PIN = A1;
const int LOADCELL_SCK_PIN = A0;


HX711 scale;

void setup() {
  Serial.begin(38400);
  Serial.println("HX711 Demo");

  Serial.println("Initializing the scale");

  // Initialize library with data output pin, clock input pin and gain factor.
  // Channel selection is made by passing the appropriate gain:
  // - With a gain factor of 64 or 128, channel A is selected
  // - With a gain factor of 32, channel B is selected
  // By omitting the gain factor parameter, the library
  // default "128" (Channel A) is used here.
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);

  Serial.println("Before setting up the scale:");
  Serial.print("read: \t\t");
  Serial.println(scale.read());			// print a raw reading from the ADC

  Serial.print("read average: \t\t");
  Serial.println(scale.read_average(20));  	// print the average of 20 readings from the ADC

  Serial.print("get value: \t\t");
  Serial.println(scale.get_value(5));		// print the average of 5 readings from the ADC minus the tare weight (not set yet)

  Serial.print("get units: \t\t");
  Serial.println(scale.get_units(5), 1);	// print the average of 5 readings from the ADC minus tare weight (not set) divided
						// by the SCALE parameter (not set yet)

  scale.set_scale(-402.f);                      // this value is obtained by calibrating the scale with known weights; see the README for details
  scale.tare();				        // reset the scale to 0

  Serial.println("After setting up the scale:");

  Serial.print("read: \t\t");
  Serial.println(scale.read());                 // print a raw reading from the ADC

  Serial.print("read average: \t\t");
  Serial.println(scale.read_average(20));       // print the average of 20 readings from the ADC

  Serial.print("get value: \t\t");
  Serial.println(scale.get_value(5));		// print the average of 5 readings from the ADC minus the tare weight, set with tare()

  Serial.print("get units: \t\t");
  Serial.println(scale.get_units(5), 1);        // print the average of 5 readings from the ADC minus tare weight, divided
						// by the SCALE parameter set with set_scale

  Serial.println("Readings:");
}

void loop() {
  Serial.print("one reading:\t");
  Serial.print(scale.get_units(), 1);
  Serial.print("\t| average:\t");
  Serial.println(scale.get_units(15), 1);

  scale.power_down();			        // put the ADC in sleep mode
  delay(5000);
  scale.power_up();
}

hx711_schematic.PNG

results.PNG