bogde / HX711

An Arduino library to interface the Avia Semiconductor HX711 24-Bit Analog-to-Digital Converter (ADC) for Weight Scales.
MIT License
896 stars 538 forks source link

HX711 only reads once on startup #251

Open Xarbenence opened 1 year ago

Xarbenence commented 1 year ago

Hello,

I wanted to post a question regarding a project I am working on. I have an HX711 interfacing with 4 half bridge strain gauges: found here. When I use the library and initialize the board, I have a loop in my setup() that just checks to see if the board is ready to be read from. I never get stuck in that loop, and I can successfully read from the board immediately after doing scale.begin(DOUT,SCL); However, when I enter my actual loop(), scale.is_ready() always returns false. I even tested the first reading I get with different weights, and the value changes, telling me that the load cells/HX711 are working, but I'm at a loss for why I need can only read once. In my loop(), if I re-call scale.begin(), I can get more reads, but I don't want to have to reset the HX711 every time I want to read from it. Has anyone else experienced this issue? Thanks.

Code:

/**** Adafruit IO Configuration ***/

// visit io.adafruit.com if you need to create an account, // or if you need your Adafruit IO key. // #define IO_USERNAME "xxxxx" // #define IO_KEY "yyyyy"

/*** WIFI Configuration **/

// #define WIFI_SSID "zzzzz" // #define WIFI_PASS "wwwww"

// #include // AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS);

/**** Main Program Starts Here ***/

/**** Libraries **/ //#include // ESP8266 library //#include // Adafruit IO library //#include // Adafruit MQTT library //#include // http Client

include // HX711 library for the scale

include "DFRobot_HT1632C.h" // Library for DFRobot LED matrix display

define calibration_factor -21700.0 //-7050.0 //This value is obtained using the SparkFun_HX711_Calibration sketch

define DOUT 4 // Pin connected to HX711 data output pin

define CLK 5 // Pin connected to HX711 clk pin

define NUM_MEASUREMENTS 20 // Number of measurements

define THRESHOLD 2 // Measures only if the weight is greater than 2 kg. Convert this value to pounds if you're not using SI units.

define THRESHOLD1 0.5 // Restart averaging if the weight changes more than 0.5 kg.

define DATA D6 // Pin for DFRobot LED matrix display

define CS D2 // Pin for DFRobot LED matrix display

define WR D7 // Pin for DFRobot LED matrix display

DFRobot_HT1632C ht1632c = DFRobot_HT1632C(DATA, WR,CS); // set up LED matrix display

//AdafruitIO_Feed *myWeight = io.feed("my-weight"); // set up the 'iot scale' feed

HX711 scale; // instantiate the scale

float weight = 0.0; float prev_weight = 0.0;

void setup() {

// start the serial connection Serial.begin(115200);

// setup LED matrix display ht1632c.begin(); ht1632c.isLedOn(true); ht1632c.clearScreen(); delay(500);

scale.begin(DOUT,CLK); // initialize scale while(!scale.is_ready()){ // wait until the scale is ready to start reading Serial.println("Initializing Scale"); delay(1000); // scale.is_ready() never fails } long reading = scale.read(); Serial.println("HX711 reading: "); Serial.println(reading);

scale.tare(); //Assuming there is no weight on the scale at start up, reset the scale to 0 Serial.println("Board Tared"); //scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch

// connect to io.adafruit.com //Serial.print("Connecting to Adafruit IO"); //io.connect();

// set up a message handler for the 'my weight' feed. // the handleMessage function (defined below) // will be called whenever a message is // received from adafruit io. //myWeight->onMessage(handleMessage);

//ESP.wdtDisable();

//ht1632c.print("connecting...",50); // wait for a connection // while(io.status() < AIO_CONNECTED) { // Serial.print("."); // ht1632c.print("...",50); // ESP.wdtFeed(); // delay(500); // }

// we are connected // Serial.println(io.statusText()); // ESP.wdtFeed(); //ht1632c.print("connected...",50);

}

void loop() {

// io.run(); is required for all sketches. // it should always be present at the top of your loop // function. it keeps the client connected to // io.adafruit.com, and processes any incoming data. //io.run();

ht1632c.clearScreen(); //ESP.wdtFeed();

weight = scale.get_units(); Serial.println(weight);

float avgweight = 0;

int i = 0; while(i<9){ if(scale.is_ready()){ // this is_ready() always fails long reading = scale.read(); Serial.print("HX711 reading: "); Serial.println(reading); break; } i++; }

if(i==9){ Serial.println("Resetting"); scale.begin(DOUT,CLK); long reading = scale.read(); Serial.println("HX711 reading: "); Serial.println(reading); // these readings always work Serial.println("Board reset"); }

// if (weight > THRESHOLD) { // Takes measures if the weight is greater than the threshold // float weight0 = scale.get_units(); // for (int i = 0; i < NUM_MEASUREMENTS; i++) { // Takes several measurements // delay(100); // weight = scale.get_units(); // avgweight = avgweight + weight; // if (abs(weight - weight0) > THRESHOLD1) { // avgweight = 0; // i = 0; // } // weight0 = weight; // } // avgweight = avgweight / NUM_MEASUREMENTS; // Calculate average weight

//   Serial.print("Measured weight: "); // this is using UART
//   Serial.print(avgweight, 1); 
//   Serial.println(" kg");

// char result[8]; // Buffer big enough for 7-character float // dtostrf(avgweight, 6, 1, result); // ht1632c.print(result); // Display on LED matrix

  //save myWeight to Adafruit.io
  //myWeight->save(avgweight);

  // wait while there's someone on the scake
  // while (scale.get_units() > THRESHOLD) {
  //   ESP.wdtFeed();
// }

  //keep LEDs on for two seconds then restart
  delay(2000);

//} }

// void handleMessage(AdafruitIO_Data *data) { // }

banoz commented 1 year ago

Did you try to call scale.power_up() after scale.begin()?

fenixil commented 7 months ago

@Xarbenence I hit the same issue today, so let me explain what's likely causing yours. First, here is the link to the datasheet - https://www.digikey.com/htmldatasheets/production/1836471/0/0/1/hx711.html As you can see, module can provide 10 or 80 samples per second. It needs some time to provide the value after it's started, that's why your first loop always succeeds as you wait for 1 second between iterations. Your second loop does not have any delays, so it will exit almost immediately. You must add a delay there too.

weight = scale.get_units(); 
// ^^^^ you read the data here, so is_ready() becomes false
...
while(i<9){
if(scale.is_ready()){ // this is_ready() always fails
  long reading = scale.read();
  Serial.print("HX711 reading: ");
  Serial.println(reading);
  break;
} else {
  delay(100);
  // ^^^^ here
}

As I can see from the sources, begin() does not perform communication with the module, so it's not something that helps you here, but rather the delay at the end of the script, or something else.

I had and identical issue cause by power_up and power_down - I called power_up and expected data was available immediately. That was obviously wrong, so after I added some delay (just hardcoded 500ms to comply with Output settling time, however there are better APIs of achieving that, have a look at wait_ready_timeout and wait_ready_retry) everything got back to normal.

PS. I'd greatly appreciate if you edit your post, use github's markdown to make it look like a code and clean it up from commented code.