Hallo,
gestern kam endlich der DHT22 Feuchtigkeits-/Temperatursensor aus China
an. Nun sitze ich schon den ganzen Tag daran, das Teil zum Laufen zu
kriegen. Es kommen zwar Werte an und ab und zu stimmt auch die
Checksumme dazu, aber die Werte können nicht stimmen. Die Daten frage
ich folgendermaßen ab:
1
#include"dht.h"
2
#include"uart.h"
3
#include<util/delay.h>
4
#include<stdlib.h>
5
6
#define TICKS 80
7
8
voiddht_reset()
9
{
10
INPUT_MODE();
11
HIGH();
12
}
13
14
voiddht_read()
15
{
16
charticks[TICKS],buf[100],checksum=0;
17
uint8_ti=0,j=7,index=0;
18
uint16_tlastState=PIN_STAT();
19
20
dht_reset();
21
22
HIGH();
23
_delay_ms(250);
24
25
data[0]=data[1]=data[2]=data[3]=data[4]=0;
26
27
OUTPUT_MODE();
28
LOW();
29
_delay_ms(20);
30
HIGH();
31
_delay_us(40);
32
INPUT_MODE();
33
34
/*Sensor output starts*/
35
lastState=1;
36
for(i=0;i<TICKS;i++)//40 bits
37
{
38
ticks[i]=0;
39
//_delay_us(40);
40
while(PIN_STAT()==lastState)//wait, until state changes
Ich hatte mich ja teilweise an folgendem Code orientiert:
https://github.com/adafruit/DHT-sensor-library/blob/master/DHT.cpp
Leider mit wenig Erfolg. Mich wundert am meisten, dass data[2], also das
Temperaturbyte meistens leer ist, da scheint wohl noch etwas mit dem
Empfangen/Auswerten des Bitstreams nicht zu stimmen, ich kann nur leider
keinen Fehler finden...
Ich habe nur einen DHT11 an meinem AVR, aber das sollte keinen
Unterschied machen. Bei mir sind halt immer die zweiten Bytes 0x00
während bei dir dort die Nachkommastellen zu finden sein sollten. Schau
doch sonst mal probeweise, ob der Code klappt.
Hinweis 1: im initdht() müsstest du noch das Einschalten des Pullups
auskommentieren.
Hinweis 2: Der Sensor darf nach dem Einschalten ein paar (Milli)Sekunden
lang nicht angesprochen werden, ansonsten bekommt man ihn leicht in
einen undefinierten Zustand. Siehe auch das verlinkte PDF bei
adafruit.com. Mach also mal ein _delay_ms(500) o.ä. bei dir in die
main() vor dem read.
So, ich habe deine Hinweise mal umgesetzt und es funktioniert immer noch
nicht. Deinen Code habe ich auch schon probiert, gleiches Ergebnis. Ich
weiß langsam nicht mehr weiter... :(
Ich habe noch einiges ausprobiert und festgestellt, dass wenn der
Bitstream vom Sensor um 3 Bit nach links verschoben wird, zumindest die
checksumme so gut wie immer stimmt. Außerdem ändern sich die Werte
nicht. Testweise habe ich den Sensor mal angehaucht und siehe da, in den
ersten zwei Bytes tut sich was :) Die Werte werden größer und nach
einiger Zeit werden sie auch wieder kleiner, also scheint die
Feuchtigkeitsmessung zumindest zu funktionieren, wenn auch keine
korrekten Werte kommen. Leider bleibt die Temperaturmessung unverändert
bei 0 :( Im Anhang hab ich mal ein Werteprotokoll hochgeladen. Die
empfangenen Bytes sind zeilenweise binär dargestellt.
Gruß
Paul
Ah, ok, ich glaub, ich habs verstanden ;) Die zwei Bytes müssen
konkateniert und dann durch 10 geteilt werden, um den eigentlichen Wert
herauszubekommen. Ich dachte im ersten Byte steht der Vorkommawert und
im zweiten der Nachkommawert. Aber jetzt ist ja alles klar :)
Ja nachdem, wann Du anfängst zu messen, werden 42 Signale / Impulse
empfangen, davon sind 40 Nutzsignale. Die langen Impulse sind 1 und die
kurzen 0. Wartet man auf das erste "High" nach der Anfrage (siehe
Datenblatt), muss man die ersten beiden Signale Ignorieren. Ich habe
leider nur einen BASCOM Code. Darin messe ich die Zeiten der Impulse und
generiere dann daraus die Bits.
Wichtig ist das umschalten des Pins. In Bascom sieht das so aus
(pinc.0):
In C sollte es ähnlich aussehen. Aber Du empfängst ja Daten, daran
sollte es nicht liegen.
Schau doch nochmal, ob Du wirklich an der richtigen Stelle ansetzt. Die
ersten beiden 16 Bits kann man auch als Word für H und T nehmen. Das
restliche Byte ist dann die Prüfsumme.
Hi,
was mir so auffällt dazu:
- es werden niemals .c Dateien includiert
- die Funktionen dht11() oder dht11_output() gibt es nicht in der
dht11.h
- stimmen die Deklarationen in der dht11.h bezüglich der genutzten Pins
und Ports?
Grüße,
Muetze1
Hi,
also die Typen der Variablen stimmen nicht. Wie in der dht11.h zu sehen
sollte es int16_t sein und keine unsigned Variante. Die gelieferten
Werte sind wimre um Faktor 10 verschoben. Die Nachkommastelle ist dann
die unterste Stelle.
Aber mal eine andere Frage: Du fragst ständig ob du so die Werte mit
Vor- und Nachkommastelle rausbekommst. Gegenfrage: was bekommst du denn
raus? Was ist die Differenz zwischen Erwartung und Resultat?
Wenn man sich die Dokumentation der Funktion itoa() anschaut, dann
sollte auch klar sein warum keine Nachkommastelle mit einem separatem
Dezimalpunkt rauskommt. Aber ich denke mit der Info aus dem ersten
Abschnitt, sollte man das gelöst bekommen.
Grüße,
Muetze1
> Thomas K. schrieb:>> Aber mal eine andere Frage: Du fragst ständig ob du so die Werte mit>> Vor- und Nachkommastelle rausbekommst. Gegenfrage: was bekommst du denn>> raus? Was ist die Differenz zwischen Erwartung und Resultat?>> Erwartung:> Temperatur: 00011000 01000111 // so in etwas> Luftfeuchte: 00110101 01100001
Wieso binär? Dann wäre die Funktion itoa() falsch. Wie soll es denn nun
ausgegeben werden?
Was sagt die Dokumentation von itoa() über das Ergebnis der Funktion
aus?
Was muss man noch beachten bezüglich dem Faktor 10 für die
Nachkommastellen? Da müsste der Code auch noch angepasst werden, wenn es
dezimal ausgegeben werden sollte. Um das mit dem Faktor 10 mal als
Beispiel zu schreiben:
Rückgabewert: 1234
bedeutet: 123,4
Ansonsten sehe ich keine Notwendigkeit für die volatile Deklaration der
beiden Variablen.
Grüße,
Muetze1
Nach den ganzen Beiträgen ein wichtiger und notwendiger Rat: Du musst
Dir unbedingt die Grundlagen erarbeiten. Ansonsten wird das
programmieren immer kompliziert und schwierig bleiben. So bleibt mir nur
noch auf ein paar Dinge hinzuweisen:
- binär und dezimal sind nur Darstellung von Daten/Zahlen. Der Wert im
Speicher ist davon komplett unabhängig. Somit werden die Daten nicht
binär oder dezimal zurück gegeben.
- Was ist mit der Nachkommastelle? Diese wird nun natürlich weggeworfen
- aber ich dachte die wäre wichtig?
- die lcd_string() Routine nimmt nur einen Parameter und nicht zwei. Ein
formatiertes String replacement musst Du somit selbst vorher machen.
Aber solche grundlegenden Sachen kann man auch jetzt schon testen: die
IDE, Compiler etc. für den AVR bekommt man kostenlos. Und
compileren/bauen kann man somit den ganzen Quellcode auch jetzt schon.
Nur halt testen auf der Original-Hardware nicht. Aber solche
syntaktischen Fehler würden dann schon jetzt auffallen und korrigierbar.
Grüße und viel Erfolg morgen.
Grüße,
Muetze1
Hi!
Da ich gerade mal wieder eine Anfrage zu dem Code bekommen habe, stelle
ich hier noch einmal meinen aktuellen Stand des Codes ein. Dieser ist
ein wenig angepasst worden. Zum einen kann er nun DHT11 und DHT21/22
einlesen (und erkennen) und zum anderen kann er zwei Sensoren am
gleichen Port (aber unterschiedlichen Pins) einlesen. Gespeichert werden
die Daten in der Struct und kann durch die Funktionen ausgelesen werden.
Auch ein abziehen und späteres wieder anstecken oder Tausch der Sensoren
macht der Code problemlos mit.
Bezüglich der Port Konfiguration wird in der Datei die hwconfig.h
angezogen, welche die folgenden Definitionen enthält:
SENSOR_HUMIDITY_DDR
SENSOR_HUMIDITY_PORT
SENSOR_HUMIDITY_PIN
SENSOR_HUMIDITY1_SIG
SENSOR_HUMIDITY2_SIG
Wobei die Definitionen eindeutig sein sollten (DDR, PORT, PIN) und die
SIG Definitionen sollten das Port Bit sein (z.B. PD2).
Die readDHT() liest immer nur einen Sensor ein (0 oder 1) und sollte
auch nicht zu oft aufgerufen werden. Ich habe es bei mir alle halbe
Sekunde bis Sekunde angestoßen.
Grüße,
Muetze1