Forum: Mikrocontroller und Digitale Elektronik Dht22 alias AM2302 mit 8051 - Timingfrage


von Diek (Gast)


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
}

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Diek schrieb:
> for (i=0; i<10; i++); //Delay ~83us

Hast Du im Assembler-Listing überprüft, dass eine entsprechende 
Verzögerung erreicht wird?

Könnte sein, dass die Schleife weg optimiert wird.
Außer (hier) i auf 10 zu setzen passiert hier ja nichts. Darüber hinaus 
wird i nirgendwo wirklich verwendet.

von Diek (Gast)


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
}

von Wolfgang (Gast)


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

von Diek (Gast)


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
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.