bogde / HX711

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

Tare the HX711 with Fish Gripper #228

Open markingle opened 2 years ago

markingle commented 2 years ago

I have built a scale to weigh fish using the HX711. I have the scale calibrated and it is showing the proper weight in testing. However due to drifting I need to tare the scale back to zero before weighing a fish. Is there a recommendation on how to do that? I have tried the calling set_scale and then tare but that throws everything off by several lbs.....thanks in advance for any help!

bogde commented 2 years ago

i think you should use set_scale in setup only and then tare() before measurement, if possible.

markingle commented 2 years ago

Hi @bogde ! I have tried using just tare before measurement but it throws off the value displayed on the screen terribly. I'll post my code and a video later evening.

markingle commented 2 years ago

@bogde Here is a link to a video showing what is happening when I tare...

https://youtu.be/pwbVxPNGlxY

Below is the line of code that is executed when the Tare button is pressed in the iPhone app:

class TareCallback: public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { std::string value = pCharacteristic->getValue(); //scale.set_scale(CALIBRATION_FACTOR); // 852 this value is obtained by calibrating the scale with known weights; see the README for details //scale.set_offset(ZERO_FACTOR); scale.tare(); // reset the scale to }; };

I have tried several functions (set_scale and set_offset now commented out) based on reading a few posts....

This is the section of code that runs once the scale is connected to the app over BLE...I recently added the power up/down to try to stabilize the HX711:

if (deviceConnected) { RGB_color(0, 0, 255); //Turn LED blue. Serial.print("get units: \t\t"); Serial.println(scale.get_units(10), 1); //Serial.print("get value: \t\t"); //Serial.println(scale.get_value(5)); double tempWeight = abs(scale.get_units(10)); scale.power_down(); delay(1000); scale.power_up(); double weight = tempWeight; char txString[5]; dtostrf(weight,1,2,txString); pCharacteristicA->setValue(txString); pCharacteristicA->notify(); display.clear(); display.setTextAlignment(TEXT_ALIGN_CENTER); display.setFont(ArialMT_Plain_10); display.drawString(55, 0, "CONNECTED"); display.setFont(Dialog_plain_50); display.setTextAlignment(TEXT_ALIGN_CENTER); display.drawString(64, 16, txString); // write the buffer to the display display.display(); //delay(100); // bluetooth stack will go into congestion, if too many packets are sent, in 6 hours test i was able to go as low as 3ms }

bogde commented 2 years ago

first of all, nice project, congrats! i recently worked on a BLE firmware plus mobile app myself, i really enjoyed the whole thing.

i would do: scale.set_scale(...); scale.tare(); // optional but why not inside the deviceConnected code, if possible, or somewhere else in the setup part of the code. are you doing that anywhere in the code? (the set_scale part i mean)

one other thing would be to try to tare on a push of a physical button on the device, or via a command on the serial port, and see if that works then go from there.

markingle commented 2 years ago

Yeah I really enjoy working with BLE. But this is my first project managing multiple peripherals. I will refactor the Central Manager code once I get the tare function working.

The deviceConnect code is in the Arduino loop so it runs continuously. Putting a tare there would not work.

I do have these statements in the setup code though...

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

The calibration factor is set in a define statement:

define CALIBRATION_FACTOR 19300.0

Pressing the Tare button in the app writes a "1" to the Tare characteristic....The write itself is what triggers the callback in the Arduino code to run the TareCallback

I added set_scale to the TareCallback. Same results though. Below is the log output....after tare the scale jumped to 1.6 with out any weight on the scale

Cull Master Scale Waiting a client connection to notify... Initializing the scale get units: 0.0 Device is connecting get units: 0.0 get units: 0.0 get units: 1.6 get units: 1.6 get units: 1.6 get units: 1.6 get units: 1.6 get units: 1.6 get units: 1.6 get units: 1.6 get units: 1.6

ba05 commented 2 years ago

Call your tare function in an interrupt that fires when the button is pressed.

markingle commented 2 years ago

Hmmm....when I call the tare function in a ISR it reboots the esp....see logs below

I have ordered a HX711 from Sparkfun as well. I dont like the drifting so I am hoping better hardware will improve things. Also as a backup plan I can restart the esp to accomplish a tare. This will be fine at this point in the project. I have already started V2 of the hardware PCB.

Cull Master Scale Waiting a client connection to notify... Initializing the scale get units: -0.0 Device is connecting get units: -0.0 get units: 0.0 get units: 0.0 get units: Tare Interrupt Called ets Jun 8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:1 load:0x3fff0018,len:4 load:0x3fff001c,len:1216 ho 0 tail 12 room 4 load:0x40078000,len:10944 load:0x40080400,len:6388 entry 0x400806b4 E (137) psram: PSRAM ID read error: 0xffffffff Cull Master Scale Waiting a client connection to notify... Initializing the scale get units: 0.0 Device is connecting get units: 0.0 get units: 0.0 get units: 0.0 get units: 0.0 get units: 0.0 get units: 0.0 get units: 0.0 get units: 0.0 get units: 0.0

bogde commented 2 years ago

for some reason i thought the if (deviceConnected) {...} block executes when a device first connects, i now understand it executes while a device stays connected.

anyway, one other thing i would try in order to debug would be to somehow output the result of scale.get_scale(); just before calling tare(). you could publish that on the characteristic or output it to the serial log and see if it still holds the value you set during setup. i cant think if reason why it wouldn't, but i guess making sure doesn't hurt.

markingle commented 2 years ago

Looks like the scale I set in setup is still holding...

Waiting a client connection to notify... Initializing the scale Device is connecting get units: 0.0 get units: Tare Interrupt Called Timer Started 0.0 Get Scale is: 19300.00 Scale has been tared get units: Get Scale is: 19300.00 Scale has been tared 0.0 Timer Stopped get units: 0.0

markingle commented 2 years ago

This is interesting....the tare offset is WAY off after a tare. I am gonna try to capture the offset in a variable then reset it after a tare...fingers crossed!

Initializing the scale get units: 0.0 Device is connecting get units: 0.0 get units: 0.0 Tare Interrupt Called B4 Get Scale is: 19300.00 B4 Tare Offset is: -233817 Scale has been tared After Get Scale is: 19300.00 After Tare Offset is: 2449015 get units: -139.0 get units: -139.0

markingle commented 2 years ago

Well that helped...I am not getting crazy weights anymore. Here is my code within the characteristic call incase someone else needs it.

Now I just need to figure out how to get the reading to 0.00 after a fish gripper is attached to the scale hook

class TareCallback: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();
      Serial.println("Tare Interrupt Called");
      //ESP.restart();
      //startTimer();
      //scale.set_scale(CALIBRATION_FACTOR);
      //scale.tare();
      Serial.print("B4 Get Scale is: ");
      Serial.println(scale.get_scale());
      Serial.print("B4 Tare Offset is: ");
      Serial.println(scale.get_offset());
      double offset_temp = scale.get_offset();
      //scale.set_scale(CALIBRATION_FACTOR);
      scale.tare();
      scale.set_offset(offset_temp);
      Serial.println("Scale has been tared");
      Serial.print("After Get Scale is: ");
      Serial.println(scale.get_scale());
      Serial.print("After Tare Offset is: ");
      Serial.println(scale.get_offset());
    };
};
bogde commented 2 years ago

quick question: you were calling tare() after set_scale(...) in your setup, right?

markingle commented 2 years ago

I am.

banoz commented 2 years ago

There is an issue with a tare method. It has to have set_offset(0) inside, before the tare process. 226