HX711-multi Library - Multiple class declaration

Hello. My project uses an ESP-32 Thing Microprocessor connected to 10 load sensors (TAL220 connected via HX711 load cell amplifier). The project has two circuit boards (one mounted above the other) with jacks to connect five load cells on each board. Each bank of five loadcells shares a common clock.

The library I have used is the HX711-multi (source: [GitHub - compugician/HX711-multi: An Arduino library to interface multiple HX711 units simultaneously]) which enables multiple load cells to share a common clock line.

I have used this library extensively with two instances of the 'HX711MULTI' class declared and no problems.

I needed to update the code (nothing related to the load sensors) and now the code only works when one instance of the HX711MULTI class is declared and I don't know why.

I have adapted the example script from the HX711-multi library to try and work out the problem and have not been able to solve it. The test code is below.

#include "HX711-multi.h"

// Pins to the load cell amp
#define CLK_BOTTOM 32      // clock pin for bottom bank of load cells
#define DOUT_A 35    // data pin to the first lca
#define DOUT_B 34    // data pin to the second lca
#define DOUT_C 39    // data pin to the third lca
#define DOUT_D 38    // data pin to the second lca
#define DOUT_E 37    // data pin to the third lca

#define CLK_TOP 15   // clock pin for top bank of load cells 
#define DOUT_F 36    // Loadcell F data pin
#define DOUT_G 0    // Loadcell G data pin
#define DOUT_H 4    // Loadcell H data pin
#define DOUT_I 17    // Loadcell G data pin
#define DOUT_J 16  // Loadcell H data pin

#define BOOT_MESSAGE "MIT_ML_SCALE V0.8"

#define TARE_TIMEOUT_SECONDS 4

byte DOUTS_BOTTOM[5] = {DOUT_A, DOUT_B, DOUT_C, DOUT_D, DOUT_E}; 
byte DOUTS_TOP[5] = {DOUT_F, DOUT_G, DOUT_H, DOUT_I, DOUT_J};

#define CHANNEL_COUNT_BOTTOM sizeof(DOUTS_BOTTOM)/sizeof(byte)
#define CHANNEL_COUNT_TOP sizeof(DOUTS_TOP)/sizeof(byte)

long int results[CHANNEL_COUNT_BOTTOM];

HX711MULTI scales_bottom(CHANNEL_COUNT_BOTTOM, DOUTS_BOTTOM, CLK_BOTTOM);
//HX711MULTI scales_top(CHANNEL_COUNT_TOP, DOUTS_TOP, CLK_TOP);

void setup() {
  Serial.begin(9600);
  Serial.println(BOOT_MESSAGE);
  Serial.flush();
  //pinMode(11,OUTPUT);
    
  tare();
}


void tare() {
  bool tareSuccessful = false;

  unsigned long tareStartTime = millis();
  while (!tareSuccessful && millis()<(tareStartTime+TARE_TIMEOUT_SECONDS*1000)) {
    tareSuccessful = scales_bottom.tare(20,10000);  //reject 'tare' if still ringing
  }
}

void sendRawData() {
  scales_bottom.read(results);
  for (int i=0; i<scales_bottom.get_count(); ++i) {;
    Serial.print( -results[i]);  
    Serial.print( (i!=scales_bottom.get_count()-1)?"\t":"\n");
  }  
  delay(10);
}

void loop() {
  
  sendRawData(); //this is for sending raw data, for where everything else is done in processing

  //on serial data (any data) re-tare
  if (Serial.available()>0) {
    while (Serial.available()) {
      Serial.read();
    }
    tare();
  }
  
 delay(5000);
}

The code compiles no problems with either one or both HX711MULTI classes declared.

When one of the HX711MULTI classes is commented out, the code works as expected on the Serial Monitor (i.e. prints values for five load cells every 5s).

When both HX711MULTI classes are defined, the Serial Monitor displays the following:

BlockquoteӔn⸮fg⸮⸮R⸮⸮fg⸮Ӓ~⸮fg⸮R~⸮f⸮⸮⸮R~⸮f⸮

The ESP32 appears to shutdown and restart every few seconds with a new string as shown above displayed on the Serial Monitor.

I am a bit stumped, as this code worked fine previously with two declarations of the HX711-MULTI class. I don't know what has changed.

it is not to exclude that lib is updated, but may be your sketch hold execution for long time and ESP force reset.

probably this you can read as ascii text at baud rate 74400

#include "HX711-multi.h"

// Pins to the load cell amp
#define CLK 32                           // clock pin for entire bank of load cells 
#define DOUT_A 35    // data pin to the first lca
#define DOUT_B 34    // data pin to the second lca
#define DOUT_C 39    // data pin to the third lca
#define DOUT_D 38    // data pin to the second lca
#define DOUT_E 37    // data pin to the third lca
#define DOUT_F 36    // Loadcell F data pin
#define DOUT_G 0    // Loadcell G data pin
#define DOUT_H 4    // Loadcell H data pin
#define DOUT_I 17    // Loadcell G data pin
#define DOUT_J 16  // Loadcell H data pin

#define TARE_TIMEOUT_SECONDS 4
#define CHANNEL_COUNT  10
byte DOUTS[] = {DOUT_A, DOUT_B, DOUT_C, DOUT_D, DOUT_E, DOUT_F, DOUT_G, DOUT_H, DOUT_I, DOUT_J};
long int results[CHANNEL_COUNT];

HX711MULTI scales(CHANNEL_COUNT, DOUTS, CLK);

void setup() {
  Serial.begin(115200);
   tare();
}

void tare() {
  bool tareSuccessful = false;
  unsigned long tareStartTime = millis();
  while (!tareSuccessful && (millis() - tareStartTime  >= TARE_TIMEOUT_SECONDS * 1000)) {
    tareSuccessful = scales.tare(20, 10000); //reject 'tare' if still ringing
  }
}

void sendRawData() {
  scales.read(results);
  for (int i = 0; i < CHANNEL_COUNT; ++i) {
    Serial.print( -results[i]);
    Serial.print( (i != CHANNEL_COUNT - 1) ? "\t" : "\n");
  }
  Serial.flush();
}

void loop() {
  static uint32_t oldMillis = millis();
  if (millis() - oldMillis >= 5000) {
    oldMillis += 5000;
    sendRawData(); //this is for sending raw data, for where everything else is done in processing
  }

  //on serial data (any data) re-tare
  if (Serial.available() > 0) {
    while (Serial.available() > 0)Serial.read();
    tare();
  }
}
1 Like

Thank you.

Changed the baud rate and could read the error messages. You are correct, with verbose debugging on it suggests that ESP is being force reset.

I ran the code as you suggested but came up with the error below.

Arduino: 1.8.19 (Windows 10), Board: "SparkFun ESP32 Thing, 80MHz, Default, 921600, Verbose"

240804-HX711_multi-test-alternate:24:44: error: invalid conversion from 'const byte* {aka const unsigned char*}' to 'byte* {aka unsigned char*}' [-fpermissive]

HX711MULTI scales(CHANNEL_COUNT, DOUTS, CLK);

corrected
UPD: again corrected.
but for ESP32 error became critical and stop compile,

....\HX711-multi-master/HX711-multi.h:49:22: error: extra qualification 'HX711MULTI::' on member 'readRaw' [-fpermissive]
   49 |                 void HX711MULTI::readRaw(long *result = NULL);

Interesting. I did some further fault finding by isolation and have been able to declare two instances of a HX711MULTI class (sort of).

I started off by declaring a second class (scales2) using the same input parameters as the first declaration (scales1). This worked no problems.

Then, through a process of elimination changed all of the input parameters to scales2.

What I found was that DOUT_G (Pin 0 on the ESP32 Thing) is causing the problem.

When I use DOUTS_TOP without DOUT_G the two HX711MULTI classes are created without any problems.

From the ESP32 Thing Hookup guide, Pin 0 can be used for multiple purposes in addition to a GPIO pin. I assume that this is what is causing the problem.

https://learn.sparkfun.com/tutorials/esp32-thing-hookup-guide/all

Not sure of the work around for this yet, but it would appear that the problem isn't related to the HX711MULTI library.

#include "HX711-multi.h"

// Pins to the load cell amp
#define CLK_BOTTOM 32      // clock pin for bottom bank of load cells
#define DOUT_A 35    // Loadcell A data pin
#define DOUT_B 34    // Loadcell B data pin
#define DOUT_C 39    // Loadcell C data pin
#define DOUT_D 38    // Loadcell D data pin
#define DOUT_E 37    // Loadcell E data pin

#define CLK_TOP 15   // clock pin for top bank of load cells 
#define DOUT_F 36    // Loadcell F data pin
#define DOUT_G 0    // Loadcell G data pin
#define DOUT_H 4    // Loadcell H data pin
#define DOUT_I 17    // Loadcell G data pin
#define DOUT_J 16  // Loadcell H data pin

#define BOOT_MESSAGE "MIT_ML_SCALE V0.8"

#define TARE_TIMEOUT_SECONDS 4

byte DOUTS_BOTTOM[5] = {DOUT_A, DOUT_B, DOUT_C, DOUT_D, DOUT_E}; 
//byte DOUTS_TOP[5] = {DOUT_F, DOUT_G, DOUT_H, DOUT_I, DOUT_J};
byte DOUTS_TOP[4] = {DOUT_F, DOUT_H, DOUT_I, DOUT_J};

#define CHANNEL_COUNT_BOTTOM sizeof(DOUTS_BOTTOM)/sizeof(byte)
#define CHANNEL_COUNT_TOP sizeof(DOUTS_TOP)/sizeof(byte)

long int results[CHANNEL_COUNT_BOTTOM];

HX711MULTI scales1(CHANNEL_COUNT_BOTTOM, DOUTS_BOTTOM, CLK_BOTTOM);
HX711MULTI scales2(CHANNEL_COUNT_TOP, DOUTS_TOP, CLK_TOP);

  /*
   * Isolate where issue is caused.
   * If scales2 uses same parameters as scales1 - script works
   * If scales2 uses CHANNEL_COUNT_TOP and CLK_TOP it works (with DOUTS_BOTTOM.
   * Tried removing DOUT_F from DOUTS_BOTTOM for scales2. Makes no difference. Still doesn't work.
   * Removed all but DOUT_J from DOUTS_TOP and it works.
   * Added DOUT_H and DOUT_I and it works.
   * Add DOUT_G and it stops working (pin 0)
   * Removed DOUT_G and added DOUT_F and it works.
   * SUGGESTS AN ISSUE WITH USING PIN 0. PIN 0 is a BUTTON  
   */

void setup() {
  Serial.begin(115200);
  Serial.println(BOOT_MESSAGE);

  Serial.println(CLK_BOTTOM);
  Serial.println(DOUTS_BOTTOM[0]);
  Serial.println(CHANNEL_COUNT_BOTTOM);

  //HX711MULTI scales1(CHANNEL_COUNT_BOTTOM, DOUTS_BOTTOM, CLK_BOTTOM);
 
  Serial.println(CLK_TOP);
  Serial.println(DOUTS_TOP[0]);
  Serial.println(CHANNEL_COUNT_TOP);

  Serial.flush();
    
  //tare();
}
/*
void tare() {
  bool tareSuccessful = false;

  unsigned long tareStartTime = millis();
  while (!tareSuccessful && millis()<(tareStartTime+TARE_TIMEOUT_SECONDS*1000)) {
    tareSuccessful = scales_bottom.tare(20,10000);  //reject 'tare' if still ringing
  }
}*/

/*
void sendRawData() {
  scales_bottom.read(results);
  for (int i=0; i<scales_bottom.get_count(); ++i) {;
    Serial.print( -results[i]);  
    Serial.print( (i!=scales_bottom.get_count()-1)?"\t":"\n");
  }  
  delay(10);
}
*/
void loop() {

  Serial.println("LOOP");
  delay(2000);
/*  sendRawData(); //this is for sending raw data, for where everything else is done in processing

  //on serial data (any data) re-tare
  if (Serial.available()>0) {
    while (Serial.available()) {
      Serial.read();
    }
    tare();
  }
  
 delay(5000);
 */
} // end loop

the lib must be corrected, open HX711-multi.h, scroll to line 49

void HX711MULTI::readRaw(long *result = NULL);

and delete HX711MULTI:: , save and close.
now open HX711-multi.cpp, scroll to line 146 digitalWrite(PD_SCK, LOW); cut it out,
and insert after line 140

		digitalWrite(PD_SCK, HIGH);
		digitalWrite(PD_SCK, LOW);
		if (NULL!=result) {

save and close, now your sketch compiles and 10 sensors reads on same CLK without issues

1 Like

Thank you!!!