pimoroni / automation-hat

Python library and examples for the Pimoroni Automation HAT, pHAT and HAT Mini
https://shop.pimoroni.com/products/automation-hat
MIT License
122 stars 41 forks source link

ADC reads incorrect values randomly. #16

Closed piplup1222 closed 6 years ago

piplup1222 commented 6 years ago

I am doing a project for the company I work for to monitor when our shop doors are locked as well as collect temperature data. There is a prox sensor in each of the doors that monitors when the dead bolts are locked. They are 24V prox sensors that run 24V to their respective inputs on that hat when the door is locked. I have four doors, three of which are connected to the digital input and the fourth is connected to the first input of the ADC. The temperature reading is connected to the second ADC input. I created a threshold for the temperature to cure its random spikes and dips from the misreading of the hat, but ultimately cannot do the same for the door that is connected to the first ADC input. I have read different threads about how the LED is what is causing the issue, but I don't even power an LED in my code and it still doesn't work properly. I have attached an image of the graph of 48-hours of a door that has been locked the entire time that is never used. I have also attached an image of my python code.

python code image

door plot image

Gadgetoid commented 6 years ago

Regardless of whether you change the LEDs or not, the current Automation HAT library sets up a thread to keep them updated with the status of inputs/outputs.

The LEDs are attached to an i2c device and I believe having two threads accessing i2c simultaneously is causing a race condition/conflict whereby the response from one devices is misdirected to the other.

Among other changes, I'm currently rewriting the way this works to a use single thread and run the lights in lock-step with the ADC polling to avoid this problem.

Gadgetoid commented 6 years ago

This is - hopefully- fixed in 0.1.0, give it a try and let me know: https://github.com/pimoroni/automation-hat/releases/tag/v0.1.0

brvier commented 6 years ago

Unfortunatly i siill have the same problem in 0.1.0 while i didn t have with 0.0.4

this simple code show the error quickly

import automationhat
while(True):
    v = automationhat.analog.one.read()
    if a>1:
        print(a)

The adc one is wired to gnd. and quickly less than 3 seconds it s read value between 4.5 and 4.9

truher commented 6 years ago

i'm seeing the same thing. could we reopen this issue? wire adc one to 5v (the example in the doc), see mostly 5v but many readings near zero, or near 4v.

[edited]

ah, it's the "autolights" feature that screws this up. turning autolights off fixes it:

automationhat.enable_auto_lights(False)

yay!

Gadgetoid commented 6 years ago

The refactor of the way auto lights and the ADC reads co-exist should have fixed this problem- I'm going to have to investigate further. Have re-opened this issue accordingly.

Gadgetoid commented 6 years ago

The bug is caused by interleaving threads. A classic race condition. My efforts to solve it were largely in vain because I wasn't fixing the right problem.

While it's not possible to trigger two consecutive ADC integrations, I believe what's happening is that the first integration (the process of converting an analog value into a digital one) is finishing, and then being overwritten by a subsequent integration trigger just before the first thread reads out the value. This causes an invalid value to be read occasionally (when the planets align).

I think I've found a proper fix for this that uses the status register to ensure no value is read when a conversion is ongoing. This may cause some readings to be delayed fractionally if the clobbering occurs, but should ensure their accuracy.

As suggested above by @truher if you're not using the fancy LED lighting effects, it's best to disable them altogether with automationhat.enable_auto_lights(False). This way the LED lighting routine wont ever clobber your readings.

Use threads problems you've got now two!

ijustwant commented 5 years ago

i'm seeing the same thing. could we reopen this issue? wire adc one to 5v (the example in the doc), see mostly 5v but many readings near zero, or near 4v.

[edited]

ah, it's the "autolights" feature that screws this up. turning autolights off fixes it:

automationhat.enable_auto_lights(False)

yay!

That fixed the problem for me as well :)

premier-boats commented 5 years ago

The fix to spurious voltage readings on the ADC channels seems to be working. With 0.1.0 of the automationhat library (fetched with apt-get) on node red, using @shortbloke's https://github.com/shortbloke/node-red-contrib-automation-hat, I was getting phantom readings to the analog inputs unless I disabled auto-lights.

Installing the automationhat library from by cloning from github, those readings are gone, so I no longer have to disable auto-lights. Though the library version still reads as 0.1.0. I'm wondering if there's plans for a release with this and other fixes over the last year so I can use this on my production system without a "cutting edge" patch to keep things reliable.