4

I have a DHT22 connected to my raspberry pi 4 model B, connected like this: enter image description here

And I wrote a small script for the raspberry pi that is supposed to get the temperature and the humidity. I made this script available through the ip address of my local network. To do so, I've used two libraries in an attempt to figure out the error: Flask and Jaymon/Endpoints.

When running the script locally, everything works great. When I call the endpoint using Postman, I get the temperature and humidity, just as expected. However, when I call the same endpoint a second time I receive the following error:

RuntimeError: Timed out waiting for PulseIn message. Make sure libgpiod is installed.

When this happens, I need to reboot the webserver and it starts all over again: I can call the api once with correct results, and it fails on the second attempt.

Here's one of the scripts I've tried:

from endpoints import Controller

import adafruit_dht import board

class Default(Controller):   def GET(self):
    dht_device = adafruit_dht.DHT22(board.D4)

    data = {
        "temperature": dht_device.temperature,
        "humidity": dht_device.humidity
    }

    return data

The problem occurs specifically when calling the dht_device.temperature/dht_device.humidity. When I leave this out, I can call the endpoint without issues.

To be clear: I did install libgpiod on the Raspberry Pi. EDIT: I installed libgpiod2, as one of the answers suggested.

Does anybody have an idea on what the issue might be here? Thanks in advance!

user3478148
  • 433
  • 1
  • 8
  • 26
  • I would suggest separating the problem into two parts: the instrument and the communication. You could return a hard-coded number for temperature and humidity until you get the communication stuff working correctly. Then add the instrument interface as a second step. – Paul Cornelius Jun 20 '20 at 20:34
  • Thanks for the tip @PaulCornelius. The issue here is that is seems as if the combination of the two isn't working correctly. When I return hardcoded data, everything works as expected. When I run the actual script for gathering the humidity and temperature separately multiple times (without the api), it works as expected as well. – user3478148 Jun 21 '20 at 07:00
  • 1
    I'm pretty sure that if you initialize DHT22 outside of `Default` controller (or if you close it after each request) it should work. The problem is that port access is usually not happy about two consecutive sessions gaining RW access to it, and thus the first session needs to close the bound hold in order for others to gain access (or at least that's my experience) – Torxed Jun 23 '20 at 05:34

3 Answers3

1

This was solved elsewhere for the Pi3 by installing libgpiod2:

https://github.com/adafruit/Adafruit_Blinka/issues/259

  • I should point out this is my first proper post in stackoverflow; feedback welcome? – Russell King Jun 20 '20 at 20:52
  • 1
    As you've asked... The general opinion of Stack Overflow is that you think forward several years and want to make sure that, if they're still relevant, that answers are still useful. Your answer is OK, because it does say to install `libgpiod2`. Any more relevant info you can add, in case the link perishes, would be better: installation instructions, explanation (although I appreciate there is no real explanation in that issue), would all improve the answer. The better, clearer and more informative the answer, the greater the chance of upvotes. – David Buck Jun 20 '20 at 21:42
  • Unfortunately, it seems that I already have `libgpiod2` installed: `libgpiod2/stable,now 1.2-3+rpi1 armhf [installed]` – user3478148 Jun 21 '20 at 06:56
  • Thanks david for the feedback - I'll bear that in mind when I post. – Russell King Jun 28 '20 at 20:23
1

You wrote:

class Default(Controller):
  def GET(self):
    dht_device = adafruit_dht.DHT22(board.D4)

    data = {
        "temperature": dht_device.temperature,
        "humidity": dht_device.humidity
    }

    return data

You need something like:

class Default(Controller):
  def __init__(self):
    super().__init__(self)
    self.dht_device = adafruit_dht.DHT22(board.D4)

  def GET(self):
    data = {
        "temperature": self.dht_device.temperature,
        "humidity": self.dht_device.humidity
    }
    return data

The problem you have is that you are creating each time a new instance when calling the endpoint. The first instance is created properly and has access to the information but the second and consecutive instances are blocked by the first instance.

Tin Nguyen
  • 5,250
  • 1
  • 12
  • 32
  • You were right! Thanks for the clear explanation :-) BTW, I'll reward you with the bounty soon. Can't do that for another 15 hours apparently. – user3478148 Jun 23 '20 at 14:15
0

I encountered this error in Raspbian stretch OS of RaspberryPi. Solved using below steps

You can try installing libgpiod2 package using below command

sudo apt-get install libgpiod2

If you get error as "E: Unable to locate package libgpiod2"

Then, Install the package using the deb package

Package url: https://packages.debian.org/buster/libgpiod2

wget http://ftp.cn.debian.org/debian/pool/main/libg/libgpiod/libgpiod2_1.2-3_armhf.deb

sudo dpkg -i libgpiod2_1.2-3_armhf.deb

If you get error as conflicting packages with libgpiod1, then uninstall the libgpiod1 package

sudo apt-get remove libgpiod1

and then try to install the package

sudo dpkg -i libgpiod2_1.2-3_armhf.deb
RaghuCK
  • 105
  • 3
  • 12