Adafruit_CircuitPython_DHT: Unable to set line 4 to input
I’m trying to make a Raspberry Pi 3 REST API that provides temperature and humidity with DHT22. The whole code:
from flask import Flask, jsonify, request
from sds011 import SDS011
from adafruit_dht import DHT22
import board
import os
import time
app = Flask(__name__)
dht = DHT22(board.D4)
def get_dht_data():
while True:
try:
temperature, humidity = dht.temperature, dht.humidity
print(temperature, humidity)
if temperature is not None and humidity is not None:
return temperature, humidity
else:
raise
except:
time.sleep(0.5)
@app.route('/', methods=['GET'])
def status():
temperature, humidity = get_dht_data()
return jsonify({
'temperature': temperature,
'humidity': humidity
})
if __name__ == '__main__':
app.run(debug=True)
However, when I start server, it shows message
Unable to set line 4 to input
and temperature and humidity is always None. If I don’t run flask app but just DHT code, it works.
About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 2
- Comments: 46 (2 by maintainers)
…it seems to work fine when I first boot up the raspberry pi and I can run the test code once and it works… After that if I try to run to the test code a second time I get the same error…
Not even using Flask - just this script, is enough to make the RPI4 hang:
Their old library worked for me. https://github.com/adafruit/Adafruit_Python_DHT
try killing any ‘libgpiod_pulsein’ processes
The solution that I found was:
dhtDevice = adafruit_dht.DHT22(board.D4, use_pulseio=False)
Acording to the group comments, this declaration
use_pulseio=False
disable the PulseIn functionality.In my case, a program executes a python script parallels. I got same error from this simple example.
dht_simpletest.py
means below. https://github.com/adafruit/Adafruit_CircuitPython_DHT/blob/master/examples/dht_simpletest.pypulseio
does not work for my situation. So I changed code like below.It works for me.
First of all, if you don’t have the
pulseio
module available (for whatever reason),adafruit_dht
will use BitBanging and this bug will not appear.I’m also affected by this bug as my temperature logger script (5min cronjob) suddenly stopped working after 23 hours, so I did some analysis:
Following the string
The output string
Unable to set line X to input
is generated by the executablelibgpiod_pulsein
atadafruit/libgpiod_pulsein:/src/libgpiod_pulsein.c#L237-L241.
This executable is called in
PulseIn.__init__()
byself._process = subprocess.Popen(cmd)
adafruit/Adafruit_Blinka:/src/adafruit_blinka/microcontroller/bcm283x/pulseio/PulseIn.py#L65PulseIn ?
A quick look into PulseIn.py reveals that
PulseIn
provides the__enter__()
and__exit__()
functions in order to be used as a context manager using thewith
statement.PulseIn usage in adafruit_dht
As
adafruit_dht
is not usingPulseIn
as a context manager, I guess it should implement the functionality of__exit__()
itself by callingPulseIn.deinit()
at the approriate moment (e.g. inDHTBase.__exit__()
? This would ensure that there is no long-runninglibgpiod_pulsein
process left behind after the python script exited.Best wishes, kerel
PS:
adafruit/Adafruit_CircuitPython_DHT:adafruit_dht.py#L66-L67 Now I’m not sure if the running process was maybe intentional (but I can’t see why this would be a good idea…)?
Did you enabled 1-wire interface when using GPIO4? Try disable 1-wire interface from raspi-config when using gpio4 with adafruit python lib.
Reverted to the old lib just now, that one’s working a treat.
Yeah it is happening even to their sample code. Just try to run the code. Stop it. They run it again. On May 3, 2020, 7:50 AM +0530, Alexandre Lemaire notifications@github.com, wrote:
Thank you, ropering! I cannot try it now, but will soon. In the meantime, I have found a workaround, which I will resort asap.
it works for me
It works for me to. But I don’t know why.
I didn’t see the PR, thanks. The
dhtDevice.exit()
method solved the issue.So this is a super hacky work around to this problem, all I’ve done is force an ImportError when the adafruit_dht.py script attempts to import PulseIn. Once it fails to import PulseIn it will attempt to use bitbang instead, this works for me but I guess it depends on your specific use case whether or not it will work for you
Anyway, I modified line 37 in the adafruit_dht.py file located in dist-packages (remember to sudo here as this file is protected). I changed “from pulseio import PulseIn” to “from pulseio import PulseIn1” this then causes an ImportError and then PulseIo is not used which means the pin won’t be blocked after exiting the code
As I said, it’s hacky but for now it’s a work around to this problem
I tried using the old repo but for some strange reason it wouldn’t work on my RPi 4, it kept trying to run the BeagleBone code which obviously does not work.
Hopefully the Adafruit team can solve this properly in a future release
Short answer
Remove
debug=True
and enjoy. 😃What was going on?
This problem drove me nuts but I think I found the root cause! In my case, I was encapsulating the DHT22 object in another object, like so:
My
main.py
looked like:And look what an interesting output I got:
The MainThread was initializing my object twice! How was that? Well, if you look at the documentation of Flask’s
run()
, you’ll see the following:So, it seems that Flask just relaunches the application or something like this. Not clear to me, to be honest. But well, if you just remove
debug
, you’ll see something like:I hope this helps. Happy coding!