Closed scboulogne closed 2 years ago
thanks for the issue, I will look into it later today. I need a good read of the datasheet again...
Are you able to test? - I have no HX711 setup at the moment
@scboulogne Created a develop branch for this issue, no functional changes yet (have to read the datasheet. This branch adds the support of the RP2040 in the build-CI which is on my list, and already increased version to 0.3.4. The version might also be bumped to 0.4.0 depending on how breaking the support for the B channel is.
Hello Rob, thank you for your prompt response. Yes I have an HX711 sitting on my table (even 2 of them) and am planing to use it in the near future. I have already built a sensor prototype from an old bathroom scale, and I just need to solder a few wires to the module to get it hooked to Arduino Uno. I haven't used the HX711 or any other such diff amplifier before, am unfamiliar with your code, and so I might need some time to get all to work just with channel A. The project is to weigh bee hives remotely (in the mountains) and to log the results via gsm (sms) once or twice per day. It aims at having 4 x HX711 modules, and it would be nice to add a temperature sensor to at least one of them. So, I am running out of digital pins, but the analog ones (A0-3) are available, and I can, of course, just add a thermistor or a Pt-resistor. However, it seems more elegant to have a Wheatstone bridge with one or two thermistors in it, and to sample temperature variations on channel B with the same card, along with weight variations on channel A. For bees, this level of accuracy might be an overkill (I teach physics labs and am no expert in bees..), but I have another application in mind, in the student lab, where it is quite important. best to you, dmitrii
-----Original Message-----
From: Rob @.> To: RobTillaart @.> Cc: scboulogne @.>; Author @.> Date: Wednesday, 2 November 2022 3:10 PM CET Subject: Re: [RobTillaart/HX711] Access to the B-channel of HX711 (Issue #27)
Are you able to test? - I have no HX711 setup at the moment — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>
Thanks Dmitrii for the explanation.
one of the things you need to do is to make multiple samples and average them. I recall from similar projects that wind can influence the scales quite a bit. Maybe humidity needs to be monitored too as water can cause extra weight. That said, it is good for students to discover such "anomalies" themselves and explain them.
So, I am running out of digital pins, but the analog ones (A0-3) are available
The analog pins of the UNO can be used as digital ones. See - https://www.arduino.cc/en/Tutorial/Foundations/AnalogInputPins
Going to dive into the datasheet now, Might take a few days, in the meantime if there are questions just ask, R.
Datasheet was only 9 pages and the library already supported all that is needed to read channel B.
To select channel B
HX.set_gain(32);
HX.read(); // dummy read to send the new gain to the sensor
To select channel A
HX.set_gain(128);
HX.read(); // dummy read to send the new gain to the sensor
or
HX.set_gain(64);
HX.read(); // dummy read to send the new gain to the sensor
The version of the library can be downloaded from - https://github.com/RobTillaart/HX711/tree/develop
As the new version of set_gain() returns a bool to indicate valid value one can do
if (HX.set_gain(64) == false) Serial.println("error");
else HX.read(); // dummy read tonly if a new valid value is set.
Hello Rob, thank you for looking into this so rapidly. It looks perfect. I have also checked the hx711 datasheet and what you suggest makes sense to me. I will be able to test this on the weekend and will let you know asap. as for various errors I can face in using strain gauges, temperature is an obvious factor affecting the deformation of the sensor, though I haven't given much thought to it. Thank you for warning about humidity. I am currently worried most about residual deformation. These sensors are designed for short time stress, like in a bathroom scale. I plan to use them permanently charged. I ignore what residual unrecoverable deformation this would produce in a day or month. For this project to work, the sensor should remain reliable for several days, as the tendency of daily increases/decreases in weight is sought for. On a longer timescale it can drift off a bit, I suppose. So, after I get a functional prototype, I'll leave it working under charge for a month to see what happens.
-----Original Message-----
From: Rob @.> To: RobTillaart @.> Cc: scboulogne @.>; Mention @.> Date: Wednesday, 2 November 2022 5:48 PM CET Subject: Re: [RobTillaart/HX711] Access to the B-channel of HX711 (Issue #27)
Datasheet was only 9 pages and the library already supported all that is needed to read channel B. To select channel B HX.set_gain(32); HX.read(); // dummy read to send the new gain to the sensor To select channel A HX.set_gain(128); HX.read(); // dummy read to send the new gain to the sensor or HX.set_gain(64); HX.read(); // dummy read to send the new gain to the sensor The version of the library can be downloaded from - https://github.com/RobTillaart/HX711/tree/develop As the new version of set_gain() returns a bool to indicate valid value one can do if (HX.set_gain(64) == false) Serial.println("error"); else HX.read(); // dummy read tonly if a new valid value is set. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>
If you use a sensor that can handle e.g. 5x weight of a hive i expect little deformation. If you use the sensor at the max of its scale, to get highest resolution, chances for deformation are bigger.
Read a blog once about how to connect multiple loadcells to one HX to maximize resolution. Have no link sorry.
Alternatively you might use a hinge on one side an a loadcell on the other to scale the weight on the sensor.
https://www.hardysolutions.com/tenants/hardy/documents/5factorsa.pdf
interesting read, It states creep / deformation is a problem, so one might need a construct in which the bee hive is lifted most of the time and put down on the load cells for measurement.
@scboulogne think of adding wrapper functions for set_gain() that are more descriptive
bool set_chanA_gain128()
{
return set_gain(128);
}
bool set_chanA_gain64()
{
return set_gain(64);
}
bool set_chanB_gain32()
{
return set_gain(32);
}
furthermore I will add the dummy read() into set_gain() for convenience.
done
Another option is to define constants and use them in set_gain()
const uint8_t HX711_CHANNEL_A_GAIN_128 = 128;
const uint8_t HX711_CHANNEL_A_GAIN_64 = 64;
const uint8_t HX711_CHANNEL_B_GAIN_32 = 32;
mmm, think I like this one better as it is less an interface break.
Hello Rob, I have the thing wired and got it running the "classic" way (borrowing on your performance.ino from examples, but using just raw reads and their averages). Judging from the raw data, it seems to do reasonably within the body of my code (so it doesn't interfere with RTC interrupts, sleep mode, button interrupts, etc, and it shows reasonable raw data which change with weight). Too late for anything more now... I will calibrate it carefully tomorrow to make sure it really does work. And then I will test different channels. As for the code, I'd also prefer just defining constants. Makes smaller code. However, I would go even further.
I do not see the reason to have them stored as constants in the RAM, especially in the small fast Arduino data RAM. If you really need such things in RAM, though I do not see why, then you can at least push them to PROGMEM (on AVR). The only reason I can come with is if one calls set_gain with the same parameter in many different places across the code. Then having the parameter stored in RAM would save a bit of storage. But this seems to me an unlikely situation, and if it occurs, the programmer will take care of it, eg.
const PROGMEM uint8_t hx711_gain = HX711_CHANNEL_A_GAIN_128;
-----Original Message-----
From: Rob @.> To: RobTillaart @.> Cc: scboulogne @.>; Mention @.> Date: Friday, 4 November 2022 10:28 AM CET Subject: Re: [RobTillaart/HX711] Access to the B-channel of HX711 (Issue #27)
Another option is to define constants and use them in set_gain() const uint8_t HX711_CHANNEL_A_GAIN_128 = 128; const uint8_t HX711_CHANNEL_A_GAIN_64 = 64; const uint8_t HX711_CHANNEL_B_GAIN_32 = 32; mmm, think I like this one better as it is less an interface break. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>
@scboulogne
Thanks for testing (working on another lib right now)
The main reason I go for const uint8_t is that there is compile time type checking, the compiler will optimize it anyway. So it should not differ in size (not tried yet).
to be continued tomorrow.
I do not see the reason to have them stored as constants in the RAM, especially in the small fast Arduino data RAM.
Tested with one of the example sketches and both the #define and the const uint8_t version gave the same size and RAM usage. So I keep the extra type-check as the compiler solves it.
you are right about const vs #define, I have checked that too. makes no difference. unlike c, the cpp compiler is smart enough. I think that const does it. I have gotten the whole thing running today, see the calibration curve attached. It works similarly on all channels with the same slope coefficient (you call it scale) if, of course, the raw data are divided (normalized) on the gain used. So good news. Here are my current problems/observations:
-----Original Message-----
From: Rob @.> To: RobTillaart @.> Cc: scboulogne @.>; Mention @.> Date: Saturday, 5 November 2022 11:59 AM CET Subject: Re: [RobTillaart/HX711] Access to the B-channel of HX711 (Issue #27)
I do not see the reason to have them stored as constants in the RAM, especially in the small fast Arduino data RAM. Tested with one of the example sketches and both the #define and the const uint8_t version gave the same size and RAM usage. So I keep the extra type-check as the compiler solves it. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>
see the calibration curve attached.
Sorry I see no attachment
This sounds like a new issue to me, please open a separate issue for this as current one was primary to get channel B working. I am thinking in small steps instead of putting too much in one PR.
Yes it is slow due to a blocking interface ... it is mentioned in the code
float HX711::read()
{
// this BLOCKING wait takes most time...
while (digitalRead(_dataPin) == HIGH) yield();
also due to line 330 +336 to handle the T2 time robustly. You can try to remove them and see if that is better
uint8_t HX711::_shiftIn()
{
// local variables are faster.
uint8_t clk = _clockPin;
uint8_t data = _dataPin;
uint8_t value = 0;
uint8_t mask = 0x80;
while (mask > 0)
{
digitalWrite(clk, HIGH);
delayMicroseconds(1); // T2 >= 0.2 us <<<<<<<<<<<<<
if (digitalRead(data) == HIGH)
{
value |= mask;
}
digitalWrite(clk, LOW);
delayMicroseconds(1); // keep duty cycle ~50% <<<<<<<<<<<<<
mask >>= 1;
}
return value;
}
An alternative could be using a boolean flag to check if the delay is needed.
uint8_t HX711::_shiftIn()
{
// local variables are faster.
uint8_t clk = _clockPin;
uint8_t data = _dataPin;
uint8_t value = 0;
uint8_t mask = 0x80;
while (mask > 0)
{
digitalWrite(clk, HIGH);
if (_T2_flag) delayMicroseconds(1); // T2 >= 0.2 us <<<<<<<<<<<<<
if (digitalRead(data) == HIGH)
{
value |= mask;
}
digitalWrite(clk, LOW);
if (_T2_flag) delayMicroseconds(1); // keep duty cycle ~50% <<<<<<<<<<<<<
mask >>= 1;
}
return value;
}
Better option would be to use the "an asynchronous call" by testing bool is_ready() yourself. If not ready, do something else. if ready, read() will be fast too.
- The first point after the gain switch should be rather thrown away. You seem to imply this when you propose to make one dummy read() after set_gain. Ok it is good to know, but there's nothing in the hardware datasheet that hints to it.
It is in the protocol if I read correctly between the lines of the datasheet. This is my line of thinking: To set the gain, extra clock pulses (25-27) are needed to inform the HX711. Then the following read() will have the right gain and channel. However the only way to send those extra pulses is to use a read command. (OK a stripped version could do the job but would increase footprint)
you are right as usual. the datasheet (fig.2) sort of implies that the gain changing bits should follow the data exchange sequence and will apply for the next data output (they say Next). In my tests, I see that this works as expected. However, there are troubling variations:
// GAIN values: 128, 64 32 [20221105 all tested] // are defined above as CORE "CONSTANTS" -> read the datasheet void set_gain(uint8_t gain = 128) { if(_gain != gain){ if(gain) _gain = gain; // gain=0 "enforces" current _gain read(); // dummy read is required to set the new gain/channel // the gain/channel change requires 400ms (table on page 3) } };
while(!is_ready()); // read does that anyway?
read(); // one more dummy read, but why?!
This occurs after I read four times on channel A (128) and then switch to channel B. Looks like some strange timing issue.
-----Original Message-----
From: Rob @.> To: RobTillaart @.> Cc: scboulogne @.>; Mention @.> Date: Saturday, 5 November 2022 9:26 PM CET Subject: Re: [RobTillaart/HX711] Access to the B-channel of HX711 (Issue #27)
// GAIN values: 128, 64 32 [20221105 all tested]
// are defined above as CORE "CONSTANTS" -> read the datasheet
void set_gain(uint8_t gain = 128) {
if(_gain != gain){
if(gain) _gain = gain; // gain=0 "enforces" current _gain
read(); // dummy read is required to set the new gain/channel
// the gain/channel change requires 400ms (table on page 3)
}
};
I notice three differences with current code:
I will remove the test for the _gain == gain so you can enforce a refresh by calling set_gain() with a valid parameter again. No need then to introduce a zero parameter. makes it also clear what value we want to refresh.
The remark about the 400 ms is important, I will add that in the readme.md
- However, in one place in my code, repeatedly, this fails... and requires one more read like this
while(!is_ready()); // read does that anyway?
read(); // one more dummy read, but why?!
This occurs after I read four times on channel A (128) and then switch to channel B. Looks like some strange timing issue.
No clue yet. How fast do you change the channel?
- HX711 conserves whatever channel-gain it had if it is reset / mcu reboots (summarized) In this case, adding an extra read(); on begin(); may even hang infinitely as read() keeps waiting for is_ready() !!
If you know your sketch does call set_gain() somewhere, you as programmer must initialize the sensor properly in setup() as there is a chance that a reboot or watchdog reset or ... can happen leaving the hardware in an undefined state.
This is not different when I am using a DS18B20 temperature sensor and I put it to a different resolution to do quick measurements sometime and at other moments I want high resolution measurements. In such case I need to do my setup() correctly. Same is true for robotics / servo motors etc, all those devices should be set to a known position. Or the software should be able to read the status from the hardware.
So there will not be a forced read() in begin() as this is the responsibility of the programmer as stated above. This prevents a blocking loop scenario in the library code.
I will add a note in the readme.md in the set_gain() section.
Changes pushed to develop branch.
I am using an older lib 0.3.3 which I have downloaded from the link in your letter. there set_gain was still just void. For now this is for tests an I assume that the programmer knows what he is doing, so no checks for valid gain values. It is up to you to make changes to the lib I believe that set_gain should accomplish what its name promises, i.e. set the gain both as _gain AND in the hardware. Therefore the (at least one) dummy read belongs in there. On the other hand, if _gain has already the value asked, no dummy read() is needed. This saves 100ms.. However, I ran into the situation when all this doesn't work. Such as after a "hot" reset of the MCU, when _gain=128 does not necessarily correspond to the actual gain of HX117 an has to be enforced. I agree that asking gain=0 is awkward. So is an extra dummy read(); As I wrote, I have found no solution for the whole issue, because my (?) HX711 doesn't want to be reset. Same goes for the second dummy read(); I do not like it. But it works for me only that way
-----Original Message-----
From: Rob @.> To: RobTillaart @.> Cc: scboulogne @.>; Mention @.> Date: Sunday, 6 November 2022 3:46 PM CET Subject: Re: [RobTillaart/HX711] Access to the B-channel of HX711 (Issue #27)
// GAIN values: 128, 64 32 [20221105 all tested] // are defined above as CORE "CONSTANTS" -> read the datasheet void set_gain(uint8_t gain = 128) { if(_gain != gain){ if(gain) _gain = gain; // gain=0 "enforces" current _gain read(); // dummy read is required to set the new gain/channel // the gain/channel change requires 400ms (table on page 3) } }; I notice three differences with current code:
No clue yet. How fast do you change the channel?
I haven't printed that time. just the time to print a few things after previous read(). here is what I do
// 2022-11-05 on old Terraillon x4 load cells with HX711 A channel (128)
// linear calibration function Vraw/gain -> weght [g] int cell2weight(float Vraw, uint8_t gain) { return (int) round(HX711_SCALEVraw/gain + HX711_SHIFT); } / NB: when 5V VADD is used, the full-scale differential input voltage +/- is 20mV (64) or 40mV (128) on channel A, and 80mV (32) on channel B. After a reset or power-down, input selection defaults to channel A (128). NB: the raw ADC data is 24bit bipolar, so 32bit int will do */ HX711 myHX711; // differential amplifier (for load cells etc)
float sample_HX711(unsigned char cnt) { float w,t;
time_t elapse_timer = millis(); Serial.print(F("samples=")); Serial.print(cnt); Serial.print(F(" "));
myHX711.set_gain(HX711_WEIGHT_GAIN); // invoques a dummy read if required while(!myHX711.is_ready()); // read does that anyway?
Serial.print(F("0x")); Serial.print(myHX711.get_gain(),HEX); Serial.print(F(":")); Serial.print(millis() - elapse_timer); Serial.print(F("ms ")); elapse_timer = millis();
w = myHX711.read();
Serial.print(F("HX711 lib ")); Serial.print(HX711_LIB_VERSION); Serial.print(F(" "));
Serial.print(F("r="));
Serial.print((long int) floor(w)); Serial.print(F(" "));
Serial.print(cell2weight(w, HX711_WEIGHT_GAIN)); w = myHX711.read_average(cnt); Serial.print(F("g, avg ")); Serial.print((long int) round(w));
Serial.print(F(":")); Serial.print(millis() - elapse_timer); Serial.print(F("ms")); elapse_timer = millis();
Serial.print(F(" ")); Serial.print(cell2weight(w, HX711_WEIGHT_GAIN)); Serial.print(F("g")); myHX711.set_gain(HX711_THERMI_GAIN); // temperature reading (on channel B) // this works only if the following TWO lines are inserted here or in set_gain directly
// while(!is_ready()); // read does that anyway?
// read(); // one more dummy read, but why?!
// after this reads become regular and take about 100ms each ...
Serial.print(F(" 0x")); Serial.print(myHX711.get_gain(),HEX); Serial.print(F(":")); Serial.print(millis() - elapse_timer); Serial.print(F("ms")); elapse_timer = millis();
Serial.print(F(" t_avg ")); // (returns previous channel read) t = myHX711.read_average(cnt); Serial.print((long int) round(t));
Serial.print(F(":")); Serial.print(millis() - elapse_timer); Serial.print(F("ms")); elapse_timer = millis();
Serial.println();
return w;
}
I call this 4 times in setup() after begin(), and I can call it any time with a push button interrupt INT0 in the loop().
The two calls show different timings, it is kind of slow read() in the loop(), but I trust the setup sequence more, because in the loop() the MCU stays in POWER_DOWN sleep mode with all timers dead. RTC kicks it every second. And all this might not be very helpful for timing measurements via millis();
-----Original Message-----
From: Rob @.> To: RobTillaart @.> Cc: scboulogne @.>; Mention @.> Date: Sunday, 6 November 2022 3:54 PM CET Subject: Re: [RobTillaart/HX711] Access to the B-channel of HX711 (Issue #27)
Sorry This is the latest version (not yet merged into master) - https://github.com/RobTillaart/HX711/tree/develop
On the other hand, if _gain has already the value asked, no dummy read() is needed. This saves 100ms..
but you stated that sometimes set_gain() needed an extra read() so I assumed you meant that one read was not enough.
when _gain=128 does not necessarily correspond to the actual gain of HX117 an has to be enforced
That is why set_gain() should not test if the value is already set, it should just do a forced set.
So I implemented the following
bool HX711::set_gain(uint8_t gain, bool forced) // forced = default false
{
if ( (not forced) && (_gain == gain)) return true;
switch(gain)
{
case HX711_CHANNEL_B_GAIN_32:
case HX711_CHANNEL_A_GAIN_64:
case HX711_CHANNEL_A_GAIN_128:
_gain = gain;
read(); // next user read() is from right channel / gain
return true;
}
return false; // unchanged, but incorrect value.
}
... MCU stays in POWER_DOWN sleep mode with all timers dead. RTC kicks it every second. And all this might not be very helpful for timing measurements via millis();
Agree it is not helpfull
Another problem with time measurement is that you must add a delay(25); before starting a measurement. This allows the serial buffer to flush itself, so you won't get interrupts to print the next character anymore. (more output might need a bigger delay)
uint32_t start, stop;
...
delay(25);
start = millis();
do_the_action();
stop = millis();
Serial println(stop - start);
If you know your sketch does call set_gain() somewhere, you as programmer must initialize the sensor properly in setup() as there is a chance that a reboot or watchdog reset or ... can happen leaving the hardware in an undefined state. true. I do precisely that: after my begin(), I tried calling read(); to enforce the default gain (128) which I have on reboot as _gain; and this hangs for reasons which I cannot understand. No matter how long the delay is after begin() ... However, just a bit later, when I do read(), all works fine, albeit the first read is faulty, it has the wrong channel-gain. The thing is, you never know how many dummy reads are needed to make sure that your next read will be valid. as for the programming style, as I said earlier, I believe that set_gain and get_gain should be as close a s possible to what they announce. Otherwise, they are misleading: the programmer should have a look at your code and should realize that they simply deal with variable _gain which doesn't always reflect to the actual gain of HX711.
-----Original Message-----
From: Rob @.> To: RobTillaart @.> Cc: scboulogne @.>; Mention @.> Date: Sunday, 6 November 2022 4:06 PM CET Subject: Re: [RobTillaart/HX711] Access to the B-channel of HX711 (Issue #27)
Otherwise, they are misleading: the programmer should have a look at your code and should realize that they simply deal with variable _gain which doesn't always reflect to the actual gain of HX711.
What should those functions be called then?
try_to_set_the_gain_and_channel_but_not_sure_it_works_always() 😂
First thing a programmer has to look at (carefully) is the data sheet of the HX711. Then she or he knows that the device cannot report its gain. Using a library without reading (a bit of ) the datasheet is opportunistic (yes I do it all the time too)
No matter how long the delay is after begin() ... However, just a bit later, when I do read(), all works fine, albeit the first read is faulty, it has the wrong channel-gain. The thing is, you never know how many dummy reads are needed to make sure that your next read will be valid.
I will reread the datasheet (again) to see if there is some information between the lines..
bug in datasheet
The only way I can see from the datasheet to do that is by cycling power_down(); for 60us and then power_up();. It says that this resets HX711 to A-128. Well, it doesn't.
OK, you tried that.
well, right. I do not know how to call set_gain and get_gain. you get the point. leave them like they are and tell their sad story in the readme.md. set_gain has now some sense in it. but doesn't always work... get_gain is just a cpp gadget to get to the value of the private variable. at the end, it seems that we will have to say what we know that works and admit in the readme.md that we have no complete solution to this two-channel gain thing.
-----Original Message-----
From: Rob @.> To: RobTillaart @.> Cc: scboulogne @.>; Mention @.> Date: Sunday, 6 November 2022 5:19 PM CET Subject: Re: [RobTillaart/HX711] Access to the B-channel of HX711 (Issue #27)
First thing a programmer has to look at (carefully) is the data sheet of the HX711. Then she or he knows that the device cannot report its gain. Using a library without reading (a bit of ) the datasheet is opportunistic (yes I do it all the time too) — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>
mmm, found a possible problem
void HX711::power_down()
{
digitalWrite(_clockPin, LOW);
digitalWrite(_clockPin, HIGH);
}
it does not guarantee the 60 us...
mmm, found a possible problem void HX711::power_down() { digitalWrite(_clockPin, LOW); digitalWrite(_clockPin, HIGH); } it does not guarantee the 60 us...
I have tried that already but it made no effect and I didn't want bothering you As I said, I have no other indicator of whether it powers down or not but for the gain that is meant to come back to 128 and it doesn't this is what I tried to use (to no awail)
// from datasheet p.5: When PD_SCK pin changes from low to high and stays at
// high for longer than 60us (fig.3), HX711 enters power down mode
// (and it remains in power down mode while PD_SCK is high)
void HX711::power_down()
{
if(!digitalRead(_clockPin)) {
delayMicroseconds(1); // T1 >= 0.1 us, just in case
digitalWrite(_clockPin, HIGH);
};
delayMicroseconds(64); // wait until power down >= 60 us
// After a reset or power-down event,
// input selection defaults to Channel A with a gain of 128
// test 20221106: THIS DOESN'T SEEM TO WORK, AS GAIN IS NOT RESTORED TO 128
_gain = 128;
}
// When PD_SCK returns to low, chip will reset and enter normal operation mode.
void HX711::power_up()
{
if(digitalRead(_clockPin)) digitalWrite(_clockPin, LOW);
delayMicroseconds(1); // T1 >= 0.1 us, just in case
}
-----Original Message-----
From: Rob @.> To: RobTillaart @.> Cc: scboulogne @.>; Mention @.> Date: Sunday, 6 November 2022 5:49 PM CET Subject: Re: [RobTillaart/HX711] Access to the B-channel of HX711 (Issue #27)
mmm, found a possible problem void HX711::power_down() { digitalWrite(_clockPin, LOW); digitalWrite(_clockPin, HIGH); } it does not guarantee the 60 us... — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>
since set_gain() with one dummy read() was working "not always", I have also added small delays into your gain setting loop in read(), meaning that it might not get this sequence all the times (the data exchange is different, there is some work done on shifting registers and some explicit usec delays added in_shiftIn , here there was no time at all)
delayMicroseconds(1); // typical T1 >= 0.1 us
while (m-- > 0)
{
digitalWrite(_clockPin, HIGH);
delayMicroseconds(1); // typical T3 >= 0.2 us
digitalWrite(_clockPin, LOW);
delayMicroseconds(1); // typical T4 >= 0.2 us
}
so it kind of reproduces better their timing diagram. helas, to no awail either
-----Original Message-----
From: Rob @.> To: RobTillaart @.> Cc: scboulogne @.>; Mention @.> Date: Sunday, 6 November 2022 5:49 PM CET Subject: Re: [RobTillaart/HX711] Access to the B-channel of HX711 (Issue #27)
mmm, found a possible problem void HX711::power_down() { digitalWrite(_clockPin, LOW); digitalWrite(_clockPin, HIGH); } it does not guarantee the 60 us... — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>
delayMicroseconds(1); // typical T1 >= 0.1 us ...
Think these should be conditional for very fast digitalWrite() processors e.g. ESP32 @240 MHZ For now I will not change it as the selecting does work.
// After a reset or power-down event, // input selection defaults to Channel A with a gain of 128 // test 20221106: THIS DOESN'T SEEM TO WORK, AS GAIN IS NOT RESTORED TO 128 _gain = 128; }
as it does not work, I will not add the _gain = 128 line.
It is a pity I have no hardware setup at the moment (to busy with other libraries too) so I could test with another board. does your board looks like
@scboulogne I am going to do a last build today, and if tomorrow there are no new insights I will merge the develop branch.
mine is very much like the 3rd card on your list, and is even called very similarly XFW-HX711 I am frustrated with the bias issue (today it drifted from +50g to -450g during the afternoon) and am tempted to try the sparkfun one (like the 1st on your list). Maybe they do a better breakout job at sparkfun. Their card has a jumper for 80Hz rate and also dual supply Vcc and Vdd which can be used with 3.3V MCU. However, they have no 2nd channel. I think that we have covered the original question, which I have asked in this thread: can one use other gains? The answer is yes, but at a cost of 400ms waiting and a bit of pain with dummy read()'s, reboot etc. Too bad, we couldn't get to the bottom of it all. I will probably have to put a stop here, because I have a lot of teaching and work coming and won't be able to concentrate on this. Besides, I have to think calmly of it all wrt my project, for which using or not channel B is a minor issue. btw. the reason why they use 24-bit adc in a bathroom scale (!) is the requirement to weigh 80kg to smth like 1g resolution.
-----Original Message-----
From: Rob @.> To: RobTillaart @.> Cc: scboulogne @.>; Mention @.> Date: Sunday, 6 November 2022 7:44 PM CET Subject: Re: [RobTillaart/HX711] Access to the B-channel of HX711 (Issue #27)
// After a reset or power-down event, // input selection defaults to Channel A with a gain of 128 // test 20221106: THIS DOESN'T SEEM TO WORK, AS GAIN IS NOT RESTORED TO 128 _gain = 128; } as it does not work, I will not add the _gain = 128 line. It is a pity I have no hardware setup at the moment (to busy with other libraries too) so I could test with another board. does your board looks like
The drift is a loadcell issue, not a library one. Have seen profi loadcells selling for above €100. Where the hobby market they are 10x less. Alibaba might even be cheaper. So I expect differences in quality too.
I have looked at the library Sparkfun is offering, but it gives no clue either. (It is a copy of Bigdes HX lib).
An option might be to mail the manufacturer?
well, just to let you know. As I suspected, it appears to have nothing to do with cells but a lot with the card I'm using. Possibly, but very unlikely, also with the power supply (it is 5V from usb and it should have enough for the step down voltage stabilizer of the card to take care of the noise). The test is simple: replace those cells with four 1K resistors in a Wheatstone bridge. You cannot blame those for whatever instability... The thing should basically measure 0, or a few Ohms due to resistors' 1% error tolerance. Take a few samples (may change polarity if you like positive numbers), compute the average and the r.m.s. error sigma, estimate peak-to-peak as 6*sigma, and obtain effective noise-free bit resolution of the ADC. Guess what I have on eight pre-averaged 4-samples? 10-12 bits noise free! Out of a 24bit setup? The card is total garbage.
-----Original Message-----
From: Rob @.> To: RobTillaart @.> Cc: scboulogne @.>; Mention @.> Date: Sunday, 6 November 2022 9:55 PM CET Subject: Re: [RobTillaart/HX711] Access to the B-channel of HX711 (Issue #27)
The drift is a loadcell issue, not a library one. Have seen profi loadcells selling for above €100. Where the hobby market they are 10x less. Alibaba might even be cheaper. So I expect differences in quality too. I have looked at the library Sparkfun is offering, but it gives no clue either. (It is a copy of Bigdes HX lib). An option might be to mail the manufacturer? — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>
@scboulogne That is indeed a very good test to see if the cells or the card is to blame. Could you wrap this in an analytic sketch?
@scboulogne I am going to merge the develop branch as in essence the issue is solved (datasheet wise in theory) IF there are new insight or other problems please open a new issue.
Thanks for your testing!
HX711 has a 1:2 mux permitting to switch between two input channels, channel A used in this library and B, which is not used. It would be nice to gain access to channel B of HX711. True, it has fixed gain and is not equivalent to A, but it might come handy to measure additional data, such as thermistor voltage (to control temperature as mentioned in the readme), or differential pressure meter.