środa, 14 listopada 2012

Raspberry Pi/czujnik DHT-22: rejestrowanie temperatury i wilgotności

Czujnik DHT-22
Rys. #1: DHT-22

Rys. #2: Testowanie DHT-22
Instalacja 2x czujnik DHT-22
Rys. #3: Okablowanie

Do wykonania instalacji potrzebne są:

Czujnik DHT-22 temperatury/wilgotności (ok. 30 zł za sztukę). Droga sprawa...

REZYSTOR 0,25W 10K OHM węglowy (1,00 zł za 100 sztuk na Allegro).

Do tego: przewody połączeniowe żeńskie, przewód telefoniczny czterożyłowy lub inny podobny, kostka elektryczna oraz rurka termokurczliwa do izolacji i wzmocnienia połączeń. (Por. Raspberry Pi: magistrala 1-Wire i rejestracja temperatury.)

UWAGA: tańszą wersja DHT-22 jest DHT-11 (aka SHT-11). Połasiłem się nawet na takowy, bo taniej ale nie polecam. Przede wszystkim mierzy temperaturę w przedziale od 0C do 50C (z kiepską dokładnością +/- 2C) więc nie nadaje się do pomiaru temperatury zewnętrznej. Do tego odczyt wilgotności jest zaniżony i nie działa podłączony do niektórych pinów GPIO (być może jest to problem oprogramowania, którego używam). Dla porównania DHT-22 mierzy temperaturę w przedziale od -40C do +80C z dokładnością +/- 0,5C.

Na stronie learn.adafruit.com znajduje się tutorial, z którego korzystałem...

Hardware

Sensor DHT-22 ma cztery piny (por. rys #1). Podłączyłem linie danych (DQ) do pinów P22, P24 i P25 (każdy sensor musi mieć oddzielną linię danych). Vdd każdego sensora do pina P1 (zasilanie 3,3V). GND (masa) każdego czujnika do pina P6. Ponadto każde DQ należało połączyć za pomocą rezystora z linią zasilania Vdd.

Pin Null nie jest wykorzystywany.

Lutowanie i łączenie wszystkiego do kupy wykonałem w sposób identyczny (kostka elektryczna, rurka termokurczliwa itp.) z opisanym bardziej szczegółowo we wpisie Raspberry Pi: magistrala 1-Wire i rejestracja temperatury.

Software

Pobieram, kompiluję i instaluję niezbędną bibliotekę:


pi@raspberrystar $ wget http://www.open.com.au/mikem/bcm2835/bcm2835-1.8.tar.gz
pi@raspberrystar $ tar -zxvf bcm2835-1.8.tar.gz
pi@raspberrystar $ cd bcm2835-1.8
pi@raspberrystar $ ./configure && make && sudo make install

Pobieram program do obsługi czujników:


pi@raspberrystar $ git clone https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git
pi@raspberrystar $ cd Adafruit-Raspberry-Pi-Python-Code
pi@raspberrystar $ cd Adafruit_DHT_Driver

W pliku Makefile należy dopisać -l rt na końcu wiersza zaczynającego się od CFLAGS:


CFLAGS = -std=c99 -I. -lbcm2835 -l rt

teraz:


## w katalogu Adafruit_DHT_Driver
pi@raspberrystar $ make

Jeżeli wszystko działa, to:


# Uruchomienie ./Adafruit_DHT typ-czujnika nr-pina-DQ
pi@raspberrystar $ sudo ./Adafruit_DHT 22 25
Using pin #25
Data (40): 0x3 0xe7 0x0 0x17 0x1
Temp = 2.3 *C, Hum = 99.9 %

W katalogu Adafruit_DHT_Driver znajduje się też skrypt Pythona pn. Adafruit_DHT_googledocs.ex.py służący do wysyłania odczytanych danych do arkusza google.docs. Skrypt Adafruit_DHT_googledocs.ex.py do działania potrzebuje modułu gspread:


pi@raspberrystar $ wget http://pypi.python.org/packages/source/g/gspread/gspread-0.0.13.tar.gz
pi@raspberrystar $ tar -zxvf gspread-0.0.13.tar.gz
pi@raspberrystar $ cd gspread
pi@raspberrystar $ sudo python setup.py install

Skrypt Pythona Adafruit_DHT_googledocs.ex.py: 1) w nieskończonej pętli uruchamia co 30 sekund program Adafruit_DHT, 2) wyłuskuje z wydruku wartości temperatury/wilgotności, 3) wysyła co trzeba na google.docs. Fragment skryptu wygląda następująco:


while(True):
output = subprocess.check_output(["./Adafruit_DHT", "2302", "4"]);
print output
# search for humidity printout
matches = re.search("Hum =\s+([0-9.]+)", output)
if (not matches):
time.sleep(3)
continue
humidity = float(matches.group(1))
## pominięty kod ...

time.sleep(30)

Ponieważ ja chcę oprócz wysłania na google.docs coś tam jeszcze zrobić z danymi, to miałem do wyboru albo rozbudować Adafruit_DHT_googledocs.ex.py o dodatkową funkcjonalność albo go uprościć. Wybrałem to drugie: moja wersja Adafruit_DHT_googledocs.ex.py ogranicza się wyłącznie do wysłania na google.docs wartości przekazanych jako argumenty wywołania:


temp = float(sys.argv[1])
humidity = float(sys.argv[2])
## pominięty kod ...

Resztą zajmie się poniższy skrypt basha:


#!/bin/bash
#
LOG_DIR=/home/pi/Logs/DHT
BIN_DIR=/home/pi/bin
SENSTYPE=22
SLEEP_TIME=5

function ReadSensor() {
local sensorType="$1"
local sensorId="$2"
local WYNIK=""
local SUCCESS=""

## zwiększyłem powtórzenia do 5 (sleep zmniejszony do 5s/było 10)
for i in 1 2 3 4 5; do
WYNIK=`sudo $BIN_DIR/Adafruit_DHT $sensorType $sensorId | tr '\n' ' '`
SUCCESS=`echo $WYNIK | awk ' { if (NF > 10) {print "YES"} else { print "NO"}}'`

if [ "$SUCCESS" = "YES" ] ; then
echo "$sensorId=$i $WYNIK" >> $LOG_DIR/DHT22.log
DHT_CURR_TEMP=`echo $WYNIK | awk '{print $13}'`
DHT_CURR_HUM=`echo $WYNIK | awk '{print $17}'`
break
fi
sleep $SLEEP_TIME;
done

## Wszystkie próby okazały się nieudane
if [ $SUCCESS = "NO" ] ; then
echo "$sensorId=? $WYNIK" >> $LOG_DIR/DHT22.log
DHT_CURR_TEMP="999.9"
DHT_CURR_HUM="999.9"
fi
}
echo "@`date "+%Y%m%d%H%M%S"`" >> $LOG_DIR/DHT22.log

## Czujnik w pokoju:
ReadSensor $SENSTYPE "24"
READINGS="$DHT_CURR_TEMP $DHT_CURR_HUM"
sleep 12

## Czujnik na zewnątrz:
ReadSensor $SENSTYPE "25"
READINGS="$READINGS $DHT_CURR_TEMP $DHT_CURR_HUM"
sleep 12

## Czujnik weranda:
ReadSensor $SENSTYPE "22"
READINGS="$READINGS $DHT_CURR_TEMP $DHT_CURR_HUM"

## zamiana na HTML + wykres
/usr/bin/perl /home/pi/bin/dht2ht.pl > /var/www/stats/DHT22.html

# Wyslanie na google
/home/pi/bin/DHT_googledocs.ex.py $READINGS

Podobnie jak w przypadku magistrali 1-Wire zdarzają się problemy z odczytaniem wartości czujnika. Na tą okoliczność funkcja ReadSensor próbuje odczytu kilkukrotnie. Maksymalna nieudana liczba prób, którą zaobserwowałem w ciągu kilkudniowej eksploatacji to 3.

Skrypt jest uruchamiany co 30 min przez crona:


1,31 * * * * /home/pi/bin/dht2ht.sh

Plik LOG wygląda jakoś tak:


@20121113230101
24=1 Using pin #24 Data (40): 0x2 0x22 0x0 0xc9 0xed Temp = 20.1 *C, Hum = 54.6 %
25=1 Using pin #25 Data (40): 0x3 0xe7 0x0 0x1c 0x6 Temp = 2.8 *C, Hum = 99.9 %
22=4 Using pin #22 Data (40): 0x2 0x73 0x0 0xb0 0x25 Temp = 17.6 *C, Hum = 62.7 %

Wiersz zaczynający się od @ zawiera datę i czas odczytu. Wiersze zaczynające się od nn=m zawierają odczytane dane (nn to numer czujnika, m numer próby w której odczytano wartości lub ? jeżeli wszystkie próby były nieudane)

Uwaga: zauważyłem, że przy intensywnych operacjach I/O są duże problemy z odczytaniem wskazań czujników.

Skrypt dht2ht.pl

Perlowy skrypt dht2ht.pl tworzy tabelę oraz wykresy prezentujące odczytane wartości plus obliczoną na ich podstawie temperaturę punktu rosy. Rezultat działania można oglądać tutaj. Omawiane w tym wpisie skrypty są zaś tutaj.

Arkusz google.docs zawierający odczyty z moich trzech czujników jest dostępny tutaj. (Uwaga: z jakiś ważnych powodów skrypt Adafruit_DHT_googledocs.ex.py zaczął dopisywanie danych od 162 wiersza arkusza.)

16 komentarzy:

  1. witam mam problem zrobilem tak jak poleciles wpisałe sudo ./Adafruit_DHT 22 25
    i wyswietlilo mi tylko to :
    Using pin #25
    Data (40): 0x0 0x0 0x0 0x0 0x0 wiesz moze co jest przyczyna?

    OdpowiedzUsuń
  2. A jakie modułu są załadowane? lsmod?

    Mój /etc/modules
    # /etc/modules: kernel modules to load at boot time.
    # Parameters can be specified after the module name.

    snd-bcm2835
    w1-gpio
    w1-therm
    #
    # http://learn.adafruit.com/\
    # adafruit-16-channel-servo-driver-with-raspberry-pi/\
    # configuring-your-pi-for-i2c
    i2c-dev
    i2c-bcm2708

    lsmod | grep i2

    i2c_bcm2708 3542 0
    i2c_dev 5587 0

    nie wiem czy powyższe nastawy są optymalne ale działa
    jest jeszcze plik /etc/modprobe.d/raspi-blacklist.conf
    którego zawartość warto sprawdzić

    Ponadto: sprawdzić czy połączenia są naprawdę poprawne.
    Zmienić pina DATA na inny (24 na przykład)...

    Ten program obsługujący jest kapryśny--jest o tym wspomniane w poście...

    OdpowiedzUsuń
  3. robiłem wszystko pokolei jak napisałes.tylko wlasnie niewiem czy to jest wszystko co musze zrobic.

    OdpowiedzUsuń
  4. Rozumiem, że dalej nie działa.
    Proponuję kontakt via email: tprzechlewski _at_ gmail

    OdpowiedzUsuń
  5. podaj jeszcze raz maila

    OdpowiedzUsuń
  6. tak jak wyżej tylko zamień _at_ na @ usuń spacje naokoło @
    i dodaj .com po gmail:-)

    OdpowiedzUsuń
  7. Świetna sprawa i cały temat rozłożony na części pierwsze. Myślałem, że już niczego w tych kwestiach się nie dowiem.

    OdpowiedzUsuń
  8. Super to zostało opisane. Pozdrawiam.

    OdpowiedzUsuń
    Odpowiedzi
    1. Pani Agato dziękuje za miłe słowa. Na dziś lepiej używać Bosch BME280, np
      https://allegro.pl/oferta/bme280-czujnik-temperatury-cisnienia-i-wilgotnosci-8363016884
      Od razu mierzy 3 rzeczy, dokładniejszy i dłuższy przewód nie stanowi problemu, a DHT mi nie działał jak chciałem przenieść czujnik trochę dalej niż za parapet

      Usuń
    2. Tu jest dobry opis jak zainstalować BME280 https://twojpomyslna.wordpress.com/2019/02/18/raspberry-pi-bme280-i2c-domoticz/

      Usuń
  9. Czy dbacie o bezpieczeństwo w swoim domu ? Niedawno skorzystałem z oferty firmy Ivel Electronics, gdzie zamówiłem kilka czujnik gazu ziemnego i jestem bardzo zadowolony. Spełniają one wszelkie normy.

    OdpowiedzUsuń
  10. Super wpis. Warto było tutaj zajrzeć

    OdpowiedzUsuń
  11. Świetny artykuł. Pozdrawiam

    OdpowiedzUsuń