Dht22 alias AM2302 mit 8051 - Timingfrage

Gast #4480828
Lesenswert?

Hi!

Habe mir einen DHT22 bestellt um damit vorrangig die Luftfeuchtigkeit zu 
messen. Habe eine Routine für den 8051 geschrieben um ihn anzusteuern, 
kann das ganze aber leider noch nicht ausprobieren, da der Sensor noch 
unterwegs ist.
Die delays habe ich per Oszi gemessen und entsprechend gewählt. Dennoch 
bin ich mir nicht sicher ob ich was im Datenblatt übersehen oder falsch 
verstanden habe.

https://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf

Es wäre daher super wenn sich jemand, der das schonmal gemacht hat 
angucken, und mir Tipps geben könnte was ich noch verbessern kann.

Fragen, die ich mir stelle sind, ob die Timings so stimmen und wie man 
mehrere Sensoren ansteueren könnte.

Danke fürs Angucken!
1
#include <dht22.h>
2

3
//Returns 1 if error, 0 if no error
4
unsigned char ReadData()
5
{
6
  unsigned char checksum=0;
7
  unsigned char humi_low=0, humi_high=0;
8
  unsigned char temp_low=0, temp_high=0;
9

10
   if (!SendStartSignal())
11
    return 1;
12
  
13
  humi_low = ReadByte();
14
  humi_high = ReadByte();
15
  
16
  temp_low = ReadByte();
17
  temp_high = ReadByte();
18
  
19
  checksum = ReadByte();
20

21
  if (checksum == (humi_low + humi_high + temp_low + temp_high))
22
  {
23
    HUMI = humi_high;
24
    HUMI <<= 8;
25
    HUMI |= humi_low;
26

27
    TEMP = temp_high;
28
    TEMP <<= 8;
29
    TEMP |= temp_low;
30
    return 0;
31
  }
32
  else
33
  {
34
    HUMI = 0;
35
    TEMP = 0;
36
    return 1;
37
  }
38
}
39

40
unsigned char SendStartSignal()
41
{
42
  unsigned char i=0, buf=0;
43

44
  DATA = 0;       //Pull low 1-10ms
45
  Wait1Ms(5);       //Delay 5ms
46
  DATA = 1;       //Pull up 20-40us
47
  for (i=0; i<5; i++); //Delay ~47us
48
  buf = DATA;
49
  for (i=0; i<10; i++); //Delay ~83us
50
  for (i=0; i<10; i++); //Delay ~83us
51
  return buf;       //0 = Slave vorhanden, 1 = kein Slave vorhanden
52
}
53

54
unsigned char ReadByte()
55
{
56
  unsigned char i;
57
  unsigned char byte=0;
58

59
  for (i=0; i<8; i++)
60
  {
61
    byte |= ReadBit();
62
    byte <<= 1;  
63
  }
64
  return byte;
65
}
66

67
unsigned char ReadBit()
68
{
69
  unsigned char i;
70

71
  while (!DATA);      //Waiting for start of bit
72
  for (i=0; i<3; i++);   //Delay ~32us
73
  if (DATA)
74
  {
75
    for (i=0; i<3; i++); //Delay ~32us
76
    return 1;
77
  }
78
  else
79
    return 0;
80
}
Gast #4480891
Lesenswert?

Der folgende Absatz lässt sich per Oszi prüfen, sollte also nicht weg 
optimiert werden.
1
void main (void)
2
{
3
    unsigned char i;
4

5
    while (1)
6
    {
7
        P0_0 = 1;
8
        for (i=0; i<10; i++);
9
        P0_0 = 0;
10
    }
11
}
Gast #4480892
Lesenswert?

Christian H. schrieb:
> Hast Du im Assembler-Listing überprüft, dass eine entsprechende
> Verzögerung erreicht wird?

> Könnte sein, dass die Schleife weg optimiert wird.

Hast du Sorgen, dass das Oszi lügt und Zeitsprünge macht?
Wenn die Zeiten richtig am Pin raus kommen, werden sie wohl richtig raus 
kommen.

Diek schrieb:
> Die delays habe ich per Oszi gemessen
Gast #4483708
Lesenswert?

An alle die es interessiert, dieser Code funktioniert bestens zu 
Ansteuerung mit einer F_CPU von 11.059Mhz:
1
#include <dht22.h>
2
#include <lcd_config.h>
3

4
//Returns 1 if error, 0 if no error
5
unsigned char ReadData()
6
{
7
  unsigned char checksum=0;
8
  unsigned char humi_low=0, humi_high=0;
9
  unsigned char temp_low=0, temp_high=0;
10
  
11
  EA = 0;
12
   if (SendStartSignal() == 1)
13
    return 2;
14
  
15
  humi_high = ReadByte();
16
  humi_low = ReadByte();
17
  
18
  temp_high = ReadByte();
19
  temp_low = ReadByte();
20
  
21
  checksum = ReadByte();
22
  EA = 1;
23
  
24
  /*P1=humi_high;
25
  Wait1Ms(1000);
26
  P1=humi_low;
27
  Wait1Ms(1000);
28
  P1=temp_high;
29
  Wait1Ms(1000);
30
  P1=temp_low;
31
  Wait1Ms(1000);
32
  P1=checksum;
33
  Wait1Ms(1000);*/
34
  
35
  if (checksum == ((humi_low + humi_high + temp_low + temp_high)&0xFF))
36
  {
37
    HUMI = humi_high;
38
    HUMI <<= 8;
39
    HUMI |= humi_low;
40

41
    TEMP = temp_high;
42
    TEMP <<= 8;
43
    TEMP |= temp_low;
44
    return 0;
45
  }
46
  else
47
  {
48
    HUMI = 0;
49
    TEMP = 0;
50
    return 1;
51
  }
52
}
53

54
unsigned char SendStartSignal()
55
{
56
  unsigned char i=0, buf=0;
57
  DATA = 1;
58
  Wait1Ms(1000);
59
  DATA = 0;       //Pull low 1-10ms
60
  Wait1Ms(5);       //Delay 5ms
61
  DATA = 1;       //Pull up 20-40us
62
  for (i=0; i<7; i++); 
63
  buf = DATA;
64
  while (!DATA);
65
  while (DATA);
66

67
  return buf;       //0 = Slave vorhanden, 1 = kein Slave vorhanden
68
}
69

70
unsigned char ReadByte()
71
{
72
  unsigned char i;
73
  unsigned char byte=0;
74

75
  for (i=0; i<7; i++)
76
  {
77
    byte |= ReadBit();
78
    byte <<= 1;  
79
  }
80
  byte |= ReadBit();
81

82
  return byte;
83
}
84

85
unsigned char ReadBit()
86
{
87
  unsigned char i=0;
88

89
  while (!DATA);      //Waiting for start of bit
90
  while (DATA)
91
  {
92
    i++;
93
  }
94
  if (i<11)
95
    return 0;
96
  else
97
    return 1;
98
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren