1000lb load cell with HX711 won't read/calibrate

Hi all,

I'm using a 5-wire, 1000lb Optima-312 load cell with a SparkFun HX711 and a RexQualis Mega 2560 Arduino but no matter what I do I can't get a reading/calibration after trying many different code libraries. When asked to place a known mass on the load cell and enter its weight, the code confirms the known weight I entered but says the calibration weight is either 0.00 or "nan" regardless of which library I use. Has anyone had a similar issue or know of a fix?

My load cell has a recommended voltage of 10-15v but no minimum voltage listed (I've tried powering it from the HX711, as well as with its power fed by a separate 9v/12v battery so as not to fry the Arduino) and I've tried testing resistances between each wire, which matches what the calibration sheet listed. Also, it lists the minimum weight it'll pick up as 0.1lbs (45g), and I've tried calibrating with weights ranging from 130g to 9072g (20lb weight).

For Serial Monitor setups (no LCD display) I'm using the following setup and code from Indrek Luuk's YouTube channel/website (with the HX711_ADC code from Olav Kallhovd)

(Picture of the wire connections)

Calibration code, part of the HX711_ADC "example" library

/*
   -------------------------------------------------------------------------------------
   HX711_ADC
   Arduino library for HX711 24-Bit Analog-to-Digital Converter for Weight Scales
   Olav Kallhovd sept2017
   -------------------------------------------------------------------------------------
*/

/*
   This example file shows how to calibrate the load cell and optionally store the calibration
   value in EEPROM, and also how to change the value manually.
   The result value can then later be included in your project sketch or fetched from EEPROM.

   To implement calibration in your project sketch the simplified procedure is as follow:
       LoadCell.tare();
       //place known mass
       LoadCell.refreshDataSet();
       float newCalibrationValue = LoadCell.getNewCalibration(known_mass);
*/

#include <HX711_ADC.h>
#if defined(ESP8266)|| defined(ESP32) || defined(AVR)
#include <EEPROM.h>
#endif

//pins:
const int HX711_dout = 4; //mcu > HX711 dout pin
const int HX711_sck = 5; //mcu > HX711 sck pin

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);

const int calVal_eepromAdress = 0;
unsigned long t = 0;

void setup() {
  Serial.begin(57600); delay(10);
  Serial.println();
  Serial.println("Starting...");

  LoadCell.begin();
  //LoadCell.setReverseOutput(); //uncomment to turn a negative output value to positive
  unsigned long stabilizingtime = 2000; // preciscion right after power-up can be improved by adding a few seconds of stabilizing time
  boolean _tare = true; //set this to false if you don't want tare to be performed in the next step
  LoadCell.start(stabilizingtime, _tare);
  if (LoadCell.getTareTimeoutFlag() || LoadCell.getSignalTimeoutFlag()) {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
    while (1);
  }
  else {
    LoadCell.setCalFactor(1.0); // user set calibration value (float), initial value 1.0 may be used for this sketch
    Serial.println("Startup is complete");
  }
  while (!LoadCell.update());
  calibrate(); //start calibration procedure
}

void loop() {
  static boolean newDataReady = 0;
  const int serialPrintInterval = 0; //increase value to slow down serial print activity

  // check for new data/start next conversion:
  if (LoadCell.update()) newDataReady = true;

  // get smoothed value from the dataset:
  if (newDataReady) {
    if (millis() > t + serialPrintInterval) {
      float i = LoadCell.getData();
      Serial.print("Load_cell output val: ");
      Serial.println(i);
      newDataReady = 0;
      t = millis();
    }
  }

  // receive command from serial terminal
  if (Serial.available() > 0) {
    char inByte = Serial.read();
    if (inByte == 't') LoadCell.tareNoDelay(); //tare
    else if (inByte == 'r') calibrate(); //calibrate
    else if (inByte == 'c') changeSavedCalFactor(); //edit calibration value manually
  }

  // check if last tare operation is complete
  if (LoadCell.getTareStatus() == true) {
    Serial.println("Tare complete");
  }

}

void calibrate() {
  Serial.println("***");
  Serial.println("Start calibration:");
  Serial.println("Place the load cell an a level stable surface.");
  Serial.println("Remove any load applied to the load cell.");
  Serial.println("Send 't' from serial monitor to set the tare offset.");

  boolean _resume = false;
  while (_resume == false) {
    LoadCell.update();
    if (Serial.available() > 0) {
      if (Serial.available() > 0) {
        char inByte = Serial.read();
        if (inByte == 't') LoadCell.tareNoDelay();
      }
    }
    if (LoadCell.getTareStatus() == true) {
      Serial.println("Tare complete");
      _resume = true;
    }
  }

  Serial.println("Now, place your known mass on the loadcell.");
  Serial.println("Then send the weight of this mass (i.e. 100.0) from serial monitor.");

  float known_mass = 0;
  _resume = false;
  while (_resume == false) {
    LoadCell.update();
    if (Serial.available() > 0) {
      known_mass = Serial.parseFloat();
      if (known_mass != 0) {
        Serial.print("Known mass is: ");
        Serial.println(known_mass);
        _resume = true;
      }
    }
  }

  LoadCell.refreshDataSet(); //refresh the dataset to be sure that the known mass is measured correct
  float newCalibrationValue = LoadCell.getNewCalibration(known_mass); //get the new calibration value

  Serial.print("New calibration value has been set to: ");
  Serial.print(newCalibrationValue);
  Serial.println(", use this as calibration value (calFactor) in your project sketch.");
  Serial.print("Save this value to EEPROM adress ");
  Serial.print(calVal_eepromAdress);
  Serial.println("? y/n");

  _resume = false;
  while (_resume == false) {
    if (Serial.available() > 0) {
      char inByte = Serial.read();
      if (inByte == 'y') {
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.begin(512);
#endif
        EEPROM.put(calVal_eepromAdress, newCalibrationValue);
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.commit();
#endif
        EEPROM.get(calVal_eepromAdress, newCalibrationValue);
        Serial.print("Value ");
        Serial.print(newCalibrationValue);
        Serial.print(" saved to EEPROM address: ");
        Serial.println(calVal_eepromAdress);
        _resume = true;

      }
      else if (inByte == 'n') {
        Serial.println("Value not saved to EEPROM");
        _resume = true;
      }
    }
  }

  Serial.println("End calibration");
  Serial.println("***");
  Serial.println("To re-calibrate, send 'r' from serial monitor.");
  Serial.println("For manual edit of the calibration value, send 'c' from serial monitor.");
  Serial.println("***");
}

void changeSavedCalFactor() {
  float oldCalibrationValue = LoadCell.getCalFactor();
  boolean _resume = false;
  Serial.println("***");
  Serial.print("Current value is: ");
  Serial.println(oldCalibrationValue);
  Serial.println("Now, send the new value from serial monitor, i.e. 696.0");
  float newCalibrationValue;
  while (_resume == false) {
    if (Serial.available() > 0) {
      newCalibrationValue = Serial.parseFloat();
      if (newCalibrationValue != 0) {
        Serial.print("New calibration value is: ");
        Serial.println(newCalibrationValue);
        LoadCell.setCalFactor(newCalibrationValue);
        _resume = true;
      }
    }
  }
  _resume = false;
  Serial.print("Save this value to EEPROM adress ");
  Serial.print(calVal_eepromAdress);
  Serial.println("? y/n");
  while (_resume == false) {
    if (Serial.available() > 0) {
      char inByte = Serial.read();
      if (inByte == 'y') {
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.begin(512);
#endif
        EEPROM.put(calVal_eepromAdress, newCalibrationValue);
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.commit();
#endif
        EEPROM.get(calVal_eepromAdress, newCalibrationValue);
        Serial.print("Value ");
        Serial.print(newCalibrationValue);
        Serial.print(" saved to EEPROM address: ");
        Serial.println(calVal_eepromAdress);
        _resume = true;
      }
      else if (inByte == 'n') {
        Serial.println("Value not saved to EEPROM");
        _resume = true;
      }
    }
  }
  Serial.println("End change calibration value");
  Serial.println("***");
}

Well, that may have damaged the HX711, since common mode input is supposed to be:

image
image

or between 1.2 v and 3.7 v when AVDD=5v.

With 9v powering the load cell, the common mode input would have been 4.5 v, and with 12 v, the common would have been 6v. Both far outside the stated range.

You should always power the load cell only from E+ and E-.

I would get a new HX711 (Sparkfun's are good), use bare minimum code, and look at the raw outputs under no load and as close to full load as possible, to see if they match or are close to the raw values you get by calculation using the HX711 characteristics and load cell parameters.

When I used external power supplies I connected them only to the positive and negative wires on the load cell (leaving E+ and E- unconnected from the HX711) and only connecting the 9v/12v batteries to the positive and negative lines on the load cell itself. The only time I connected the E+/- lines was when I used the Arduino power supply as shown in the picture. Would that still give issues? Thank you for the advice!

The reason I added "the load cell" in parentheses to the quote was to show what I understood your "it" to refer to, and by implication that I understood you did not power the HX711 or your Arduino with the batteries....only the load cell.

So yes, you apparently exceeded the common mode input upper limit of the HX711, by quite a lot.

Ah ok, thank you. I guess I don't understand the common mode input, I thought if the HX711 had no connection to the higher voltage it'd be ok but as I understand it perhaps it got too much voltage through the A-/A+ wires? Is there a way to prevent this? I've ordered some more (smaller and much less expensive) load cells with HX711's but since it was initially giving me the same issue using the Arduino's laptop connection for power I'm curious if there are any other potential things I screwed up? Thanks again for your replies I really appreciate them

Yes. Google common mode input for a fuller understanding.

Yes. Only power the load cell with E+ and E- from the HX711, as previously mentioned.

Why? You certainly didn't harm the load cell by using 9v to 12v, when the recommended is 10v to 15v.

Ok thanks. Since that didn't work initially (it was well below the voltage I needed, possibly for other reasons, and gave the same issue), is there any way to power the load cell with the higher voltage it needs while not accidentally burning out the HX711 through the connected green and white (A+/-) wires?

I was thinking perhaps I'd get a $10 pack of load cells just to see if the code and rest of the setup was having any issues and since the entire package for two load cells/HX711s cost the same as the one HX711 I initially bought

Possibly using a Buck converter to lower voltage?

A load cell is just a bunch of passive resistors, so it should work from 0volt.
10-15volt (12volt) could be recommended to get maximum resolution without overheating/burning it. But 12volt means old (analogue) technology. You don't want to go there with a microprocessor.

The 4.25volt excitation voltage from the HX711 should work fine.
Maybe you connected things wrong. Did you connect the two power pins of the Sparkfun board to 5volt. Post a real picture of the setup.
Measure E+ A+ A- and GND pins of the load cell while holding the negative lead on the USB shield of the Mega. Post results.
Leo..

So is there no safe way of giving a sensor a separate amount of voltage than that of a microprocessor?

HX711/USB shield voltage readings:
(Arduino powered only)
Red/E+: 4.18v
Green/A+: 2.09 to 2.16v
White/A-: 2.09 to 2.15v
Black/E-: 7.8-36mv

(With 12.73v power to Load Cell)
Red/E+ on connected load cell: 6.51v
Red/E+ disconnected HX711: 4.19v
Black/E- on connected load cell: -5.36v
Black/E- on disconnected HX711: 3.6mv
Green/A+: 0.5v
White/A-: 0.5v

Original Setup with Arduino power only, 9v and 12v off to the side

Close Up of connections
(HX711 Data is blue wire, goes to port 4 of Arduino)
(HX711 Clock is purple wire, becomes white wire going to port 5 of Arduino)

12.7v setup

Serial Monitor, 793.8g calibration (same with either power source)

Serial Monitor, 130g calibration (same with either power source)

Serial Monitor after calibration--with some code it instead says 0.00

You miss the point.
With a different supply, displayed weight will depend on weight and E+ variations and external supply variations. When the load cell is powered from E+ (which is also the supply of the internal A/D of the HX711), then supply variations are compensated. If supply increases 1%, load cell output increases 1%, and A/D sensitivity decreases 1%, thus cancelling each other out. You don't have that compensation with two unrelated supplies.

Forget about 12volt excitation if you're going to use a HX711.
The chip can't cope with it.

The INA125 was AFAIK a chip designed for 10volt load cells. But then you must also use an external 16+ bit A/D. With that setup you could get a lower resolution and more problems than with a default HX711 setup.

Don't know if I see it correctly, but I think you only have powered the analogue part of the HX711, not the digital part.
Leo..

Ah ok, thanks for clarifying the power supply issue!
-Regarding the INA125 is there anything I need to do to modify my setup?
-For the digital part of the HX711 are you talking about the B+/- pins that aren't marked on the front side of the board? I didn't see them connected in any circuit diagrams so don't know what to do with them

VDD = digital

image

Read the Sparkfun hookup guide to learn how to ... hook up ... their HX711:

https://learn.sparkfun.com/tutorials/load-cell-amplifier-hx711-breakout-hookup-guide/all

Try this and report the output with the load cell loaded and unloaded:

#include "HX711.h" // <-- capitalize as shn... the bogde library...

HX711 scale(x, y); // set to your (data,clock) pins

void setup() {
  Serial.begin(115200);  // set your monitor to match
}

void loop() {
  Serial.println(scale.read()); // print a raw read
  delay(5000);
}

This is the "bare minimum code" part of post #2.

From the Sparkfun site:
"Then VCC and VDD just need to be hooked up to 2.7-5V"

Which is of course wrong.

VCC must always be connected to 5volt, otherwise the 4.25volt excitation voltage won't be stable.
VDD is the logic supply, and must be connected to 5volt when a 5volt-logic processor is used, or to 3.3volt when a 3.3volt processor is used.

OP has a Mega (5volt logic), so both VCC and VDD must be connected to 5volt.
Leo..

Thanks everyone! The simplified code wouldn't upload (said something about having an issue with the HX711 scale(4, 5); function even though I have the bogde library installed) but I got a new HX711 which is working now and will be sticking to Arduino power from here on out. Idk why the load cell manufacturer insisted that I use no less than 10v when I specified that I was using the HX711 but I appreciate all of y'all's help troubleshooting.

Did you connect to D4 and D5, or to A4 and A5.
Leo..