Can I used two Hx711 modules with ESP32? ..#2

Thread Starter

Edi023

Joined Jun 13, 2022
10
i also try to connect two hx711 boards to an esp32 devkit v1.
I connected 1 to pin 18&5, that one is working.
but I have no idea where I can connect the second one to.
 

Thread Starter

Edi023

Joined Jun 13, 2022
10
Hi Edi,
Welcome to AAC.
Please post a circuit diagram and your Sketch.
E
Hi Eric,

thank you for the warm welcome.

I use the calibration sketch in the following link:
https://github.com/EverythingSmartHome/mqtt-bed-sensor/tree/master/Scale_Calibration

i connect the dt->pin5
sck->pin18
the board gets its 5v from the esp32
this one is working.

With the second one I tried different pins and its not working: dt->19. dt->15
sck->23. sck->14
i 'am calibration them separately (one board at the time)
 

ErnieM

Joined Apr 24, 2011
8,377
Looking at the HX711_basic_example.ino it seems that the HX711 library creates an object to simplify communications.

I would suggest trying to create two such objects with suitable pins pairs for each load cell sensor. Any unused GPIO pins should be suitable.

Code:
#include "HX711.h"

const int LOADCELL_1_DOUT_PIN = 2;
const int LOADCELL-1_SCK_PIN = 3;

const int LOADCELL_2_DOUT_PIN = 4;
const int LOADCELL_2_SCK_PIN = 5;

void setup() {
  scale_1.begin(LOADCELL_1_DOUT_PIN, LOADCELL_2_SCK_PIN);
  scale_2.begin(LOADCELL_2_DOUT_PIN, LOADCELL_2_SCK_PIN);

  Serial.begin(57600);
}

void loop() {
    long reading = scale_1.read();
    Serial.print("HX711_1 reading: ");
    Serial.println(reading);

    reading = scale_2.read();
    Serial.print("HX711_2 reading: ");
    Serial.println(reading);
}
 
Last edited:

Thread Starter

Edi023

Joined Jun 13, 2022
10
Looking at the HX711_basic_example.ino it seems that the HX711 library creates an object to simplify communications.

I would suggest trying to create two such objects with suitable pins pairs for each load cell sensor. Any unused GPIO pins should be suitable.

Code:
#include "HX711.h"

const int LOADCELL_1_DOUT_PIN = 2;
const int LOADCELL-1_SCK_PIN = 3;

const int LOADCELL_2_DOUT_PIN = 4;
const int LOADCELL_2_SCK_PIN = 5;

void setup() {
  scale_1.begin(LOADCELL_1_DOUT_PIN, LOADCELL_2_SCK_PIN);
  scale_2.begin(LOADCELL_2_DOUT_PIN, LOADCELL_2_SCK_PIN);

  Serial.begin(57600);
}

void loop() {
    long reading = scale_1.read();
    Serial.print("HX711_1 reading: ");
    Serial.println(reading);

    reading = scale_2.read();
    Serial.print("HX711_2 reading: ");
    Serial.println(reading);
}

thank you for the reply, I will try to adopt this code once I can get a reading from the second loadcell.

Within the calibration sketch I put :
const int LOADCELL_DOUT_PIN = 19;
const int LOADCELL_SCK_PIN = 23;

but I get a zero value despite I put weight on it or not.
i wired the second loadcell the same as the first one, the first one I put on:
const int LOADCELL_DOUT_PIN = 5;
const int LOADCELL_SCK_PIN = 18;
 

ericgibbs

Joined Jan 29, 2010
18,872
Hi Edi,
post your Sketch when ready, I have a two HX711project set up on the bench, I can check your code.
Which type load cells are you using.?
E
 

Thread Starter

Edi023

Joined Jun 13, 2022
10
Hi Eric,

I use the the filling calibration sketch:

Code:
#include <HX711.h>

HX711 scale;  // Initializes library functions.

const int LOADCELL_DOUT_PIN = 19;          //Remember these are ESP GPIO pins, these might not be the pins labeled on the board.
const int LOADCELL_SCK_PIN = 23;

int calibration_factor = 2400; // Defines calibration factor we'll use for calibrating.

void setup()
{
  Serial.begin(74880);   // Starts serial communication in 9600 baud rate.

  Serial.println("Initializing scale calibration.");  // Prints user commands.
  Serial.println("Please remove all weight from scale.");
  Serial.println("Place known weights on scale one by one.");


  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);   // Initializes the scaling process.
  scale.set_scale();
  scale.tare();          // Resets the scale to 0.
}


void loop()
{

  scale.set_scale(calibration_factor);  // Adjusts the calibration factor.
  scale.wait_ready();
  Serial.print("Reading: ");            // Prints weight readings in .2 decimal kg units.
  Serial.print(scale.get_units(), 2);
  Serial.println(" kg");
  Serial.print("Calibration factor: "); // Prints calibration factor.
  Serial.println(calibration_factor);

  scale.power_down();    // Puts the scale to sleep mode for 3 seconds.
  delay(3000);
  scale.power_up();
}
the following code I wanne use for the final readout with two sensors:


Code:
#include <Arduino.h>
#include <HX711.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include "config.h"

HX711 scale;                          // Initiate HX711 library
WiFiClient wifiClient;                // Initiate WiFi library
PubSubClient client(wifiClient);      // Initiate PubSubClient library

void setup() {
  Serial.begin(74880);
  Serial.println();
  WiFi.mode(WIFI_STA);
  WiFi.begin(SSID, PASSWORD);
  Serial.print("Connecting...");

  while (WiFi.status() != WL_CONNECTED) {       // Wait till Wifi connected
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());                     // Print IP address

  client.setServer(MQTT_SERVER, 1883);                // Set MQTT server and port number
  client.setCallback(callback);                       // Set callback address, this is used for remote tare
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);   // Start scale on specified pins
  scale.wait_ready();                                 //Ensure scale is ready, this is a blocking function
  scale.set_scale();                                 
  Serial.println("Scale Set");
  scale.wait_ready();
  scale.tare();                                       // Tare scale on startup
  scale.wait_ready();
  Serial.println("Scale Zeroed");
}

void loop() {
  float reading; // Float for reading
  float raw; // Float for raw value which can be useful
  scale.wait_ready(); // Wait till scale is ready, this is blocking if your hardware is not connected properly.
  scale.set_scale(calibration_factor);  // Sets the calibration factor.

  // Ensure we are still connected to MQTT Topics
  if (!client.connected()) {
    reconnect();
  }
 
  Serial.print("Reading: ");            // Prints weight readings in .2 decimal kg units.
  scale.wait_ready();
  reading = scale.get_units(10);        //Read scale in g/Kg
  raw = scale.read_average(5);          //Read raw value from scale too
  Serial.print(reading, 2);
  Serial.println(" kg");
  Serial.print("Raw: ");
  Serial.println(raw);
  Serial.print("Calibration factor: "); // Prints calibration factor.
  Serial.println(calibration_factor);

  if (reading < 0) {
    reading = 0.00;     //Sets reading to 0 if it is a negative value, sometimes loadcells will drift into slightly negative values
  }

  String value_str = String(reading);
  String value_raw_str = String(raw);
  client.publish(STATE_TOPIC, (char *)value_str.c_str());               // Publish weight to the STATE topic
  client.publish(STATE_RAW_TOPIC, (char *)value_raw_str.c_str());       // Publish raw value to the RAW topic

  client.loop();          // MQTT task loop
  scale.power_down();    // Puts the scale to sleep mode for 3 seconds. I had issues getting readings if I did not do this
  delay(3000);
  scale.power_up();
}

void reconnect() {
  while (!client.connected()) {       // Loop until connected to MQTT server
    Serial.print("Attempting MQTT connection...");
    if (client.connect(HOSTNAME, mqtt_username, mqtt_password, AVAILABILITY_TOPIC, 2, true, "offline")) {       //Connect to MQTT server
      Serial.println("connected");
      client.publish(AVAILABILITY_TOPIC, "online", true);         // Once connected, publish online to the availability topic
      client.subscribe(TARE_TOPIC);       //Subscribe to tare topic for remote tare
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);  // Will attempt connection again in 5 seconds
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
  if (strcmp(topic, TARE_TOPIC) == 0) {
    Serial.println("starting tare...");
    scale.wait_ready();
    scale.set_scale();
    scale.tare();       //Reset scale to zero
    Serial.println("Scale reset to zero");
  }
}
I checkend everything again, the wiring,code and voltages at the hx711 board.
I found that between the vcc and grnd is around 5v, but at the sensor side between the E+ and the E- I don't measure anything.
So I think I broke my hx711 board, I ordered a new one to change it out and try again.
The load cells iam using are P.S.D model:psd-s1 200kg.
 

ericgibbs

Joined Jan 29, 2010
18,872
hi Edi,
Where did you get the first Sketch from.?
When running, the Vext to the Load Cell is being pulled from ~+4v to almost 0v, during a Read cycle.

Do you have a photo of your ESP32 so that I can check the pin coding agrees.

E
 

Thread Starter

Edi023

Joined Jun 13, 2022
10
hi Edi,
Where did you get the first Sketch from.?
When running, the Vext to the Load Cell is being pulled from ~+4v to almost 0v, during a Read cycle.

Do you have a photo of your ESP32 so that I can check the pin coding agrees.

E
I found the sketches at the following link:
https://github.com/EverythingSmartHome/mqtt-bed-sensor

Could the voltage drop be because of the de 3 sec delay that the loadcell turns off?

I use the esp32-wroom-da module library.
I use the following esp32 board:
image_67175425.JPG
 

ericgibbs

Joined Jan 29, 2010
18,872
hi Edi,
Which version of the HX711 Lib are you using.?
Could you post a short listing of the results you got when using the 'working' first program.?

E
 

Thread Starter

Edi023

Joined Jun 13, 2022
10
hi Edi,
Which version of the HX711 Lib are you using.?
Could you post a short listing of the results you got when using the 'working' first program.?

E
Hi Eric,
the lib version I use is 0.7.4 by Bogdan Necula.
I found out that one board was't outputting 5v to the loadcell.
I changed that board out for a new one from sparkfun, so I loaded the calibration sketch and the second one is working.
So now I have two working loadcells with a deviation of 0.02, that is accurate enough.
Now I only have to see if I can combine the two of them in one sketch and push the values using Mqtt to my home assistant.
 

ericgibbs

Joined Jan 29, 2010
18,872
hi Edi,
Also using Bogdan.
I have two load cells I use for testing, 5kG and 30kG.
The 30kG was giving weird results, check the cable, and it had been chewed up by a mouse or some other critter... its ruined.!
However, the 5kg is running OK, see the clip attached. 500gm Cal weight and 36gm weight.
I will knock up a resistive test box to substitute for the ruined load cell.

Keep me posted with your dual sketch and I will run it.

E
 

Attachments

ericgibbs

Joined Jan 29, 2010
18,872
hi Edi,
There is a problem with that ESP32/Bogdan library, in that if the unloaded load cell output is greater than ~ -100uV the set-up code fails and the readings are large negative values.
I encountered this problem when using the 30kG load cell on the ESP32 , HX711 & Bogdan sketch, fixed it by adding a small positive offset voltage on the HX711 A+ input [1meg to +Vx].
When using the 30kG L/C with a Uno code and library, it works OK.

E
 

Thread Starter

Edi023

Joined Jun 13, 2022
10
Hello Eric,

due to some really nice weather here in holland my reply is a bit late, sorry for that.

I finished connected the sales under my bed and sinds I use home assistant I decided to use the esphome add-on and found a
piece off code to use and well it works flawless, only have to fine tune it a bit.
Thank you for your time and patience.

I don't think this piece off code works with the ardunio software but here it is:
Code:
globals:
  - id: initial_zero
    type: float
    restore_value: yes
    # NOTE: make sure to align this value to the one used in "calibrate_linear" below!
    initial_value: '51265'
  - id: initial1_zero
    type: float
    restore_value: yes
    # NOTE: make sure to align this value to the one used in "calibrate_linear" below!
    initial_value: '8037'
    
  - id: auto_tare_enabled
    type: bool
    restore_value: yes
    initial_value: 'true'
  - id: auto_tare1_enabled
    type: bool
    restore_value: yes
    initial_value: 'true'

  - id: auto_tare_difference
    type: float
    restore_value: yes
    initial_value: '0'
  - id: auto_tare1_difference
    type: float
    restore_value: yes
    initial_value: '0'
    
  - id: manual_tare_flag
    type: bool
    restore_value: no
    initial_value: 'false'
  - id: manual_tare1_flag
    type: bool
    restore_value: no
    initial_value: 'false'

    
switch:
  ## Switch to enable/disable the auto tare feature
  - platform: template
    id: bed_deur_continuous_tare_enabled
    name: "Smart Scale Continuous Tare Enabled"
    lambda: |-
      return id(auto_tare_enabled);
    turn_on_action:
      - lambda: |-
          id(auto_tare_enabled) = true;
    turn_off_action:
      - lambda: |-
          id(auto_tare_enabled) = false;
          
  - platform: template
    id: bed_kast_continuous_tare_enabled
    name: "Smart Scale Continuous Tare Enabled"
    lambda: |-
      return id(auto_tare1_enabled);
    turn_on_action:
      - lambda: |-
          id(auto_tare1_enabled) = true;
    turn_off_action:
      - lambda: |-
          id(auto_tare1_enabled) = false;
 
  ## Switch used to initiate a manual tare
  - platform: template
    id: bed_deur_manual_tare_action_switch
    name: "Smart Scale Manual Tare Action"
    lambda: |-
      return id(manual_tare_flag);
    turn_on_action:
      - lambda: |-
          id(auto_tare_difference) = id(initial_zero) - id(bed_deur_value_raw).state;
      - switch.turn_off: bed_deur_manual_tare_action_switch
    turn_off_action:
      - lambda: |-
          id(manual_tare_flag) = false;
  - platform: template
    id: bed_kast_manual_tare_action_switch
    name: "Smart Scale Manual Tare Action"
    lambda: |-
      return id(manual_tare1_flag);
    turn_on_action:
      - lambda: |-
          id(auto_tare1_difference) = id(initial1_zero) - id(bed_kast_value_raw).state;
      - switch.turn_off: bed_kast_manual_tare_action_switch
    turn_off_action:
      - lambda: |-
          id(manual_tare1_flag) = false;

## Sensor Configuration ##
sensor:
  # template sensors from global variables
 
  - platform: template
    id: bed_deur_initial_zero
    name: "bed deur Initial Zero"
    lambda: |-
      return id(initial_zero);
    update_interval: 1s
  - platform: template
    id: bed_kast_initial_zero
    name: "bed kast Initial Zero"
    lambda: |-
      return id(initial1_zero);
    update_interval: 1s
    
  - platform: template
    id: bed_deur_auto_tare_difference
    name: "bed deur Auto Tare Difference"
    lambda: |-
      return id(auto_tare_difference);
    update_interval: 1s
  - platform: template
    id: bed_kast_auto_tare_difference
    name: "bed kast Auto Tare Difference"
    lambda: |-
      return id(auto_tare1_difference);
    update_interval: 1s
    
  # sensors imported from home assistant
  - platform: homeassistant
    id: homeassistant_initial_zero
    entity_id: input_number.bed_deur_initial_zero
    on_value:
      then:
        - lambda: |-
            id(initial_zero) = x;
  - platform: homeassistant
    id: homeassistant_initial_zero1
    entity_id: input_number.bed_kast_initial_zero
    on_value:
      then:
        - lambda: |-
            id(initial1_zero) = x;
 
  # RAW Scale input
  - platform: hx711
    id: bed_deur_value_raw
    internal: True
    dout_pin: 5
    clk_pin: 18
    gain: 128
    unit_of_measurement: kg
    accuracy_decimals: 2
    update_interval: 0.2s
    filters:
      - sliding_window_moving_average:
          window_size: 5
          send_every: 5
    on_value:
      then:
        - sensor.template.publish:
            id: bed_deur_value
            state: !lambda 'return id(bed_deur_value_raw).state;'
        - if:
            condition:
              and:
                - lambda: 'return id(auto_tare_enabled);'
                # current smart scale value is below approx. 10KG (raw value -275743) aka nobody is standing on the scale
                - lambda: 'return id(bed_deur_value).state < 10.0;'
            then:
              - if:
                  condition:
                    # current raw scale value is below expected zero value
                    - lambda: 'return id(bed_deur_value_raw).state < (id(initial_zero) - id(auto_tare_difference));'
                  then:
                    # INcrease Auto-Tare offset to slowly align real zero value with expected zero value
                    - lambda: |-
                        id(auto_tare_difference) += 10;
                  else:
                    # DEcrease Auto-Tare offset to slowly align real zero value with expected zero value
                    - lambda: |-
                        id(auto_tare_difference) -= 10;
  - platform: hx711
    id: bed_kast_value_raw
    internal: True
    dout_pin: 23
    clk_pin: 19
    gain: 128
    unit_of_measurement: kg
    accuracy_decimals: 2
    update_interval: 0.2s
    filters:
      - sliding_window_moving_average:
          window_size: 5
          send_every: 5
    on_value:
      then:
        - sensor.template.publish:
            id: bed_kast_value
            state: !lambda 'return id(bed_kast_value_raw).state;'
        - if:
            condition:
              and:
                - lambda: 'return id(auto_tare1_enabled);'
                # current smart scale value is below approx. 10KG (raw value -275743) aka nobody is standing on the scale
                - lambda: 'return id(bed_kast_value).state < 10.0;'
            then:
              - if:
                  condition:
                    # current raw scale value is below expected zero value
                    - lambda: 'return id(bed_kast_value_raw).state < (id(initial1_zero) - id(auto_tare1_difference));'
                  then:
                    # INcrease Auto-Tare offset to slowly align real zero value with expected zero value
                    - lambda: |-
                        id(auto_tare1_difference) += 10;
                  else:
                    # DEcrease Auto-Tare offset to slowly align real zero value with expected zero value
                    - lambda: |-
                        id(auto_tare1_difference) -= 10;

    
  # Mapped value to KG
  - platform: template
    id: bed_deur_value
    name: "bed_deur"
    internal: False
    filters:
      # apply auto_tare difference
      - lambda: 'return x + id(auto_tare_difference);'
      # apply rough calibration
      - calibrate_linear:
          # retrieve these values by evaluating the raw values with loads of known mass.
          # note that a bigger difference between measurements usually results in higher resolution,
          # so measure 0 Kg and the highest known mass you have (like f.ex. your own weight, measured by a normal scale with good accuracy)
          - 51265 -> 0
          - 88682 -> 82
      # map values below 0.1 to 0 (to decrease value changes due to random fluctuation)
      - lambda: |-
          if (x <= 0.1) {
            return 0.0;
          } else {
            return x;
          }
  - platform: template
    id: bed_kast_value
    name: "bed_kast"
    internal: False
    filters:
      # apply auto_tare difference
      - lambda: 'return x + id(auto_tare1_difference);'
      # apply rough calibration
      - calibrate_linear:
          # retrieve these values by evaluating the raw values with loads of known mass.
          # note that a bigger difference between measurements usually results in higher resolution,
          # so measure 0 Kg and the highest known mass you have (like f.ex. your own weight, measured by a normal scale with good accuracy)
          - 8037 -> 0
          - 24646 -> 82
      # map values below 0.1 to 0 (to decrease value changes due to random fluctuation)
      - lambda: |-
          if (x <= 0.1) {
            return 0.0;
          } else {
            return x;
          }
          
    unit_of_measurement: kg
    accuracy_decimals: 2
    update_interval: 1.0s
 
Top