Elektroda.pl
Elektroda.pl
X
Sklep HeluKabel
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[BASCOM] Czujnik wilgotności i temperatury DHT11

krzychop 12 Mar 2012 21:24 9757 16
  • #1 12 Mar 2012 21:24
    krzychop
    Poziom 9  

    Witam
    Jeśli ktoś szuka rozwiązania programowego aby wykorzystać czujnik temperatury i wilgotności DHT11 zamieszczam rozwiązanie .
    Program na którym pracuje poprawnie.

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0 16
  • Sklep HeluKabel
  • #2 15 Lip 2012 22:18
    doles
    Poziom 19  

    Witam, czy mógłbyś po krótce wyjaśnić zasadę komunikacji z DHT11 ? Wiem, że jest on na 1Wire, jednak nie rozumiem jak dobrać się do jego rejestrów z danymi...w dokumentacji nie ma nic na ten temat, ani jakiegoś adresu ROM urządzenia (gdy mamy kilka urządzeń na magistrali), ani informacji jak zczytać dane...Tylko napisane, że całość zawiera 40 bitów z czego: temperatura rejestr wyższy i niższy 16 bit, tak samo wilgotność + CRC...W Twoim kodzie też nie widzę jakiejkolwiek informacji na ten temat, jakieś adresy rejestrów etc. Z góry dzięki, pewnie wielu osobom się to przyda

    0
  • Sklep HeluKabel
  • #3 12 Sty 2013 22:57
    yozue
    Poziom 9  

    Witam
    Temperatura i wilgotność, wyświetla tylko wartość całkowitą. A jak z czytać przynajmniej jedno miejsce po przecinku ?

    0
  • #4 13 Sty 2013 06:22
    emarcus
    Poziom 35  

    doles napisał:
    Witam, czy mógłbyś po krótce wyjaśnić zasadę komunikacji z DHT11 ? Wiem, że jest on na 1Wire, jednak nie rozumiem jak dobrać się do jego rejestrów z danymi...w dokumentacji nie ma nic na ten temat, ani jakiegoś adresu ROM urządzenia (gdy mamy kilka urządzeń na magistrali), ani informacji jak zczytać dane...Tylko napisane, że całość zawiera 40 bitów z czego: temperatura rejestr wyższy i niższy 16 bit, tak samo wilgotność + CRC...W Twoim kodzie też nie widzę jakiejkolwiek informacji na ten temat, jakieś adresy rejestrów etc. Z góry dzięki, pewnie wielu osobom się to przyda


    Nie ma tam adresów rejestrów bo jest tylko jeden rejestr, który możesz tylko odczytac w sposób podobny do 1-Wire (1-Wire jest to specyficzny protocol opracowany przez Dallas/Maxim Semiconductor Corp. i obsługuje tylko ich devices).
    Nota katalogowa DHT11 zawiera szczegóły sposobu i timingi tej kommunikacji (dla odróżnienia nazwanej "single-wire").
    http://www.robotshop.com/PDF/dht11.pdf

    DHT11 jest to 'basic' sensor do zastosowań jako single device, jest bardzo wolny (5-10 sec. response time) i małej rozdzielczości 5% dla wigotności oraz 2 st.C dla temperatury.

    Chcesz wiecej objaśnień do kodu kol.'krzych'; - odnajdziesz je tu:
    http://software.pc-fault.com/software/86440.html

    Zechcesz miec więcej devices na magistrali, lub większą dokładnośc odczytu będziesz zmuszony poszukac innych rozwiązań.

    e marcus

    0
  • #5 18 Sty 2013 15:06
    maximus22_kr
    Poziom 18  

    A czy można dać po jednym układzie na jeden pin Atmega ?
    Czyli coś takeigo:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Ja tak zrobiłem na Atmega644P, dodatkowo dla pewności każdy z programów wywołuje w innym czasie ( jeden co 6 drugi co 7 sekund ) poprzez ustawienie flag w przerwaniu Timer0. Wyświetla obie wilgotności i temperatury.

    Ale mam wrażenie, że użycie dwóch układów DHT11 jest przyczyną zawieszania procesora nawet po kilku godzinach. A dołożenie do tego jeszcze zapisu SD zawiesza procesor w kilka minut.

    Dodano po 3 [godziny] 7 [minuty]:

    Znalazłem jeszcze taki kod:
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Przetestuje wieczorem

    0
  • #6 25 Sty 2013 18:16
    _kaktus_
    Poziom 12  

    maximus22_kr,
    zmniejsz częstotliwość dokonywania pomiarów, czy tak dużą ilość próbek potrzebujesz do jakiejś analizy?
    Jeśli nie to odczytuj je na przemian co minutę lub rzadziej (raz jeden raz drugi) , i pamiętaj, że obsługa/odczyt jednego czujnika dla µC to cała wieczność.


    pozdrawiam kaktus

    0
  • #7 25 Sty 2013 22:33
    maximus22_kr
    Poziom 18  

    Tzn. zrobiłem odczyt
    - pierwszy czujnik co 1 minute i 1 sekundę
    - drugi czujnik co 2 minuty i 2 sekundy
    ale wczoraj po jednej dobie poprawnej pracy zawiesił się, więc teraz mam dwa razem ( oczywiście na osobnych liniach ) i dział już nieco ponad dobę.
    Ale spróbuję ( tzn. poczekam aż się zawiesi ) np. co dwie minuty i zmieniać na przemian przez flagę.

    0
  • #8 25 Sty 2013 22:52
    _kaktus_
    Poziom 12  

    proponuję abyś powyłączał wszystko oprócz obsługi naprzemiennej czujników, i pokazywał wyniki na wyświetlacz, dodatkowo liczył sekundy minuty itd na wyświetlaczu, będziesz miał narzędzie diagnostyczne w ten sposób sprawdzisz sobie obsługę DHT.
    Postępując analogiczną drogą znajdziesz i wyeliminujesz błąd bo pewno gdzieś jest. Istotna jest też jakość zasilania µC.
    W nocie czujnika przeczytasz:

    Cytat:
    zalecana długość kabla do 20m, pull-up 5K
    po załączeniu zasilania 3-5,5V poczekać na przekroczenie stanu niestabilności 1s.
    Można zwiększyć kondensator pomiędzy pinami zasilania (Vdd, GND) do 100nF.


    na dużych odległościach polecają przewód komunikacyjny ekranowany.

    powodzenia

    kaktus

    0
  • #9 25 Sty 2013 23:10
    maximus22_kr
    Poziom 18  

    No właśnie tak doszedłem do tego, że to problem z czujnikami DHT11
    - sam zegar PCF8563 działa
    - zegar PCF8563 z zapisem SD działa
    - zegar PCF8563 z czujnikami DHT11 działa
    - zegar PCF8563 z czujnikami DHT11 i zapisem SD zawieszał się po kilkunastu minutach ( odczyt z DHT11 był co 8 sekund )

    Zwiększenie czasu pomiędzy odczytami DHT11 ma jak na razie pozytywny skutek - całość chodzi ponad dobę.
    Podejrzewałem jeszcze RC5, ale Kolega piotrva wyjaśnił, że zapis na SD również potrzebuje Timer'a ( a u mnie już ich brakło ), tak więc zawieszanie się przy włączeniu odbioru RC5 było oczywiste. Natomiast po wyłączeniu RC5 już nie tak bardzo.

    Ale będę próbował z tym naprzemiennym odczytem. W sumie Wilgotność to nie jest tak istotny parametr, można go mierzyć co 2- 4 minuty. W sumie ten pomysł z naprzemiennym odczytem powinien zmniejszyć ryzyko ewentualnego "zamieszania" - bo może się zdarzyć, że odczyt z obydwu DHT11 nastąpi jeden zaraz po drugim".

    0
  • #10 25 Sty 2013 23:33
    _kaktus_
    Poziom 12  

    szkoda że nie mam dwóch sztuk DHT, bym sprawdził empirycznie, bo teoretycznie to sądzę, że to nie od tego, choć nie muszę mieć racji.

    Spróbuj poukładać sobie dobrze w programie, aby każda czynność (odczyt czujnika, zegarka, zapis i co tam jeszcze masz) nie wadziła drugiej, niech się wykonują jednorazowo, kolejno co zadany interwał czasu. Jak wykorzystujesz przerwania rozważ co się dzieje. Tak jak piszesz należy posprawdzać czy "różne działania" podczas pracy nie wykorzystują wspólnych zasobów µC. Tak że dobrze oczka wytrzeszczaj i czytaj, a uzdrowisz sytuację.
    ;-)

    0
  • #11 25 Sty 2013 23:55
    maximus22_kr
    Poziom 18  

    Jest to pomysł, aby nadać pewne priorytety czynnościom. Np. dla mnie ważny jest zapis, więc może dam dodatkowy warunek - sprawdzanie stanu pinu, który steruje zapisem ( CS_SD ) i gdy jego stan niski to blokować działanie innych podprogramów.

    Samo wykonywanie po kolei może się do końca nie sprawdzić, bo np :
    - DTH11 co 2 minuty
    - zapis SD co minutę
    - pomiar DS18B20 co 10 sekund

    i teraz co dziesiąty pomiar DS18B20 zablokuje przerwania ( choć tutaj mogę blokować tylko INT1 od PCF8574 ). Co drugi zapis na SD będzie razem z odczytem DHT11.

    W sumie "męczę" jeszcze jeden temat. Chciałem, żeby podprogram "żył własnym życiem" w trakcie swojego trwania, czyli np. aktualizował wskazania, a jeszcze lepiej, żeby nie blokował innych funkcji. Np. oglądam wskazania z DS18B20 w podmenu, a w tym czasie pojawia się flaga zapisu na SD i zapis przepada.

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0
  • #12 07 Lut 2013 13:32
    bald22
    Poziom 12  

    witam. znajdzie sie ktoś z pomocną dłonią i napisze mi program na atmege8 pracującej na oscylatorze wewnętrznym, bo już kilka razy próbowałem i nie działa, a aż takich umiejętności nie mam. DHT podłączene do PD.3. LCD 16*2 (Config Lcdpin = Pin , Db4 = Portb.3 , Db5 = Portb.2 , Db6 = Portb.1 , Db7 = Portb.0 , E = Portb.4 , Rs = Portb.5). dziękuje :) Aha i może dodam że na testowanych programach blokuje sie na Start....... i nic a jak włącze bez dht11 to normalnie wyświetla tylko że temp 0 a wilg 255. I jeszcze czy może to być wina rezystora bo mam 10k gdzieś tak znalazłem nie wiem gdzie ale teraz widze że ma być 5k??

    0
  • #13 28 Wrz 2013 16:50
    _kaktus_
    Poziom 12  

    bald22 napisał:
    witam. znajdzie sie ktoś z pomocną dłonią i napisze mi program na atmege8 pracującej na oscylatorze wewnętrznym, ...


    przełączenie rezonatora na wewnętrzny oscylator zrobisz przestawiając stosowne fusebits

    co do obsługi sensora poczytaj tutaj

    rezystor 10k jest jak najbardziej prawidłowy

    0
  • #14 20 Lis 2017 17:07
    grabek_radek
    Poziom 21  

    Witam serdecznie
    Mam taki kodzik

    Cytat:

    $regfile = "m8adef.dat"
    $crystal = 8000000

    'konfiguracja wyświetlacza LCD
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 , Db7 = Portd.3 , E = Portd.4 , Rs = Portd.5
    Cursor Off
    Cls

    'deklaracja procedury
    Declare Sub Get_th(t As Byte , H As Byte)

    'Config Serialin = Buffered , Size = 128 'konfiguracja hardware UART
    'Config Serialout = Buffered , Size = 128 'konfiguracja hardware UART

    'czujnik podłączony do PortD.6
    Dht_put Alias Portd.6
    Dht_get Alias Pind.6
    Dht_io_set Alias Ddrd.6

    Dim T As Byte 'zmienna do przechowywania temperatury
    Dim H As Byte 'zmienna do przechowywania wilgotności
    Dim Crc As Byte 'zmienna do przechowywania bajtów parzystości
    Dim Mybyte As Byte
    Dim Sensor_data As String * 40 'tutaj będą zapisywać się dane z czujnika
    Dim Tmp_str8 As String * 8
    Dim Count As Byte 'zmienna do obliczania odebranych bitów

    'Enable Interrupts

    Set Dht_io_set
    Set Dht_put

    Lcd "DHT 11"
    Lowerline
    Lcd " sensor"

    Do
    Waitms 1500
    Call Get_th(t , H)
    Cls
    Lcd "TMP: " ; T ; "C"
    Lowerline
    Lcd "PHP: " ; H ; "%"
    Loop

    Sub Get_th(t As Byte , H As Byte)

    Count = 0
    Sensor_data = ""
    Set Dht_io_set 'robimy wyjście z PD.6
    Reset Dht_put 'ustawić magistralę w stan LOW
    Waitms 25 'odczekać co najmniej 18ms

    Set Dht_put 'zwolnić magistrale
    Waitus 40
    Reset Dht_io_set 'robimy wejście z PD.6
    Waitus 40 'odczekaj 40 ms
    If Dht_get = 1 Then 'jeśli magistrala jest w stanie wysokim
    H = 1 'oznacza że czujnik nie odpowiedział
    Exit Sub 'kończymy podprogram
    End If

    'jeśli czujnik odpowiedział i wyciągnął magistrale do zera kontynuujemy pracę
    Waitus 80 'czekamy jeszcze 80ms
    If Dht_get = 0 Then 'jeśli na linii jest nadal 0
    H = 2 'oznacza czujnik zwariował
    Exit Sub 'kończymy podprogram




    End If

    'jeśli wszystko pójdzie dobrze i czujnik zareagował prawidłowo, możemy kontynuować

    While Dht_get = 1 : Wend 'czekamy, aż magistrala ma stan wysoki

    Do 'zaczynamy przyjmować 40-bitowe dane
    While Dht_get = 0 : Wend 'czekamy na ustawienie magistrali w stan 0
    Waitus 30 'po wystąpieniu stanu 0 czekać 30 ms
    If Dht_get = 1 Then 'jeśli na szynie 1
    Sensor_data = Sensor_data + "1" 'zapisujemy do zmiennej tą wartość
    While Dht_get = 1 : Wend 'i czekamy aż nadajnik wyśle kolejny bit
    Else 'w przeciwnym razie, jeśli tam jest 0
    Sensor_data = Sensor_data + "0" 'zapisujemy je do zmiennej
    End If
    Incr Count 'zwiększamy licznik
    Loop Until Count = 40 'Powtarzaj tę czynność dopóki licznik osiągnie liczbę 40

    Set Dht_io_set
    Set Dht_put

    'zaczynamy rozkładać otrzymane dane

    Tmp_str8 = Left(sensor_data , 8) 'bierzemy lewe 8 znaków zmiennej
    H = Binval(tmp_str8) 'jest cała część wilgotności

    Tmp_str8 = Mid(sensor_data , 17 , 8) 'wyjmujemy 8 znaków ze środka
    T = Binval(tmp_str8) 'to cała część temperatury

    Tmp_str8 = Right(sensor_data , 8) 'prawe 8 znaków
    Crc = Binval(tmp_str8) 'dane testowe

    'test sumy kontrolnej

    Mybyte = T + H 'dodajemy wartości temperatury i wilgotności
    If Mybyte <> Crc Then 'jeśli suma kontrolna się nie zgadza
    H = 3 'Oznacza to, że dane nie są poprawne
    End If

    End Sub 'powrót do głównej pętli programu

    problem polega na tym ze temperature odczytuję dobrze natomiast wilgotność wskazuje 3 % i co pewien czas wskoczy wartość 30-35%.
    Rezystor miedzy out a VCC 4,7k fuse bit przestawiony na zew. oscylator 8MHz

    0
  • #15 20 Lis 2017 17:50
    _kaktus_
    Poziom 12  

    Ponieważ diabeł tkwi w szczegółach, po zaglądnięciu na początek i koniec Twojego kodu wskażę Ci co tam napisałeś, bo być może coś umknęło Twojej uwadze:

    Kod: vbnet
    Zaloguj się, aby zobaczyć kod

    to pierwsze, gdzieś na końcu zauważyłem jeszcze takie coś:
    Kod: vbnet
    Zaloguj się, aby zobaczyć kod


    potem piszesz:
    grabek_radek napisał:
    problem polega na tym ze temperature odczytuję dobrze natomiast wilgotność wskazuje 3 % i co pewien czas wskoczy wartość 30-35%.


    i co ja mam sobie myśleć? Więc zadam pytanie czy to jest Twoja praca?

    Pisząc:
    grabek_radek napisał:
    fuse bit przestawiony na zew. oscylator 8MHz

    masz na myśli zewnętrzny rezonator kwarcowy - czy to kolejna niewiadoma?
    Bo oscylator =! rezonator kwarcowy

    Tak jak na wstępie zaznaczyłem diabeł tkwi w szczegółach więc bardzo trzeba być drobiazgowym i szczegółowym (nawet upierdliwym) aby nie powstawały tej podobne sytuacje.

    Mając "nowe" informacje przeanalizuj dokładnie skąd ta 3-ka się może brać.

    0
  • #16 20 Lis 2017 19:49
    grabek_radek
    Poziom 21  

    _kaktus_
    Dzięki za podpowiedź. Kod jest prawdopodobnie z twojej strony
    Mam rezonator kwarcowy 8 MHz zewnętrzny.
    Ale i tak nie wiem dlaczego nie odczytuje poprawnie ... jedynie co jakiś czas wskoczy poprawna wartosc

    0
  • #17 20 Lis 2017 20:09
    _kaktus_
    Poziom 12  

    Z ciekawości zapytam:
    A próbowałeś zakomentować linię gdzie do H przypisywana jest wartość po teście sumy kontrolnej?

    Sprawdź jak wtedy działa ...
    No i dla ścisłości wypadało by otrzymany wynik porównać z odczytem z innego przyrządu.

    0