-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathdht.c
148 lines (129 loc) · 3.3 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
139
140
141
142
143
144
145
146
147
148
/*
DHT Library 0x03
copyright (c) Davide Gironi, 2012
Released under GPLv3.
Please refer to LICENSE file for licensing information.
*/
#include <stdio.h>
#include <string.h>
#include <avr/io.h>
#include <util/delay.h>
#include "dht.h"
/*
* get data from sensor
*/
#if DHT_FLOAT == 1
int8_t dht_getdata(float *temperature, float *humidity) {
#elif DHT_FLOAT == 0
int8_t dht_getdata(int8_t *temperature, int8_t *humidity) {
#endif
uint8_t bits[5];
uint8_t i,j = 0;
memset(bits, 0, sizeof(bits));
//reset port
DHT_DDR |= (1<<DHT_INPUTPIN); //output
DHT_PORT |= (1<<DHT_INPUTPIN); //high
_delay_ms(100);
//send request
DHT_PORT &= ~(1<<DHT_INPUTPIN); //low
#if DHT_TYPE == DHT_DHT11
_delay_ms(18);
#elif DHT_TYPE == DHT_DHT22
_delay_us(500);
#endif
DHT_PORT |= (1<<DHT_INPUTPIN); //high
DHT_DDR &= ~(1<<DHT_INPUTPIN); //input
_delay_us(40);
//check start condition 1
if((DHT_PIN & (1<<DHT_INPUTPIN))) {
return -1;
}
_delay_us(80);
//check start condition 2
if(!(DHT_PIN & (1<<DHT_INPUTPIN))) {
return -1;
}
_delay_us(80);
//read the data
uint16_t timeoutcounter = 0;
for (j=0; j<5; j++) { //read 5 byte
uint8_t result=0;
for(i=0; i<8; i++) {//read every bit
timeoutcounter = 0;
while(!(DHT_PIN & (1<<DHT_INPUTPIN))) { //wait for an high input (non blocking)
timeoutcounter++;
if(timeoutcounter > DHT_TIMEOUT) {
return -1; //timeout
}
}
_delay_us(30);
if(DHT_PIN & (1<<DHT_INPUTPIN)) //if input is high after 30 us, get result
result |= (1<<(7-i));
timeoutcounter = 0;
while(DHT_PIN & (1<<DHT_INPUTPIN)) { //wait until input get low (non blocking)
timeoutcounter++;
if(timeoutcounter > DHT_TIMEOUT) {
return -1; //timeout
}
}
}
bits[j] = result;
}
//reset port
DHT_DDR |= (1<<DHT_INPUTPIN); //output
DHT_PORT |= (1<<DHT_INPUTPIN); //low
_delay_ms(100);
//check checksum
if ((uint8_t)(bits[0] + bits[1] + bits[2] + bits[3]) == bits[4]) {
//return temperature and humidity
#if DHT_TYPE == DHT_DHT11
*temperature = bits[2];
*humidity = bits[0];
#elif DHT_TYPE == DHT_DHT22
uint16_t rawhumidity = bits[0]<<8 | bits[1];
uint16_t rawtemperature = bits[2]<<8 | bits[3];
if(rawtemperature & 0x8000) {
*temperature = (float)((rawtemperature & 0x7FFF) / 10.0) * -1.0;
} else {
*temperature = (float)(rawtemperature)/10.0;
}
*humidity = (float)(rawhumidity)/10.0;
#endif
return 0;
}
return -1;
}
/*
* get temperature
*/
#if DHT_FLOAT == 1
int8_t dht_gettemperature(float *temperature) {
float humidity = 0;
#elif DHT_FLOAT == 0
int8_t dht_gettemperature(int8_t *temperature) {
int8_t humidity = 0;
#endif
return dht_getdata(temperature, &humidity);
}
/*
* get humidity
*/
#if DHT_FLOAT == 1
int8_t dht_gethumidity(float *humidity) {
float temperature = 0;
#elif DHT_FLOAT == 0
int8_t dht_gethumidity(int8_t *humidity) {
int8_t temperature = 0;
#endif
return dht_getdata(&temperature, humidity);
}
/*
* get temperature and humidity
*/
#if DHT_FLOAT == 1
int8_t dht_gettemperaturehumidity(float *temperature, float *humidity) {
#elif DHT_FLOAT == 0
int8_t dht_gettemperaturehumidity(int8_t *temperature, int8_t *humidity) {
#endif
return dht_getdata(temperature, humidity);
}