-
Notifications
You must be signed in to change notification settings - Fork 14
/
DHT.c
138 lines (97 loc) · 3.2 KB
/
DHT.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "DHT.h"
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
uint8_t data [4];
int8_t i;
initDHT();
if(fetchData(data))
{
for(i = data[2]; i >= 0; --i)
{
SET_BIT(PORTB,LED);
_delay_ms(100);
CLEAR_BIT(PORTB,LED);
_delay_ms(500);
}
}
return 0;
}
void initDHT(void)
{
/* Set LED as output */
SET_BIT(DDRB,LED);
/* According to the DHT11's datasheet, the sensor needs about
1-2 seconds to get ready when first getting power, so we
wait
*/
_delay_ms(2000);
}
uint8_t fetchData(uint8_t* arr)
{
uint8_t data [5];
uint8_t cnt, check;
int8_t i,j;
/******************* Sensor communication start *******************/
/* Set data pin as output first */
SET_BIT(DDRB,DHT_PIN);
/* First we need milliseconds delay, so set clk/1024 prescaler */
TCCR0B = 0x05;
TCNT0 = 0;
/* Clear bit for 20 ms */
CLEAR_BIT(DHT_PORT_OUT,DHT_PIN);
/* Wait about 20 ms */
while(TCNT0 < 160);
/* Now set Timer0 with clk/8 prescaling.
Gives 1µs per cycle @8Mhz */
TCCR0B = 0x02;
TCNT0 = 0;
/* Pull high again */
SET_BIT(DHT_PORT_OUT,DHT_PIN);
/* And set data pin as input */
CLEAR_BIT(DDRB,DHT_PIN);
/* Wait for response from sensor, 20-40µs according to datasheet */
while(IS_SET(DHT_PORT_IN,DHT_PIN))
{ if (TCNT0 >= 60) return 0; }
/************************* Sensor preamble *************************/
TCNT0 = 0;
/* Now wait for the first response to finish, low ~80µs */
while(!IS_SET(DHT_PORT_IN,DHT_PIN))
{ if (TCNT0 >= 100) return 0; }
TCNT0 = 0;
/* Then wait for the second response to finish, high ~80µs */
while(IS_SET(DHT_PORT_IN,DHT_PIN))
{ if (TCNT0 >= 100) return 0; }
/********************* Data transmission start **********************/
for (i = 0; i < 5; ++i)
{
for(j = 7; j >= 0; --j)
{
TCNT0 = 0;
/* First there is always a 50µs low period */
while(!IS_SET(DHT_PORT_IN,DHT_PIN))
{ if (TCNT0 >= 70) return 0; }
TCNT0 = 0;
/* Then the data signal is sent. 26 to 28µs (ideally)
indicate a low bit, and around 70µs a high bit */
while(IS_SET(DHT_PORT_IN,DHT_PIN))
{ if (TCNT0 >= 90) return 0; }
/* Store the value now so that the whole checking doesn't
move the TCNT0 forward by too much to make the data look
bad */
cnt = TCNT0;
if (cnt >= 20 && cnt <= 35)
{ CLEAR_BIT(data[i],j); }
else if (cnt >= 60 && cnt <= 80)
{ SET_BIT(data[i],j); }
else return 0;
}
}
/********************* Sensor communication end *********************/
check = (data[0] + data[1] + data[2] + data[3]) & 0xFF;
if (check != data[4]) return 0;
for(i = 0; i < 4; ++i)
{ arr[i] = data[i]; }
return 1;
}