User | Revision | Line number | New contents of line |
s_inoue_mbed |
4:48798b126d93
|
1
|
/*
|
s_inoue_mbed |
4:48798b126d93
|
2
|
* Library for the use of the DHT11, a temperature and humidity sensor
|
s_inoue_mbed |
4:48798b126d93
|
3
|
* Shigenori Inoue, September 10, 2014
|
s_inoue_mbed |
0:4d4c5ea17d86
|
4
|
*/
|
s_inoue_mbed |
0:4d4c5ea17d86
|
5
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
6
|
#include "DHT11.h"
|
s_inoue_mbed |
0:4d4c5ea17d86
|
7
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
8
|
// Constructor
|
s_inoue_mbed |
0:4d4c5ea17d86
|
9
|
DHT11::DHT11(PinName pin) : io(pin, PIN_INPUT, OpenDrain, 1), io_irq(pin)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
10
|
{
|
s_inoue_mbed |
0:4d4c5ea17d86
|
11
|
io_irq.rise(this, &DHT11::pos_edge);
|
s_inoue_mbed |
0:4d4c5ea17d86
|
12
|
io_irq.fall(this, &DHT11::neg_edge);
|
s_inoue_mbed |
0:4d4c5ea17d86
|
13
|
io_irq.disable_irq();
|
s_inoue_mbed |
6:257e2ab66d0f
|
14
|
init();
|
s_inoue_mbed |
6:257e2ab66d0f
|
15
|
first_time = true;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
16
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
17
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
18
|
// Destructor
|
s_inoue_mbed |
0:4d4c5ea17d86
|
19
|
DHT11::~DHT11(void) {}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
20
|
|
s_inoue_mbed |
6:257e2ab66d0f
|
21
|
// Reading the data bits from the DHT11
|
s_inoue_mbed |
0:4d4c5ea17d86
|
22
|
int DHT11::readData()
|
s_inoue_mbed |
0:4d4c5ea17d86
|
23
|
{
|
s_inoue_mbed |
0:4d4c5ea17d86
|
24
|
// Initialize
|
s_inoue_mbed |
6:257e2ab66d0f
|
25
|
init();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
26
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
27
|
// Checking the measurement frequency
|
s_inoue_mbed |
0:4d4c5ea17d86
|
28
|
if (t.read_ms() < 2000 & first_time == false) {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
29
|
t.reset();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
30
|
return TOO_FAST_READ;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
31
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
32
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
33
|
// Checking the data bus
|
s_inoue_mbed |
0:4d4c5ea17d86
|
34
|
if (io == 0) {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
35
|
io.input();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
36
|
return BUS_BUSY;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
37
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
38
|
|
s_inoue_mbed |
8:160047ca45bf
|
39
|
// Sending start signal, low signal for 20 ms
|
s_inoue_mbed |
0:4d4c5ea17d86
|
40
|
io.output();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
41
|
t.reset();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
42
|
t.start();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
43
|
do {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
44
|
io = 0;
|
s_inoue_mbed |
8:160047ca45bf
|
45
|
} while (t.read_ms() < 20);
|
s_inoue_mbed |
7:50f5c8efd967
|
46
|
io = 1;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
47
|
io.input();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
48
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
49
|
// Waiting for the start of the response signal
|
s_inoue_mbed |
0:4d4c5ea17d86
|
50
|
t.reset();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
51
|
t.start();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
52
|
do {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
53
|
if (t.read_us() > 100) {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
54
|
io.input();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
55
|
return NOT_PRESENT;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
56
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
57
|
} while (io == 1);
|
s_inoue_mbed |
0:4d4c5ea17d86
|
58
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
59
|
// Wainting for the start of the ready signal
|
s_inoue_mbed |
0:4d4c5ea17d86
|
60
|
t.reset();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
61
|
t.start();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
62
|
do {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
63
|
if (t.read_us() > 100) {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
64
|
io.input();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
65
|
return NOT_READY;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
66
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
67
|
} while (io == 0);
|
s_inoue_mbed |
0:4d4c5ea17d86
|
68
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
69
|
// Wainting for the end of the ready signal
|
s_inoue_mbed |
0:4d4c5ea17d86
|
70
|
t.reset();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
71
|
t.start();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
72
|
do {} while (io == 1);
|
s_inoue_mbed |
0:4d4c5ea17d86
|
73
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
74
|
// Starting the pulse width sensing
|
s_inoue_mbed |
0:4d4c5ea17d86
|
75
|
io_irq.enable_irq();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
76
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
77
|
do {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
78
|
wait_us(100);
|
s_inoue_mbed |
0:4d4c5ea17d86
|
79
|
if (wdt > 50) {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
80
|
return WATCHDOG_ERR;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
81
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
82
|
wdt++;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
83
|
} while (eod == false);
|
s_inoue_mbed |
0:4d4c5ea17d86
|
84
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
85
|
// Calculating the check sum
|
s_inoue_mbed |
0:4d4c5ea17d86
|
86
|
chksum = ((data & 0xff00000000) >> 32)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
87
|
+ ((data & 0x00ff000000) >> 24)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
88
|
+ ((data & 0x0000ff0000) >> 16)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
89
|
+ ((data & 0x000000ff00) >> 8);
|
s_inoue_mbed |
0:4d4c5ea17d86
|
90
|
if (chksum != (data & 0x00000000ff)) {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
91
|
return CHKSUM_ERR;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
92
|
} else {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
93
|
t.reset();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
94
|
first_time = false;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
95
|
return OK;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
96
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
97
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
98
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
99
|
// Extracting humidity data from the received data
|
s_inoue_mbed |
0:4d4c5ea17d86
|
100
|
int DHT11::readHumidity()
|
s_inoue_mbed |
0:4d4c5ea17d86
|
101
|
{
|
s_inoue_mbed |
0:4d4c5ea17d86
|
102
|
if (err == OK) {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
103
|
return (data & 0xff00000000) >> 32;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
104
|
} else {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
105
|
return 0xffffffff;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
106
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
107
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
108
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
109
|
// Extracting temperature data from the received data
|
s_inoue_mbed |
0:4d4c5ea17d86
|
110
|
int DHT11::readTemperature()
|
s_inoue_mbed |
0:4d4c5ea17d86
|
111
|
{
|
s_inoue_mbed |
0:4d4c5ea17d86
|
112
|
if (err == OK) {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
113
|
return (data & 0x0000ff0000) >> 16;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
114
|
} else {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
115
|
return 0xffffffff;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
116
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
117
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
118
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
119
|
// Initialization of variables
|
s_inoue_mbed |
0:4d4c5ea17d86
|
120
|
void DHT11::init(void)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
121
|
{
|
s_inoue_mbed |
0:4d4c5ea17d86
|
122
|
t_pulse_us = 0;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
123
|
data = 0;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
124
|
chksum = 0;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
125
|
cnt = 0;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
126
|
wdt = 0;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
127
|
err = OK;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
128
|
eod = false;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
129
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
130
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
131
|
void DHT11::pos_edge(void)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
132
|
{
|
s_inoue_mbed |
0:4d4c5ea17d86
|
133
|
// Disabling the interruptions
|
s_inoue_mbed |
0:4d4c5ea17d86
|
134
|
io_irq.disable_irq();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
135
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
136
|
// Initializing the Timer
|
s_inoue_mbed |
0:4d4c5ea17d86
|
137
|
t.reset();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
138
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
139
|
// Enabling the interruptions
|
s_inoue_mbed |
0:4d4c5ea17d86
|
140
|
io_irq.enable_irq();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
141
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
142
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
143
|
void DHT11::neg_edge(void)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
144
|
{
|
s_inoue_mbed |
0:4d4c5ea17d86
|
145
|
// Disabling the interruptions
|
s_inoue_mbed |
0:4d4c5ea17d86
|
146
|
io_irq.disable_irq();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
147
|
|
s_inoue_mbed |
8:160047ca45bf
|
148
|
// Reading the positive pulse width
|
s_inoue_mbed |
0:4d4c5ea17d86
|
149
|
t_pulse_us = t.read_us();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
150
|
|
s_inoue_mbed |
8:160047ca45bf
|
151
|
// Detecting 0 if the pulse width ranges from 20 us to 30 us
|
s_inoue_mbed |
0:4d4c5ea17d86
|
152
|
if (20 <= t_pulse_us && t_pulse_us <= 30) {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
153
|
// Shifting the data buffer and not adding 1 (because this bit is zero)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
154
|
data = data << 1;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
155
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
156
|
// Counting up the bits
|
s_inoue_mbed |
0:4d4c5ea17d86
|
157
|
cnt++;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
158
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
159
|
|
s_inoue_mbed |
8:160047ca45bf
|
160
|
// Detecting 1 if the pulse width ranges from 60 us to 80 us
|
s_inoue_mbed |
0:4d4c5ea17d86
|
161
|
else if (60 <= t_pulse_us && t_pulse_us <= 80) {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
162
|
// Shifting the data buffer and adding 1 (because this bit is one)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
163
|
data = data << 1;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
164
|
data++;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
165
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
166
|
// Counting up the bits
|
s_inoue_mbed |
0:4d4c5ea17d86
|
167
|
cnt++;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
168
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
169
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
170
|
// Detecting the end of Data
|
s_inoue_mbed |
0:4d4c5ea17d86
|
171
|
if (cnt < 40) {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
172
|
// Enabling the interruptions
|
s_inoue_mbed |
0:4d4c5ea17d86
|
173
|
io_irq.enable_irq();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
174
|
} else {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
175
|
eod = true;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
176
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
177
|
} |