-
Notifications
You must be signed in to change notification settings - Fork 0
/
dht.c
163 lines (128 loc) · 4.22 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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
* dht11.h Copyright (C) 2016 Ron Pedde <ron@pedde.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <avr/io.h>
#include <util/delay.h>
#include "util.h"
#include "hardware.h"
#include "sensor.h"
#include "dht.h"
static uint8_t dht_data[5];
static char *label="dht: ";
static int sample_count = DHT_INTERVAL;
void dht_init(void) {
DPUTS(label); DPUTS("init"); DCR;
// input
CLEARBIT(DHT_DDR, DHT_PIN);
_delay_ms(2000);
}
void dht_sleep(void) {
}
void dht_wake(void) {
}
static int dht_wait_for_value(int val, int timeout) {
int res;
TCNT0 = 0;
while(TCNT0 < timeout) {
res = (DHT_INP) & _BV(DHT_PIN);
if ((res == 0) && (val == 0))
return TCNT0;
if (res && val)
return TCNT0;
/* if((!res && !val) || (res && val)) */
/* return TCNT0; */
}
return TCNT0;
}
int dht_get(void) {
int res;
sample_count++;
if(sample_count < DHT_INTERVAL) {
return FALSE;
}
sample_count = 0;
DPUTS(label); DPUTS("read "); DPUTS("start"); DCR;
SETBIT(DHT_DDR, DHT_PIN); /* set to output */
CLEARBIT(DHT_OUTP, DHT_PIN); /* output low */
/* This might need to be adjusted for dht11 and 22
* Longer delay (50ms) seems to work fine on 11, but not 22. */
_delay_ms(20); /* min 18ms */
SETBIT(DHT_OUTP, DHT_PIN); /* and high */
CLEARBIT(DHT_DDR, DHT_PIN); /* set for input */
/* set up prescalar for timer0 */
DHT_PRESCALE_REG |= \
(DHT_CS00 << CS00) | \
(DHT_CS01 << CS01) | \
(DHT_CS02 << CS02);
if((res = dht_wait_for_value(0, DHT_FORTY)) > DHT_FORTY) {
DPUTS(label); DPUTS("fail:"); DPUTS("0"); DCR;
return FALSE;
}
if((res = dht_wait_for_value(1, DHT_HUNDRED)) > DHT_HUNDRED) {
DPUTS(label); DPUTS("fail:"); DPUTS("1"); DCR;
return FALSE;
}
if(dht_wait_for_value(0, DHT_HUNDRED) > DHT_HUNDRED) {
DPUTS(label); DPUTS("fail:"); DPUTS("2"); DCR;
return FALSE;
}
for(int i=0; i<5; i++) {
for(int j=0; j<8; j++) {
if(dht_wait_for_value(1, DHT_EIGHTY) > DHT_EIGHTY) {
DPUTS(label); DPUTS("fail:"); DPUTS("3"); DCR;
return FALSE;
}
if(dht_wait_for_value(0, DHT_EIGHTY) > DHT_FORTY) {
SETBIT(dht_data[i], 7-j);
} else {
CLEARBIT(dht_data[i], 7-j);
}
}
}
/* should check the checksum */
uint8_t data = dht_data[0] + dht_data[1] + \
dht_data[2] + dht_data[3];
if (data != dht_data[4]) {
DPUTS(label); DPUTS("fail:"); DPUTS("4"); DCR;
return FALSE;
}
DPUTS(label);
for(int i=0; i<5; i++) {
DPUTBYTEX(dht_data[i]); DPUTS(" ");
}
DCR;
/* /\* DHT11 format *\/ */
/* if(DHT_SENSOR_MODEL == SENSOR_MODEL_DHT11) { */
/* DPRINTF("Humidity: %0d.%02d percent\n\r", dht_data[0], dht_data[1]); */
/* DPRINTF("Temperature: %0d.%02d degrees C\n\r", dht_data[2], dht_data[3]); */
/* } */
/* if(DHT_SENSOR_MODEL == SENSOR_MODEL_DHT22) { */
/* uint16_t h, t; */
/* h = dht_data[0] << 8 | dht_data[1]; */
/* t = dht_data[2] << 8 | dht_data[3]; */
/* /\* DHT22 (tenths) *\/ */
/* DPRINTF("Hum: %0.2f\n\r", (float)h/10.0); */
/* DPRINTF("Temp: %0.2f\n\r", ((float)t/10.0) * (9.0/5.0) + 32); */
/* } */
DPUTS(label); DPUTS("read "); DPUTS("end"); DCR;
return TRUE;
}
uint16_t dht_get_rh(void) {
return dht_data[0] << 8 | dht_data[1];
}
uint16_t dht_get_temp(void) {
return dht_data[2] << 8 | dht_data[3];
}