Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seting Up multiple amplifiers for multiple load cells #35

Open
rtlop opened this issue Apr 7, 2016 · 182 comments
Open

Seting Up multiple amplifiers for multiple load cells #35

rtlop opened this issue Apr 7, 2016 · 182 comments

Comments

@rtlop
Copy link

rtlop commented Apr 7, 2016

So the library works great for one amplifier and load cell. But what would I need to change if I wanted to set up to 2 load cell and amplifiers?

@electrokean
Copy link

Two ways I can suggest:

  1. use channel B to connect the second load cell and select it using scale.set_gain(32)
  2. instantiate a second HX711 object using a different pair of I/O pins, and use a second HX711 interface PCB, both using channel A for the load cell input - e.g. HX711 scale1(A1,A0), scale2(A3,A2);

Note that option 1 has some limitations (limited gain and limited library support), and relies on your HX711 interface PCB breaking out the channel B input pins. You would use the same excitation output for both load cells.

@bneedhamia
Copy link

I'm building a scale using 4 load sensors (each is half of a load cell) and Sparkfun's HX711 board (which has only one set of inputs). I recently decided to use a separate amplifier and HX711 object for each load sensor so that I can separately calibrate each load sensor. (Of course I'm adding two resistors to each load sensor to turn each sensor into a Wheatstone Bridge.) It's good to hear someone recommend using multiple HX711 objects in one Sketch.

@electrokean
Copy link

@bneedhamia you mention adding two resistors to create a wheatstone bridge from those half-load cells. What tolerance resistors are you using?
Your blog post mentions 0.7lb variance for approx 15lb weight in different locations. That is just under a 5% variance. I hope you're not using 5% resistors :)
Even if you use a pair of 1% resistors, you could see +/-2% variance or approx 4% variance between any two of the bridges (not even allowing for the load cell matching).

@ghost
Copy link

ghost commented Apr 25, 2016

Hello,
I use for test three HX11 with load cells.

And this code:

HX711 scale0(A1, A0);
HX711 scale1(A2, A0);
HX711 scale2(A3, A0);
#define SENSORCNT 3
HX711 *scale[SENSORCNT];
...
void setup()
{
scale[0] = &scale0;
scale[1] = &scale1;
scale[2] = &scale2;
...
}

void loop()
{
for (uint8_t i = 0; i < SENSORCNT; i++)
{
long read = scale[i]->read();
value[i] = (read - scale[i]->get_offset()) / scale[i]->get_scale();
Serial.print(" ");
Serial.print(read);
Serial.print(" ");
Serial.print(value[i], 1);
}
...
}


Output:

Value: 238452 0.9 198543 0.0 217988 0.0
Value: 238448 0.1 198569 0.0 217965 0.0
...

But sometimes (ie. 15 sec.) I got an error on one Channel:
Value: -8388607 -1891.9 198575 0.0 217965 0.0 <- error !

This happens in different times on all channels and only if I run throught all sensors - not with a single on.

Pit

@matouchat790te
Copy link

I have the same issue as pit001, with one XH711 it's ok. With 3 , sometime values not valid. An idea ?

@electrokean
Copy link

@matouchat790te Are you sharing a pin for the HX711 clock like A0 in the above example?
I believe this could be the cause. Can you try wiring two separate pins for each HX711.
You don't want to be clocking all 3 HX711 chips every time you read one, as it could lead to this kind of issue.

@matouchat790te
Copy link

I'm not sharing pins. each HX711 has is own .
If I do a squale_power_up / down at each loop, the problem disappear. But it's too slow.
One other way is to use three arduino board and 'OR' the ouputs, but it's not elegant . the project is for a touch probe for a cnc milling machine.

@matouchat790te
Copy link

I'll put an oscilloscope on the pins, and a logic analyzer to see if the problem is outside or not. may be I have crosstalk between channels which makes pulses on the wrong clock input. Disable interrupts has no effect.
I'm glad to see I'm not alone with this issue.

@matouchat790te
Copy link

Hello all.
I did some measurements
And I noticed an important point: the HX711 periodically performs conversion without external application need. It works in free running.

With only one HX711 : If we wait for the conversion end signal, all goes well. ( Falling edge of DOUT ) This works for one XH711.
But as soon we use more, calling the ‘is_ready’ function becomes asynchronous. It is not clear in the datasheet, but the HX711 is free running at 80Hz. And if you activate CLOCK signal a few microseconds before the next end of conversion, you may just send the clock at the wrong time in the 10 microseconds time . Named # T1 1: falling edge to DOUT PD_SCK rising edge. (See datasheet). and data will be wrong.
In all the tests I made the datas were false if the Arduino make a request exactly 12.75ms after the last end of conversion signal. ( falling edge of DOUT )
This bug could also appear with one HX711 if you make asynchronous read of the chip.

I have an imperfect workaround: make a loop for the FALLING edge of DOUT rather than checking its level and immediately start the clock for reading data. But you may be waiting 12 ms more than necessary.

Anyone have a better solution ?

@electrokean
Copy link

@matouchat790te Yes, I experienced this behaviour too. My original debug code was doing too much processing or serial output between readings. Even after some work I would occasionally still get an incorrect reading which I would have to filter out. In the end I gave up on the HX711 due to its limitations and poor documentation.

@bneedhamia
Copy link

I've had nothing but good luck using the HX711 board from Sparkfun and
the https://github.com/bogde/HX711 library, connected to an Arduino
101. I used them in both a dog bed weight scale and a dog water bowl
scale. My app code is at
https://github.com/bneedhamia/CurieBLEBowlScale and
https://github.com/bneedhamia/CurieBLEWeightMonitor if you'd like to
take a look. The Bowl project uses one load cell connected to the
HX711; the bed uses 4 load sensors (each 1/2 a wheatstone bridge) plus
matched resistors, and 4 HX711s.

Granted, all those projects do is read the weight and send it via BLE to
a Raspberry Pi gateway - they don't do a lot of computation between
HX711 readings.

On 9/12/2016 5:45 AM, Kean Maizels wrote:

@matouchat790te https://github.com/matouchat790te Yes, I experienced
this behaviour too. My original debug code was doing too much
processing or serial output between readings. Even after some work I
would occasionally still get an incorrect reading which I would have
to filter out. In the end I gave up on the HX711 due to its
limitations and poor documentation.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#35 (comment), or
mute the thread
https://github.com/notifications/unsubscribe-auth/AJqtSoNz2MK5RSmvqFQ95zhrsU_O5p-jks5qpUligaJpZM4ICbpk.

@matouchat790te
Copy link

matouchat790te commented Sep 12, 2016

One way could be using interrupts , one on each HX711. so moving on Mega .
I found a similar AD with same serial link here : http://www.analog.com/media/en/technical-documentation/data-sheets/AD7780.pdf
they spoke about 'ensure reading before new conversion signal '

@compugician
Copy link

Hi all,

I wrote a library that resolves most of the issues discussed here with multiple cells, while also sampling all of them at 80hz simultaneously.

check it out:
https://github.com/compugician/hx711-multi

It is stripped at the moment of all the other functionality (tare, offset, units, etc.) but those are easy to implement on your own in or out of the library if you'd like.

I'll add them soon, hopefully, or if someone wants to contribute please do.

@matouchat790te
Copy link

matouchat790te commented Sep 18, 2016

Hello all,
I replaced in the beginning of function read()
long HX711::read() {
// wait for the chip to become ready
while (!is_ready());


by this
long HX711::read() {
// wait for the chip to become ready
if (!is_ready()){
while (!is_ready()) { // we are at 1 ,0 we wait for falling edge
// Will do nothing on Arduino but prevent resets of ESP8266 (Watchdog Issue)
yield();
}
} else {
while (is_ready()) {
// attend 1
yield();
}
while (!is_ready()) {
// wait for falling edge
yield();
}
}


waiting the FALLING edge of data ready ( DOUT ) ensuring the data is available for the next 10 ms

@compugician
Copy link

@matouchat790te

I'm looking to understand this problem better so I can fix it also in my copy of this repository.

If I understand your code correctly, doesn't that effectively reduce the sampling rate by at least half?

Maybe I'm misunderstanding the original issue, but if the issue that some samples are bad because we're sampling too 'late' after a ready signal, maybe the solution should be to check the timing from the last known good sample, and as long as it is within a threshold of a full cycle we go ahead and sample, and otherwise wait?

Of course that is not guaranteed to work forever because of the two-clocks problem, but that could be mitigated either by once in a while re-setting the chip, or otherwise re-synchronizing our timing (to a falling edge, for example, by using your trick)?

Thoughts?

@SreevatsaAcharya
Copy link

Hello,
I am trying to send the value obtained from the load cell to a server using a gprs sim900 module, and i am doing so as follows

char val[20];
char url[160];
float temp;
temp= scale.get_units(); // or scale.get_units(10); AVERAGE OF 10

  dtostrf(temp, 7, 2, val);
  snprintf(url, 74, "AT+HTTPPARA=\"URL\",\"http://www.website.com/test.php?temp=%s\"", val );
  mySerial.println(url);


and sending the variable "temp" in the http url request. i get the value on the serial monitor when i print the variable on the serial monitor but it does not get updated on the server. I just get a blank reading.

Am i missing something? Any solutions?

@compugician
Copy link

I'm not sure how this is a question to the HX711 issues forum.

  1. The most obvious thing not shown in your code is how you are sending this to the http server.
  2. Do you know your server works? If you manually send a value in a URL of an http request does it work?
  3. If yes to scale.set_zero()  #2, use the GPRS_TCPConnection example (or equivalent that came with the library for your shield), and manually change the URL there to yours. Notice that if you are using the seeed-studio library then you split the connection into gprs.connect to the server and gprs.send with a get command such as "GET /test.php?temp=123.45" (or put, or whatever your PHP script is expecting).
  4. If yes to using channel A + B together? #3, and indeed you see the value in 'val' when printed out, then check how your code for sending the http request differs from using channel A + B together? #3.

@SreevatsaAcharya
Copy link

@compugician

`
float temp;
char val[20];
char url[160];

void SendData() {
mySerial.println("AT+HTTPINIT"); //init the HTTP request
delay(2000);
ShowSerialData();

// Serial.print("Reading: ");

// temp=random(1000.12,9999.99);
temp= scale.get_units();
Serial.print(scale.get_units(), 1); //scale.get_units() returns a float
Serial.print(" Kg"); //You can change this to kg but you'll need to refactor the calibration_factor
Serial.println(temp);

delay(3000);

dtostrf(temp, 7, 2, val);
snprintf(url, 74, "AT+HTTPPARA="URL","http://www.website.com/test.php?temp=%s\"", val );
mySerial.println(url);

delay(3000);
ShowSerialData();

mySerial.println("AT+HTTPACTION=0");//submit the request
delay(10000);
ShowSerialData();

mySerial.println("AT+CIPCLOSE");//close the connection
delay(5000);
ShowSerialData();
}`

This is the code i am following and i am able to send static data to the server i.e if i define temp=2134 etc in the url. It also works if the variable temp receives the value from a random number generating function as shown.
But when i transfer value from the scale.get.units() function it returns blank.
I am using a Sim900 rs232 gprs module and found this method to be most suitable to send data. Initial settings are all correct and verified.

I tried the GET method but faced a lot of issues so shifted to this method.

@compugician
Copy link

So if you set temp manually it works, but if you use scale.get_units() it does not?

What is printed by 'Serial.println(temp)' in each case?

Also, what random() funtion are you using? AFAIK the standard one does not generate floating point numbers.

Does rounding temp solve result in the data getting to the server appropriately?

@SreevatsaAcharya
Copy link

Finally!!! Made it work. The scale.get.units() function reads value from the load cell very quickly so i guess the value wasn't actually getting stored in the variable i defined. Made a few changes , and now it works.
Thanks for your help @compugician

@lucian0112
Copy link

@compugician - First of all great job with the library.
Is there any chance to include in it the tare function and calibration?
I tested your library with 12 hx711 sharing same clock and seems work fine, but I was not able to implement these functions which are actually very important for me....

Thanks

@jpk73
Copy link

jpk73 commented Sep 27, 2017

@tk5ep
Copy link

tk5ep commented Oct 18, 2017

Hi,
@lucian0112
Do i understand it correctly that you're using a DOUT pin common to all your 12 HX711 ?

I would like to use 4 HX711 using the minimum number of pins of my pro mini. I don't need any speed, so i will use 40Hz not 80Hz.

Would the original library work without here described problems ?

Thanks,

@lucian0112
Copy link

Hi,
Yes you are correct. I used that lib and 12 hx711 with clock pin shared. The problem for me was that I was not able to implement functions in it like (tare, calibration etc...). The lib just read raw values of the chips.
Not sure if is relevant but my hx's were modified for 80Hz.
Meanwhile I moved on arduino mega and have enough pins to use them on classic wired

Cheers

@zstergios
Copy link

Hi there!
I have work in past with1 load cell and + HX711 (bodge library)

I want to build a large scale, so I will need 6 load cells. (2 front,2 middle,2 back)
I planning to use 3xHX711 chips (1 per 2 cells/row)

My purpose is to get the total weight.
I have checked the multi-HX711 library, but what's the logic of combining 3 values?
I guess it's SUM of readings divided by 3 (total of amplifiers)?
How accurate is this way?

THANK YOU

@tk5ep
Copy link

tk5ep commented Oct 29, 2017

Hi,

How do you connect 2 cells to one HX711 ?

Never thought about your problem, but i don't see any other way to solve it than summing the 3 readings.
About accuracy, if you have a common scale, you will never know how much weight is on which cell. You can only suppose it is an equal part of the total weight... so ....

Keep us informed, i might have the same need soon !

@zstergios
Copy link

You can connect 4 load cells to one chip.
Search for half bridge and full bridge hx711.

The issue is when you have 6 or 3. Need to summarize them probably

@lucian0112
Copy link

Have you connected 4 load cells to one chip? Please tell us how you did it.

@zstergios
Copy link

zstergios commented Nov 6, 2017

It's simple, just search on google.
http://prntscr.com/h6u02q (Source https://www.youtube.com/watch?v=0Lwdzpr_TxM)

Edit: Link fixed

@detroit54
Copy link

makay68g: I tried a delayMicroseconds(1); after all PD_SCK writing in the HX711-MULTI.cpp code as you suggested but I still get those random high values. I thought I should try it just to see what happens, and I still like the higher sampling rate I get with that code. Especially if the regular HX711 library still gives me some random errors.

It makes me think maybe I should just post-process the data file and replace (with the average of the previous and following readings) or delete the incorrect values. I'll have to do more testing with both methods and see what works best.

@matouchat790te
Copy link

Yes for speed I use one arduino nano per channel. All 3 are 'ORed ' to produce one signal ''touch'' for the CNC . The sphere at the bottom of the picture is probe tip used to find the edge of the part. Or to find the center of a hole.

@detroit54
Copy link

Do you think digitalWriteFast(), digitalReadFast(), and pinModeFast() might speed up the HX711 library for reading them one at a time? Or possibly using PORT commands to read all eleven pins at the same time as fast as the MEGA can handle it?

@matouchat790te
Copy link

mixing all 11 channels is not the good solution. fast reading or not. They are working asynchronously . It'll never get accurate readings

@detroit54
Copy link

I was thinking more of parallel processing somehow while continuously reading all pins. But I don't really understand this well enough to know if it could be made to work.

@matouchat790te
Copy link

doing all 11 in the same loop is like waiting for conjunction of 11 planets . It's ... rare, Try to wire 11 HX711 on separates entries and run 11 instances of HX711 objects

@detroit54
Copy link

Do you still think it's worth splitting out the 11 CLK wires to individual pins?

@matouchat790te
Copy link

good morning. I've made a specific soft to trap the problem, the soft raise a pin to signal value out of range on a no stress sensor. Normally the value must not change a lot. We have an error when we start to read D_OUT pin when it is still on high level. in violation of the specifications. So .. certainly the multi HX711 at one moment have a slow shift and fall in this case. I have no time to multiHX711 this morning.
error_if_clk_when_high

@makay68g
Copy link

makay68g commented Dec 10, 2018

@detroit54: when you read 1250 psi intead of 2500 psi, that is a simple bit shift: you missed one bit.

Using one CLK and using the HX711's asynchronously is not as bad as it sounds at first. By controlling them using the CLK they will become more-or-less synchronous sooner or later. The problem is that they run free: if one is a bit faster than the others, it will start transmitting data sooner and you will get an error. The problem is, that they do not hold the ready bit long enough to enable true synchronous working (that is what we tested with that max. 3 millisecond waiting). BTW: you might try that with even smaller numbers and using digitalReadFast in the is_ready function...

Certainly 11 individual CLK wires and separate reading will help with the errors, but your Arduino may not be fast enough to read all the sensors one after the other at an appropriate frequency. For this to work you should definitely try digitalReadFast, digitalWriteFast, that should help a lot. But also notice, that according to the specification of the HX711, the PD_SCK HIGH and LOW time must be at least 0.2 us and according to https://github.com/NicksonYap/digitalWriteFast the read/write takes 0.125 us. So you might simply write PD_SCK TWICE, which would make it 0.25 us:

digitalWrite(CLK, HIGH);
digitalWrite(CLK, HIGH);

This is definitely needed at the gain setting part. You might not need it in the reading part.

Another idea is to read the HX711's in the order they present themselves as ready in a round robin fashion. That is: wait for an HX711 to be ready by checking all of them and stopping at the first one saying it is ready. Read the data from it, mark is as finished and check for another not finished HX711 to be ready. If you have your data from all HX711's (all of them marked as finished), then delete that mark and start again. With this method you keep your Arduino busy at all times. Reading them sequentionally may slow down the reading, but they migh fall into one line after some time, you might try that too, it is definitely easier to program. You should be able to read all HX711's at 80Hz: since setting the PD_CLK must take at least 0.4us, reading the bit takes 0.125us, and you also need some time to process the result, so reading 24 bits will take somewhere around 20-50us. 11 of them will take 220-550 us, with 80Hz it is somewhere between 20-50 ms, and you should complete it in 1 second. You definitely cannot do that with the "normal" diritalRead/digitalWrite, as it take 50 times more time according to https://github.com/NicksonYap/digitalWriteFast.

I am really interested in what you can do with this, so tell me your results... :)

@makay68g
Copy link

P.S.: I just realized: with digitalReadFast, digitalWriteFast you might be able to read all HX711's in one group. It is possible, that you will have more errors while reading, but still: it would be an interesting test... :)

@detroit54
Copy link

I'll try this out a little later when I get some free time! It's a side project, so I've been working on it during evenings and weekends mostly :) It is exciting to see it starting to work, and I really appreciate all the help!

@matouchat790te
Copy link

Thanks matay68g, I discover the digitalWriteFast function
I'll analyze how to read 24 bits in one call . It'll faster !

@makay68g
Copy link

@detroit54, @matouchat790te: Did you have any success with digitalReadFast and digitalWriteFast?

@detroit54
Copy link

I still need to try that. I got pulled onto another project, but things should be slowing down for me enough to try it out after next week :)

@Wiljan1
Copy link

Wiljan1 commented Jan 13, 2019

Hi
I'm trying to make a pressure triggered floor with several zones and do used 4 weight cell on each HX711

I do run Arduino UNO with 4 x HX711 and a common CLK ans I do see error as well when using more than 1 HX711.

Using a scope and look on the "data" out of the HX711 with the "clk" grounded you will see a short pulse 100uS every 100mS (10Hz = converting rate).

For sure it will shift in time so when trying to read multiply HX711
More boards will make the risk for collision bigger

This confirm that the HX711 does convert even without trying to clk / read and this pulse does show it's busy.

I have tried to modify the HX711.c read to be sure not to try to read while conversion are in process

// wait while low for a high
while (is_ready()) {
yield();
}

while (!is_ready()) {
// wait for falling edge
yield();
}

This will make the read to start just after end of conversion and not potential just before

Also I have extended the last bit for the gain since it's way shorter that the shiftIn

// set the channel and the gain factor for the next reading using the clock pin for (unsigned int i = 0; i < GAIN; i++) { digitalWrite(PD_SCK, HIGH); digitalWrite(PD_SCK, HIGH); // extend the high clk to be longer digitalWrite(PD_SCK, LOW);

And a final approach is to make a a Trigger counter so a value should be above a certain value for 2 or 3 measurements.

So far so good, but now it's a bit slow due to all the work around so any good idea are welcome

@detroit54
Copy link

Hi all,

I'm back on this project now. I just rewired the breadboard so each HX711 has its own clock pin, and I created a MEGA shield PCB layout which I will etch in the next week or two when I get time. I want to get this off the breadboard to eliminate possible loose connections and lots of wires crossing over the circuitry. I'll let you know if separating the clock pins makes any difference after I get a chance to test it. I might try that digitalWriteFast routine after I get it onto the PCB.

image

@makay68g
Copy link

@detroit54: The point of using digitalReadFast and digitalWriteFast is that you could read all HX711's with a shared clock pin. Using @Wiljan1's idea you might be able to read them without those reading errors. Using the 80 Hz setup you should be able to read the HX711's in 40 Hz frequency.

@Wiljan1
Copy link

Wiljan1 commented Jan 14, 2019

I did split my Arduino up into 4 X clk + 4 x data and use the normal HX711 4 times (no wating for while (is_ready()) only the while (!is_ready())

HX711 scale_A(DOUT_A, CLK_A); HX711 scale_B(DOUT_B, CLK_B); HX711 scale_C(DOUT_C, CLK_C); HX711 scale_D(DOUT_D, CLK_D);

I did remove the check for 2 round and it has been running for a few hours without and "fail" read
So right now I have like 5 reads of all 4 HX711 per second

I also did look on the 10/80 times sample and the pin 15 on all the HX711 boards I have here are connected to gnd via a track on the PCB which goes under the HX711 chip.
So to change to 80 samples it's required to lift the pin 15 and solder it to pin 16.
I will try to avoid that since some of the board are already installed and not easy to get access to

I also had in mind to use 4 small 8bit PIC chip to read the HX711 and send the data to the Arduino on a sequential request

But for now I do think I can live with the read speed.

@detroit54
Copy link

I know the potential is there to use the shared clock pin, but I needed to get something production-ready in the short term so I decided to try what I was sure would work. With individual pins, I'm able to read twelve (I added one) HX711s at around 13 Hz with no errors. I might even be able to use digitalReadFast to speed that up a bit, or maybe some kind of sorting routine if I can work it out to read them in the order that they are ready assuming all the clocks stay where they are - i.e. instead of reading 1,2,3,4, determine which one is ready first and read in that order (4,2,1,3 for instance).

One question I have: if one of the HX711 modules has failed or is not plugged in, the code stalls for a long time. Is there a way to check to see if the modules are working with a timeout that will allow me to just skip the modules that are either no longer working or not installed?

I just etched and drilled a PCB for this. It will sit on top of the MEGA 2560 like a shield:

image

@ppdepra
Copy link

ppdepra commented Jun 8, 2020

Hi guys,
I'm an Arduino novice.
I am trying to carry out a design of a force platform with 4 load sensors. However, I am having problems running the sketch. Has anyone in this group ever posted a sketch with the simultaneous use of 4 Load Cells and 4 Hx711?

@detroit54
Copy link

detroit54 commented Jun 8, 2020

The code below is what I used to connect up to 12 HX711 modules to an Arduino MEGA 2560. I got it working for 11 connected with one commented out for a future add-on load cell, but it will work for all 12. I was using this for one 50k loadcell, eight 10k load cells, and two 5,000psi pressure transducers. IIRC this code would read all 11 load cells at around 8 Hz, which was fast enough for my purposes. The OLED display code is left in case you need it, but commented out since I decided to just use the serial monitor to view data. Hope this helps!

// Modified 1/24/2019 for separate CLK pins for each HX711 module, added 12th HX711 to code
// NOTES: 1. If one HX711 module is bad, the code will run extremely slowly or not at all.
//        2. The bad module can be identified by commenting out one module at a time from the code starting with scale.begin statements.

#include "HX711.h"
//#include <Wire.h>
//#include <Adafruit_SSD1306.h>
//#include <Adafruit_GFX.h>

// OLED display TWI address
//#define OLED_ADDR   0x3C

HX711 scale1;
HX711 scale2;
HX711 scale3;
HX711 scale4;
HX711 scale5;
HX711 scale6;
HX711 scale7;
HX711 scale8;
HX711 scale9;
HX711 scale10;
HX711 scale11;
//HX711 scale12;
float val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12;

//Adafruit_SSD1306 display(-1);

//#if (SSD1306_LCDHEIGHT != 64)
//#error("Height incorrect, please fix Adafruit_SSD1306.h!");
//#endif

void setup() {
  // initialize and clear display
/*  display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
  display.clearDisplay();
  display.display();

  // display a line of text
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.print("YOUR LOGO");
  display.setTextSize(1);
  display.println("Load");
  display.println("Cell");
  display.println("Program");
  
  // update display with all of the above graphics
  display.display();
  
  delay(2000);

  display.clearDisplay();
  display.display();
*/
  Serial.begin(115200);
  Serial.println("HX711 Demo");

  Serial.println("Initializing the scale");
  // parameter "gain" is ommited; the default value 128 is used by the library
  // HX711.DOUT	- pin #A1
  // HX711.PD_SCK	- pin #A0
  // syntax: scale.begin(DOUT, CLK)
  scale1.begin(A1, A0);  Serial.println("Scale1 initialized");
  scale2.begin(A3, A2);  Serial.println("Scale2 initialized");
  scale3.begin(A5, A4);  Serial.println("Scale3 initialized");
  scale4.begin(A7, A6);  Serial.println("Scale4 initialized");
  scale5.begin(A9, A8);  Serial.println("Scale5 initialized");
  scale6.begin(A11, A10);  Serial.println("Scale6 initialized");
  scale7.begin(3, 2);  Serial.println("Scale7 initialized");
  scale8.begin(5, 4);  Serial.println("Scale8 initialized");
  scale9.begin(7, 6);  Serial.println("Scale9 initialized");
  scale10.begin(9, 8);  Serial.println("Scale10 initialized");
  scale11.begin(11, 10);  Serial.println("Scale11 initialized");
  //scale12.begin(13, 12);  Serial.println("Scale12 initialized");

  Serial.println("Before setting up the scale:");
  Serial.print("read: \t\t");
  Serial.println(scale1.read());			// print a raw reading from the ADC
  Serial.println(scale2.read());      // print a raw reading from the ADC
  Serial.println(scale3.read());      // print a raw reading from the ADC
  Serial.println(scale4.read());      // print a raw reading from the ADC
  Serial.println(scale5.read());      // print a raw reading from the ADC
  Serial.println(scale6.read());      // print a raw reading from the ADC
  Serial.println(scale7.read());      // print a raw reading from the ADC
  Serial.println(scale8.read());      // print a raw reading from the ADC
  Serial.println(scale9.read());      // print a raw reading from the ADC
  Serial.println(scale10.read());      // print a raw reading from the ADC
  Serial.println(scale11.read());      // print a raw reading from the ADC
 // Serial.println(scale12.read());      // print a raw reading from the ADC
 
  Serial.print("read average: \t\t");
  Serial.println(scale1.read_average(20));  	// print the average of 20 readings from the ADC

  Serial.print("get value: \t\t");
  Serial.println(scale1.get_value(5));		// print the average of 5 readings from the ADC minus the tare weight (not set yet)

  Serial.print("get units: \t\t");
  Serial.println(scale1.get_units(5), 1);	// print the average of 5 readings from the ADC minus tare weight (not set) divided
						// by the SCALE parameter (not set yet)

  scale1.set_scale(-523000.f);    // -523000.f seems to give me 1:1 for mV output testing with 5,10,15mV                // this value is obtained by calibrating the scale with known weights; see the README for details
  scale2.set_scale(-523000.f);    //(-1246.f);
  scale3.set_scale(-523000.f);    //(-1246.f);
  scale4.set_scale(-523000.f);    //(-1246.f);
  scale5.set_scale(-523000.f);    //(-1246.f);
  scale6.set_scale(-523000.f);    //(-1246.f);
  scale7.set_scale(-523000.f);    //(-1246.f);
  scale8.set_scale(-523000.f);    //(-1246.f);
  scale9.set_scale(-523000.f);    //(-1246.f);
  scale10.set_scale(-523000.f);    //(-748.f);
  scale11.set_scale(-523000.f);    //(-748.f);
//  scale12.set_scale(-523000.f);    //(-748.f);
  //scale.tare();				        // reset the scale to 0

  Serial.println("After setting up the scale:");

  Serial.print("read: \t\t");
  Serial.println(scale1.read());                 // print a raw reading from the ADC

  Serial.print("read average: \t\t");
  Serial.println(scale1.read_average(20));       // print the average of 20 readings from the ADC

  Serial.print("get value: \t\t");
  Serial.println(scale1.get_value(5));		// print the average of 5 readings from the ADC minus the tare weight, set with tare()

  Serial.print("get units: \t\t");
  Serial.println(scale1.get_units(5), 1);        // print the average of 5 readings from the ADC minus tare weight, divided
						// by the SCALE parameter set with set_scale

  Serial.println("Readings:");
}

void loop() {
  Serial.print("one reading:\t");
  val1 = scale1.get_units();
  val2 = scale2.get_units();
  val3 = scale3.get_units();
  val4 = scale4.get_units();
  val5 = scale5.get_units();
  val6 = scale6.get_units();
  val7 = scale7.get_units();
  val8 = scale8.get_units();
  val9 = scale9.get_units();
  val10 = scale10.get_units();
  val11 = scale11.get_units();
//  val12 = scale12.get_units();
  Serial.print(millis()); Serial.print(" "); Serial.print(val1, 1); Serial.print(" "); Serial.print(val2, 1); Serial.print(" "); Serial.print(val3, 1); Serial.print(" "); Serial.print(val4, 1); Serial.print(" "); Serial.print(val5, 1); 
  Serial.print(" "); Serial.print(val6, 1); Serial.print(" "); Serial.print(val7, 1); Serial.print(" "); Serial.print(val8, 1); Serial.print(" "); Serial.print(val9, 1); Serial.print(" "); Serial.print(val10, 1); Serial.print(" "); Serial.print(val11, 1); Serial.print(" "); Serial.print(val12, 1); Serial.print(" ");

@ppdepra
Copy link

ppdepra commented Jun 8, 2020

Thank you @detroit54. I appreciate your help.

@ppdepra
Copy link

ppdepra commented Jun 10, 2020 via email

@detroit54
Copy link

I never created a readme file for that code, but you can try looking at this one:

https://github.com/bogde/HX711/blob/master/README.md

There is a section that discusses how to calibrate in that readme file.

The code I posted on June 8, 2020 works for multiple load cells but I am using one HX711 for each four wire load cell. If you are doing something different, like integrating four smaller load cells for a bathroom scale, try looking at some of this example:

https://www.instructables.com/id/Arduino-Bathroom-Scale-With-50-Kg-Load-Cells-and-H/

I don't have any experience with this example, I only know how to connect four or more individual load cells.

@vincentj87
Copy link

hello I just tried to make an arduino project where I used 3 scales, I used libra from https://github.com/compugician/HX711-multi/blob/master/examples/HX711-multi/HX711-multi.ino

I get an error where the output of the serial monitor is not clear, but the number is static depending on the weight I put in the load cell `#include "HX711-multi.h"

// Pins to the load cell amp
#define CLK A0 // clock pin to the load cell amp
#define DOUT1 A1 // data pin to the first lca
#define DOUT2 A2 // data pin to the second lca
#define DOUT3 A3 // data pin to the third lca

#define BOOT_MESSAGE "MIT_ML_SCALE V0.8"

#define TARE_TIMEOUT_SECONDS 4

byte DOUTS[3] = {DOUT1, DOUT2, DOUT3};

#define CHANNEL_COUNT sizeof(DOUTS)/sizeof(byte)

long int results[CHANNEL_COUNT];

HX711MULTI scales(CHANNEL_COUNT, DOUTS, CLK);

void setup() {
Serial.begin(9600);
Serial.println(BOOT_MESSAGE);
Serial.flush();

tare();
}

void tare() {
bool tareSuccessful = false;

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

void sendRawData() {
scales.read(results);
/* for (int i=0; i<scales.get_count(); ++i) {;
Serial.print( -results[i]);
Serial.print( (i!=scales.get_count()-1)?"\t":"\n");
}
*/
Serial.print(-results[0]);
Serial.print(" ");
Serial.print(-results[1]);
Serial.print(" ");
Serial.print(-results[2]);
Serial.println(" ");
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();
}

}`

@bogde
Copy link
Owner

bogde commented Apr 5, 2021

@vincentj87 It looks like you're using a different library. You may want to open an issue here: https://github.com/compugician/HX711-multi

@sandorimre
Copy link

I found a solution for multiple load cells with one single HX711 ADCmodule:
image
image
image

@compugician
Copy link

@sandorimre thanks for sharing. That method has its advantages and disadvantages, but essentially the whole thing becomes one load cell.

The benefit of using separate amplifiers per cell is that you get separate measurements from each cell, and depending on how they are connected physically, you can then use that extra data.

Definitely worth pointing out that aggregating is also an option.

At least in the first portion of your diagram it seems that you are using four half bridges, so this would be the equivalent of connecting two load cells -- I'd have to dive deeper into what you did there, but from first glance seems that it's in parallel?

@azertym
Copy link

azertym commented Dec 7, 2021

Hi evereybody , thanks for this post !

I would like make like this project. i use 6 hx711. Each hx711 it's like pressure sensor (under stone, when we walk on it i need to start something). But i don't understand how to take each sensor independently. I want to take this signal in node red after.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests