Posts Read out DHT11/22 with RaspberryPi 4 and Ubuntu Server
Post
Cancel

Read out DHT11/22 with RaspberryPi 4 and Ubuntu Server

I recently bought a RaspberryPi 4 and installed Ubuntu Server 20.04 64 Bit on it. There are many tutorials available how to read the temperature/humidity via Python, unfortunately none of them worked out of the box. It seems to be that they are

  • either for Raspbian OS
  • or for 32 Bit OSes.

After some searching I found a way from several sources to make it run. This is a horrible hacky workaround and I’d be very happy to see a better way and/or out-of-the-box solution.

Prerequisites

Installation

1. Install Python 3 Pip

We will use adafruit-circuitpython-dht to read out the sensor and install it via pip. Run below command from the shell.

1
sudo apt install python3-pip

2. Install RPi.GPIO via apt-get

Usually this is a dependency to adafruit-circuitpython-dht and thus could be installed with it. Unfortunately it does not succeed installing the dependency, so we need to install it ourself. For more information see this thread on askubuntu.com. Run below command from the shell.

1
sudo apt-get install RPi.GPIO

3. Install adafruit-circuitpython-dht

1
sudo pip3 install adafruit-circuitpython-dht

4. Install libgiod

This step is a bit ugly. Basically the default installation did not succeed for me, and I ended up finding that this solution on GitHub worked yet slightly modified.

4.1. Install and build libgpiod

1
2
3
4
sudo apt install libgpiod-dev git build-essential
git clone https://github.com/adafruit/libgpiod_pulsein.git
cd libgpiod_pulsein/src
make

You should see a new folder named libgpiod_pulsein. Run the script dht.py (linked in the prerequisites) and you should see some similar error:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Traceback (most recent call last):
  File "run.py", line 11, in <module>
    dhtDevice = adafruit_dht.DHT11(board.D16)
  File "/usr/local/lib/python3.8/dist-packages/adafruit_dht.py", line 265, in __init__
    super().__init__(True, pin, 18000, use_pulseio)
  File "/usr/local/lib/python3.8/dist-packages/adafruit_dht.py", line 56, in __init__
    self.pulse_in = PulseIn(self._pin, 81, True)
  File "/usr/local/lib/python3.8/dist-packages/adafruit_blinka/microcontroller/bcm283x/pulseio/PulseIn.py", line 67, in __init__
    self._process = subprocess.Popen(cmd)
  File "/usr/lib/python3.8/subprocess.py", line 854, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.8/subprocess.py", line 1702, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: '/usr/local/lib/python3.8/dist-packages/adafruit_blinka/microcontroller/bcm283x/pulseio/libgpiod_pulsein'

Of particular interest for us is the last line. The file exists, but Python cannot see/access it. Unfortunately granting Python any rights does not solve this problem either. So we need to replace it by the previous build and then grant python correct rights.

The path might be different on your computer, so don’t blindly copy & paste the next steps but in case it differs use path from your output.

4.2. Replace libgpiod with build

Go into the directory libgpiod_pulsein/src/ from step 4.1. and run the following command from there (important: Replace the path if it differs).

1
sudo cp libgpiod_pulsein /usr/local/lib/python3.8/dist-packages/adafruit_blinka/microcontroller/bcm283x/pulseio/libgpiod_pulsein

4.3. Set suid for Python

If you run dht.py again, it will show you the same error as before. We need to allow any user to run python with the same rights as the owner, which is root. It is done via setuid. This solution was posted on armbian.com. Please note: It is very dangerous to grant these rights to Python. So you should rather copy your Python Binary and change only the copy. See the linked solution for doing so.

As I have Python 3.8 on my machine, my Python Binary is found in /usr/bin/python3.8. To enable setuid, run the following command:

1
sudo chmod 4775 /usr/bin/python3.8

Read Sensor Data

Everything set up, so we are ready to read the data. You need to alter the script dht.py in line 8, depending on your GPIO Pin and Sensor:

1
2
3
4
# VE    - DHT version, e.g. 11 or 22
# PIN   - GPIO Pin the board is connected to, e.g. D4 = GPIO Pin 4
#                           VE       PIN
dhtDevice = adafruit_dht.DHT22(board.D4)

It should now start without any errors and print output similar (different values) to that.

1
2
3
4
5
➜  ~ python dht.py
Temp: 66.2 F / 19.0 C    Humidity: 32% 
Temp: 68.0 F / 20.0 C    Humidity: 33% 
Temp: 68.0 F / 20.0 C    Humidity: 33% 
Temp: 68.0 F / 20.0 C    Humidity: 33% 
This post is licensed under CC BY 4.0 by the author.