-
Notifications
You must be signed in to change notification settings - Fork 540
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
Comments
Two ways I can suggest:
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. |
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. |
@bneedhamia you mention adding two resistors to create a wheatstone bridge from those half-load cells. What tolerance resistors are you using? |
Hello, And this code:HX711 scale0(A1, A0); void loop() Output:Value: 238452 0.9 198543 0.0 217988 0.0 But sometimes (ie. 15 sec.) I got an error on one Channel: This happens in different times on all channels and only if I run throught all sensors - not with a single on. Pit |
I have the same issue as pit001, with one XH711 it's ok. With 3 , sometime values not valid. An idea ? |
@matouchat790te Are you sharing a pin for the HX711 clock like A0 in the above example? |
I'm not sharing pins. each HX711 has is own . |
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. |
Hello all. With only one HX711 : If we wait for the conversion end signal, all goes well. ( Falling edge of DOUT ) This works for one XH711. 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 ? |
@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. |
I've had nothing but good luck using the HX711 board from Sparkfun and Granted, all those projects do is read the weight and send it via BLE to On 9/12/2016 5:45 AM, Kean Maizels wrote:
|
One way could be using interrupts , one on each HX711. so moving on Mega . |
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: 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. |
Hello all, by this waiting the FALLING edge of data ready ( DOUT ) ensuring the data is available for the next 10 ms |
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? |
Hello,
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? |
I'm not sure how this is a question to the HX711 issues forum.
|
` void SendData() { // Serial.print("Reading: "); // temp=random(1000.12,9999.99); delay(3000); dtostrf(temp, 7, 2, val); delay(3000); mySerial.println("AT+HTTPACTION=0");//submit the request mySerial.println("AT+CIPCLOSE");//close the connection 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. I tried the GET method but faced a lot of issues so shifted to this method. |
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? |
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. |
@compugician - First of all great job with the library. Thanks |
check out these examples: |
Hi, 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, |
Hi, Cheers |
Hi there! I want to build a large scale, so I will need 6 load cells. (2 front,2 middle,2 back) My purpose is to get the total weight. THANK YOU |
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. Keep us informed, i might have the same need soon ! |
You can connect 4 load cells to one chip. The issue is when you have 6 or 3. Need to summarize them probably |
Have you connected 4 load cells to one chip? Please tell us how you did it. |
It's simple, just search on google. Edit: Link fixed |
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. |
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. |
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? |
mixing all 11 channels is not the good solution. fast reading or not. They are working asynchronously . It'll never get accurate readings |
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. |
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 |
Do you still think it's worth splitting out the 11 CLK wires to individual pins? |
@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:
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... :) |
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... :) |
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! |
Thanks matay68g, I discover the digitalWriteFast function |
@detroit54, @matouchat790te: Did you have any success with digitalReadFast and digitalWriteFast? |
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 :) |
Hi 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 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()) { 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
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 |
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. |
@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. |
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())
I did remove the check for 2 round and it has been running for a few hours without and "fail" read 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. 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. |
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: |
Hi guys, |
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!
|
Thank you @detroit54. I appreciate your help. |
Hi
Please, could you send me the readme file?
How is the procedure order to calibrate the scale?
Best,
Pedro
Em seg., 8 de jun. de 2020 às 11:33, detroit54 <notifications@github.com>
escreveu:
… 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. 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(" ");
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#35 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AP4KGLO4N3TYZLLVX7AMQOLRVTZFLANCNFSM4CAJXJSA>
.
--
Pedro Deprá
|
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. |
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 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() { tare(); void tare() { unsigned long tareStartTime = millis(); void sendRawData() { void loop() { sendRawData(); //this is for sending raw data, for where everything else is done in processing //on serial data (any data) re-tare }` |
@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 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? |
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. |
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?
The text was updated successfully, but these errors were encountered: