Closed dsafak closed 2 years ago
Hi there! Hmm, not sure what you mean by "free-running mode"? The HX711 should hold the data after DOUT goes low, and it should not start a new conversion before the current conversion has been clocked out with 25 SCK pulses. For example, if you have some time consuming code in your sketch the conversions should still read out correctly, but the sample rate (SPS) will of course go down. So there isn't any limited "read window" that I know of. This is also indicated in the data sheet, as T1 (the first "DOUT falling edge to PD_SCK rising edge") don't seem to have an upper time limit.
If I remember correctly you don't have an oscilloscope available to check the actual communication? Would have been interresting to see though...
Regardless, if you want to read out the conversion asap after it's ready I don't think that there is any other way then using interrupt on DOUT.
As far as I know it is not in data-sheet but HX711 is not holding the data till its read at least at at rate = 1. I remember reading it somewhere too but I'll check again.
By free-running I mean that, it continuously convert and doesn't wait for it to be read. check this out: https://github.com/bogde/HX711/issues/35#issuecomment-246322798
Further thinking upon this, I realized in this library (HX711_ADC), we only start reading when DOUT goes low, and it is synchronus reads right after that, so this couldn't be free running related as long as I do not miss timing between SCK HIGH and LOW clocks to read data.
There is a long explaination if anyone stumbles upon this, I'll try my best:
It turns out there is an interrupt in my code used by a library (unrelated so I am not going deep into detail on the library) which is triggering an ISR, while the HX711 Data Reading is in progress (conversion24bits method).
ISRs timing is breaking the (delaying conversion24bits method in middle of execution) so the data was getting corrupted.
Probaby because hx711 is in free running mode at 80hz. So this happens: DOUT = LOW Conversion24bits Runs 10 times (10-11-12 this is hyptotetical state of conversion24bits loop state) Interrupt Triggered from another source, ISR enters HX711 starts converting new data, SCK HIGH ISR ends, code is back to Conversion24bits and continues from 11th loop SCK HIGH, LOW doesn't matter next reading bits are all wrong.
@olkal you already knew this so there is an interrupt define in config. I already knew this as well but, I made a typo at some point, so interrupts were not disabled.
Leaving this issue aside, it is solved, this time it wasn't related to timing issue caused by hx711 but ISR:
I still come up with a way to make conversion exactly after DOUT goes low when we are observing and expecting it. Because of free-running mode (assuming it exists) there is still potential for a timing issue.
I believe, I bumped into it couple of times and had to fiddle with delays to get it right in past. But maybe Free-running mode is not a thing, and my past problems were also related to another problem.
so I thought, This issue (The one I just solved) was related to missing timings because of Free running mode, but it wasn't, I just expected it to be related to free-running mode.
Anyway, Here is what I come up with:
inside update() method, at the top, we put this:
#if defined WaitForNextReading
while(!digitalRead(doutPin));
while(digitalRead(doutPin));
#endif
This is a blocking method but it should transfer the idea behind this. Case: We have 3 cells, they are running in free-running mode, WaitForNextReading is UN-defined Our main loop is running { We enter 1stCell's update() method. If DOUT == LOW else olddata returns conversion24bit(); getData(); We enter 3rdCell's update() method, If DOUT == LOW conversion24bit(); getData(); We enter 3rdCell's update() method, If DOUT == LOW conversion24bit(); getData(); } When did DOUT for all 3 loadcell's become LOW? We do not know. When can DOUT for all 3 loadcell's potentially go HIGH again? we do not know. (Free-running mode)
WaitForNextReading is DEFINED Our main loop is running { We enter 1stCell's update() method While DOUT == LOW, wait. While DOUT == HIGH Wait. If DOUT == LOW conversion24bit(); getData(); ... } This way we make sure We are reading exactly after a conversion is complete and ready to be read. I see this as a somewhat fail-safe guard.
If we could confirm the free-running mode @ rate = 1, Everything I wrote above would start making more sense. So the code above is either useless, or it is not. Depends on HX711's behaviour.
Here: https://github.com/bogde/HX711/issues/35 There is couple of mentions about this, and seems pretty confirmed.
I know this is a long post, but I tried to explain what is going on, and What I think is going on, the best way I could.
Hi So you're saying that @80hz the HX711 starts the next conversions by itself even if you're not done clocking out the data? If this is true, I didn't know that! (I have mostly used it @10hz myself). That would be a rather serious flaw in the HX711 chip I think.
I don't like while() loops much, and you would of course miss the DOUT going low on your other two HX711 while waiting for the first to go low. But I understand that you have it working without this while() loops now that you fixed the disable interrupt code in conversion24bit(), correct?
Hi did some testing with HX711 at 80hz now:
Using the library example file Read_1x_load_cell.ino
. This example sketch does only read out the data every 250ms there is a delay from the DOUT goes low to the data is clocked out as it is. Nevertheless the readout value is consistent, and no corrupted data during my 5min test. Based on this, I don't think there is such a thing as a non-documented "free-running mode". Your problem was probably caused alone by the un-related ISR triggering, don't you think?
Edit: My test doesn't proove anything as the LoadCell.update()
is still called without any delay.
Hi, Yeah I fixed my problem by fixing typo with interrupts disable flag, I already knew about it, and I thought I already disabled interrupts but the there was a typo. So the issue I had is gone. But that led me into this free-running loop-hole and that ugly while loops (which I don't like as much as you do) and I am aware of its flaws.
But I knew this free-running mode thing way back, I never paid huge-attention because whenever I had a timing issue, I just made the code run faster, and it was gone.
I think matouchat790te from other hx711 library's thread where he/she reporting they noticed undocumented free-running mode is onto something, or maybe different undocumented revisions of hx711s?. Clones?
I'll try this: I'll try to apply dynamic load (static load will return same bits, so can't notice a jump in values) Calculate how long single conversion24bit() takes exactly. Time the start myself so I know my T0. Stop conversion at T1 midway. Wait till known conversion24bit() time is over. Wait conversion24bit() / 2 time more. Continue reading from hx711.
if I see an unexpected jump / value / error, we can be sure it is free running, if not, it is no such thing as free-running @ 80hz. I'll try to get my hands on an oscilloscope, at this point I should buy one already...
My issue is solved but I would like to contribute
Hi, the HX711 device specs (Avia Semiconductor) are very vague on the exact communication protocol: what triggers a next ADC conversion, does it wait until read before starting a conversion, does it continuously convert at a 80sps rate? The only meaningless clue I could read in the datasheet: "The 25th pulse at PD_SCK input will pull DOUT pin back to high" - on which one might assume it will start a new conversion. You could try to contact Avia for exact details: sales@aviaic.com
I have looked at the data sheet for ADS1231, a chip that is not identical but in many ways similar to the HX711 (this library also work with ADS1231). From the ADS1231 datasheet it seems to be indeed "free-running", meaning that it does conversions continuously, and the register data is updated in a "no-read" window of 90us just before the DOUT goes low. The "no-read" period is labeled tupdate in the ADS1231 datasheet. I think we should be able to test if this is the same for HX711 as well.
@JM-DfT: yes, the HX711 datasheet is not good, but looking at Avia's website I don't have much hope of getting more detailed information out of them.
I have done more testing and found some interresting things indicating I was a bit wrong about how the HX711 actually works... The conversions seems indeed to be going on continiously both at 10SPS and 80SPS. At the end of each conversion the DOUT pin goes high for about 75µs before it is pulled low. Assuming that there is some similarity between HX711 and ADS1231 this should be the "tupdate" or "no read" period used for updating the data register before starting next conversion.
But it's not entirely correct to call it a "free-running mode" as it's not a mode at all, the behaviour is the same regardless of 10SPS/80SPS setting. It's just that at 80SPS it's 8 times more likely to accidentally read out data during the "no-read" period.
See results below, just measuring the DOUT pin, no data reading:
<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40">
Numbers measured with Arduino Due | HX711 LOW internal osc. | HX711 HIGH internal osc. | HX711 LOW 20mhz crystal | HX711 HIGH 20mhz crystal -- | -- | -- | -- | -- DOUT low time | 85560µs ±20µs | 10627µs ±20µs | 55243µs ±1µs | 6863µs ±1µs DOUT high time ("no-read" period) | 75µs ±1µs | 75µs ±1µs | 48µs | 48µs Conversion time | 85635µs ±20µs | 10702µs ±20µs | 55291µs ±1µs | 6911µs ±1µs
Hi, This is more of a question then an issue but the issue page should be fine for this. Case: Using 3xhx711s at 80hz with 32u4 and some custom port manipulation code to make it quick enough to make it work on 32u4. Result: All works fine with the magic micros(1); delay on conversion24bits method with SCK_DELAY enabled, which takes about 12 cycles so 12*62.4ns. Problem: I moved my code to use another USB stack now I encounter reading errors on 1 out of 3 hx711s here and there. HX711 sets DOUT to "LOW" when data is ready, but it is in free-running mode, so it doesn't hold data till it is read. so when the read window is missed, the pin goes High for the rest of the conversion. Cause: I am unable to hit the magic read timing on 3xhx711s now and one misses time to time. Even if I try inserting delays from 3 Nops to 12 Nops (1 nop = 62.5ns).
I know it is timing related after spending hours on both hx711 and cs1237. It is timing, interrupts something with the new USB Stack / Project braking into calculations and missing the hx711 data read window.
Solution: Using hardware interrupts to enter ISR the moment one of the 3 says data is ready to read. Problem with this solution: Only one interrupt can be served at a time so other 2 might miss, might not miss. (probably won't miss needs testing but I need a new PCB for this so I can use hardware interrupt pins).
Question: Is there any better or other way to make sure that, Code is not going to miss the hx711 read window?