tatobari / hx711py

HX711 Python Library for Raspberry Pi.
Apache License 2.0
206 stars 154 forks source link

Faster sampling rate #39

Open PAmerikanos opened 3 years ago

PAmerikanos commented 3 years ago

Hello, Is there a way to make it sample data faster than ~1Hz? Thanks

carlosbarilatti commented 3 years ago

Yes! HX711 delivers 10 samples per second or 80 samples per second with less precision, depending on how the IC is implemented on the PCB. The typical small green HX711 breakout and Sparkfun's breakout are both configured for 10 SPS.

However, this library is pretty inefficient and currently takes a lot of time to read the value once, around a second. I'm planning on improving that.

PAmerikanos commented 3 years ago

Thanks for the quick reply. Is there something I could do right now to improve this, like a small code tweak, or is it only dependent on the IC? I'd be happy even with just 2sps.

tatobari commented 3 years ago

Any chance you could post your code?

On Sat, Feb 27, 2021, 13:53 PAmerikanos notifications@github.com wrote:

Thanks for the quick reply. Is there something I could do right now to improve this, like a small code tweak, or is it only dependent on the IC? I'd be happy even with just 2sps.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/tatobari/hx711py/issues/39#issuecomment-787101635, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABVNTWNSU7HOFTJSO4QA54TTBEPR5ANCNFSM4YJVFI7A .

PAmerikanos commented 3 years ago

I'm just running the example.py script. What I tried to do was lower the sleep function durations, but found out they were not the cause of the slow rate. I also had added a write to file method, but I don't think it's so demanding.

caseypen commented 3 years ago

Thanks for your code bundling up, Tatobari. I think the reading rate is correct if you set the median filter window size as 1 (the parameter of "get_weight"), the reading time is around 100ms (10HZ). If you want to have a higher sample rate, try to short the 15 pin to VDD on your HX711, then the sample rate will be 80 Hz but with a larger noise output. Most Hx711 boards have the option of choosing the sample rate with a jumper. The only defection is the waiting time of data ready is not very stable, sometime it will wait over 500ms. You may want to set a timer to jump out of the while if the time reaches to have the running time of measuring function is stable.

Hope it helps

PAmerikanos commented 3 years ago

Hi all, thanks for your time. For unrelated reasons I replaced my RaspberryPi B+ with a RaspberryPi 3B, which dramatically improved performance. The sampling became faster (did not bother measuring how fast it is right now), but, more importantly, its sampling period stabilized and any spikes or noise have ceased. I am very satisfied with its current performance, just by changing to a newer device model.

caseypen commented 3 years ago

Thanks for posting it. I used this code on Rpi-Zero. It also happens for some spikes and noise. The median filter applied can filter out most of them though.

FrancescoNegri commented 3 years ago

Yes! HX711 delivers 10 samples per second or 80 samples per second with less precision, depending on how the IC is implemented on the PCB. The typical small green HX711 breakout and Sparkfun's breakout are both configured for 10 SPS.

However, this library is pretty inefficient and currently takes a lot of time to read the value once, around a second. I'm planning on improving that.

Hi! I was wondering if anyone succeded in increasing the reading speed for one sample! :)

PAmerikanos commented 3 years ago

Yes! HX711 delivers 10 samples per second or 80 samples per second with less precision, depending on how the IC is implemented on the PCB. The typical small green HX711 breakout and Sparkfun's breakout are both configured for 10 SPS. However, this library is pretty inefficient and currently takes a lot of time to read the value once, around a second. I'm planning on improving that.

Hi! I was wondering if anyone succeded in increasing the reading speed for one sample! :)

I'm not sure I understand? You mean to increase the sampling speed from 10Hz to 80Hz, increase the sampling speed to reach the previous numbers, or shorting the sensor reading speed/window for each sample?

FrancescoNegri commented 3 years ago

I just read that this library is not super efficient when it comes to make the measurement from the pins connected to the HX711 sensor, thus I was wondering if someone succeeded in enhancing the performance. However, I managed to obtain 80Hz with a precise sampling time, avoiding spikes and error employing a moving median filter while measuring to limited-size batches of data. I build that solution on the top of another HX711 library.

tatobari commented 3 years ago

Sample Rate

HX711 sample rate will depend on how the IC is implemented on the board. According to the datasheet, pin 15 must be HIGH for 80 SPS (samples per second, aka, Hz), otherwise the rate is 10 SPS.

image

image

Library Performance

It should work pretty fast, not having problems achieve 10 SPS (not sure with 80 SPS because there are a few unnecessary sleep functions product of me not knowing anything about electronics back then, I know a bit more now). I wonder if the problem is related to the readlock to prevent other threads from accesing the ports while the library is reading them (self.readLock.acquire() and self.readLock.release()).

It's been a while since I last tested this library. I did it for a prototype and them moved to Arduino. But I will test and get back to you.

tatobari commented 3 years ago

I've bought a PI 4 B 8GB (amazing device) and tested the code. Well, yes, the library is pretty inefficient because the implementation is not quite the best. Long story short, I only managed to improve it to make two or three readings per second, but that's not a lot. The modifications I made to my local copy of the code were:

  1. Commented time.sleep(0.1), hx.power_up() and hx.power_down() from the loop on the example.py code. I guess that's the biggest change.
  2. Just for the sake of it I also commented self.readLock.acquire() and self.readLock.release() from the code and run the setup again, but I don't think that made much of a difference.

There are two factors that add time to the value reading. First of all, Raspberry is a full CPU and the code runs on Python, on Linux, which is not quite the best option for real-time applications such as this one because the multitask functionalities and garbage collectors might make use of the CPU at anytime, postponing the tasks the code is running. For realtime and really fast applications, and Arduino or any other MCU is probably the best option.

But, my guess is that the factor that most contributes to the long reading time is that the HX711 makes you wait while it reads the value. Very briefly, the HX711 holds the DOUT pin HIGH while the it is reading the voltage and drives the DOUT pin to LOW when it's ready to output the value. So, when hx.get_weight() is run, the code might have to wait for a couple ms until the HX711 is ready to deliver the data.

I had the same problem on Arduino and I solved it by using interruptions and it worked like a charm, extremely fast at 10SPS. 80SPS is way more than necessary and reduces the precision. The interruptions based implementation can also be done on Raspberry and Python. The implementation should be such that everytime the DOUT pin goes from HIGH to LOW, the code reads the value no matter what, and stores the received value in memory so that the get_weight() method has direct access to the latest value stored in memory. Many values can be stored to use some math to get a more precise value.

I might work on it but I'm not sure if I can. Got a new job with a lot to learn and I barely managed to quickly write this comment while having lunch. Anyone interested in submitting a PR with this implementation will be welcomed.

caseypen commented 3 years ago

Hi all,

Thanks for your contribution to this repo, Tatobari. I cannot agree more with your analysis, as it is exactly the same as what I found. I recently modified and applied the code in my project from pigpio. They used an interrupt method to detect the DOUT pin and read the values. It works like a charm.... I can create a pull request when available. But it should be very easy to keep it work with the same interface you defined. You can probably have a trial yourself.

Thanks,

Chen

PAmerikanos commented 3 years ago

Tatobari, thank you for the great analysis. Good luck at your new position!

tatobari commented 3 years ago

@caseypen thanks! Gonna take a look at your implementation.