User | Revision | Line number | New contents of line |
s_inoue_mbed |
10:f0d789f49df7
|
1
|
/* Copyright (c) 2014 Shigenori Inoue, MIT License
|
s_inoue_mbed |
10:f0d789f49df7
|
2
|
*
|
s_inoue_mbed |
10:f0d789f49df7
|
3
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
s_inoue_mbed |
10:f0d789f49df7
|
4
|
* and associated documentation files (the "Software"), to deal in the Software without restriction,
|
s_inoue_mbed |
10:f0d789f49df7
|
5
|
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
s_inoue_mbed |
10:f0d789f49df7
|
6
|
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
s_inoue_mbed |
10:f0d789f49df7
|
7
|
* furnished to do so, subject to the following conditions:
|
s_inoue_mbed |
10:f0d789f49df7
|
8
|
*
|
s_inoue_mbed |
10:f0d789f49df7
|
9
|
* The above copyright notice and this permission notice shall be included in all copies or
|
s_inoue_mbed |
10:f0d789f49df7
|
10
|
* substantial portions of the Software.
|
s_inoue_mbed |
10:f0d789f49df7
|
11
|
*
|
s_inoue_mbed |
10:f0d789f49df7
|
12
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
s_inoue_mbed |
10:f0d789f49df7
|
13
|
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
s_inoue_mbed |
10:f0d789f49df7
|
14
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
s_inoue_mbed |
10:f0d789f49df7
|
15
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
s_inoue_mbed |
10:f0d789f49df7
|
16
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
s_inoue_mbed |
0:4d4c5ea17d86
|
17
|
*/
|
s_inoue_mbed |
0:4d4c5ea17d86
|
18
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
19
|
#include "DHT11.h"
|
s_inoue_mbed |
0:4d4c5ea17d86
|
20
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
21
|
// Constructor
|
s_inoue_mbed |
0:4d4c5ea17d86
|
22
|
DHT11::DHT11(PinName pin) : io(pin, PIN_INPUT, OpenDrain, 1), io_irq(pin)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
23
|
{
|
JohnnyK |
12:af1eadec17e5
|
24
|
io_irq.rise(callback(this, &DHT11::pos_edge));
|
JohnnyK |
12:af1eadec17e5
|
25
|
io_irq.fall(callback(this, &DHT11::neg_edge));
|
s_inoue_mbed |
0:4d4c5ea17d86
|
26
|
io_irq.disable_irq();
|
s_inoue_mbed |
9:056d1e9b428c
|
27
|
t.start();
|
s_inoue_mbed |
6:257e2ab66d0f
|
28
|
first_time = true;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
29
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
30
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
31
|
// Destructor
|
s_inoue_mbed |
0:4d4c5ea17d86
|
32
|
DHT11::~DHT11(void) {}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
33
|
|
s_inoue_mbed |
9:056d1e9b428c
|
34
|
// Constants
|
s_inoue_mbed |
9:056d1e9b428c
|
35
|
const int DHT11::t_tol_start = 2;
|
s_inoue_mbed |
9:056d1e9b428c
|
36
|
const int DHT11::t_tol_pulse = 10;
|
s_inoue_mbed |
9:056d1e9b428c
|
37
|
|
s_inoue_mbed |
6:257e2ab66d0f
|
38
|
// Reading the data bits from the DHT11
|
s_inoue_mbed |
9:056d1e9b428c
|
39
|
int DHT11::readData(void)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
40
|
{
|
s_inoue_mbed |
9:056d1e9b428c
|
41
|
// Checking the measurement frequency
|
JohnnyK |
12:af1eadec17e5
|
42
|
if (chrono::duration_cast<chrono::milliseconds>(t.elapsed_time()).count() < 2000 && first_time == false) {
|
s_inoue_mbed |
9:056d1e9b428c
|
43
|
t.reset();
|
s_inoue_mbed |
9:056d1e9b428c
|
44
|
return READ_TOO_OFTEN;
|
s_inoue_mbed |
9:056d1e9b428c
|
45
|
}
|
s_inoue_mbed |
9:056d1e9b428c
|
46
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
47
|
// Initialize
|
s_inoue_mbed |
6:257e2ab66d0f
|
48
|
init();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
49
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
50
|
// Checking the data bus
|
s_inoue_mbed |
0:4d4c5ea17d86
|
51
|
if (io == 0) {
|
s_inoue_mbed |
9:056d1e9b428c
|
52
|
t.reset();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
53
|
return BUS_BUSY;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
54
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
55
|
|
s_inoue_mbed |
9:056d1e9b428c
|
56
|
// Sending start signal, low signal for around 10 ms
|
s_inoue_mbed |
0:4d4c5ea17d86
|
57
|
t.reset();
|
s_inoue_mbed |
11:e91c151d1798
|
58
|
io.output();
|
s_inoue_mbed |
11:e91c151d1798
|
59
|
io = 0;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
60
|
do {
|
JohnnyK |
12:af1eadec17e5
|
61
|
} while (chrono::duration_cast<chrono::milliseconds>(t.elapsed_time()).count() < 20 + t_tol_start);
|
s_inoue_mbed |
11:e91c151d1798
|
62
|
io.input();
|
s_inoue_mbed |
7:50f5c8efd967
|
63
|
io = 1;
|
s_inoue_mbed |
11:e91c151d1798
|
64
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
65
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
66
|
// Waiting for the start of the response signal
|
s_inoue_mbed |
0:4d4c5ea17d86
|
67
|
t.reset();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
68
|
do {
|
JohnnyK |
12:af1eadec17e5
|
69
|
if (t.elapsed_time().count() > 100) {
|
s_inoue_mbed |
9:056d1e9b428c
|
70
|
t.reset();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
71
|
return NOT_PRESENT;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
72
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
73
|
} while (io == 1);
|
s_inoue_mbed |
0:4d4c5ea17d86
|
74
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
75
|
// Wainting for the start of the ready signal
|
s_inoue_mbed |
0:4d4c5ea17d86
|
76
|
t.reset();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
77
|
do {
|
JohnnyK |
12:af1eadec17e5
|
78
|
if (t.elapsed_time().count() > 100) {
|
s_inoue_mbed |
9:056d1e9b428c
|
79
|
t.reset();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
80
|
return NOT_READY;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
81
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
82
|
} while (io == 0);
|
s_inoue_mbed |
0:4d4c5ea17d86
|
83
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
84
|
// Wainting for the end of the ready signal
|
s_inoue_mbed |
0:4d4c5ea17d86
|
85
|
t.reset();
|
s_inoue_mbed |
9:056d1e9b428c
|
86
|
do {
|
JohnnyK |
12:af1eadec17e5
|
87
|
if (t.elapsed_time().count() > 100) {
|
s_inoue_mbed |
9:056d1e9b428c
|
88
|
t.reset();
|
s_inoue_mbed |
9:056d1e9b428c
|
89
|
return WATCHDOG_ERR;
|
s_inoue_mbed |
9:056d1e9b428c
|
90
|
}
|
s_inoue_mbed |
9:056d1e9b428c
|
91
|
} while (io == 1);
|
s_inoue_mbed |
0:4d4c5ea17d86
|
92
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
93
|
// Starting the pulse width sensing
|
s_inoue_mbed |
9:056d1e9b428c
|
94
|
// by the use of interruptions
|
s_inoue_mbed |
0:4d4c5ea17d86
|
95
|
io_irq.enable_irq();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
96
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
97
|
do {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
98
|
wait_us(100);
|
s_inoue_mbed |
0:4d4c5ea17d86
|
99
|
if (wdt > 50) {
|
s_inoue_mbed |
9:056d1e9b428c
|
100
|
t.reset();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
101
|
return WATCHDOG_ERR;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
102
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
103
|
wdt++;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
104
|
} while (eod == false);
|
s_inoue_mbed |
0:4d4c5ea17d86
|
105
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
106
|
// Calculating the check sum
|
s_inoue_mbed |
0:4d4c5ea17d86
|
107
|
chksum = ((data & 0xff00000000) >> 32)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
108
|
+ ((data & 0x00ff000000) >> 24)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
109
|
+ ((data & 0x0000ff0000) >> 16)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
110
|
+ ((data & 0x000000ff00) >> 8);
|
s_inoue_mbed |
9:056d1e9b428c
|
111
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
112
|
if (chksum != (data & 0x00000000ff)) {
|
s_inoue_mbed |
9:056d1e9b428c
|
113
|
t.reset();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
114
|
return CHKSUM_ERR;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
115
|
} else {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
116
|
t.reset();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
117
|
first_time = false;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
118
|
return OK;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
119
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
120
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
121
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
122
|
// Extracting humidity data from the received data
|
s_inoue_mbed |
9:056d1e9b428c
|
123
|
int DHT11::readHumidity(void)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
124
|
{
|
s_inoue_mbed |
9:056d1e9b428c
|
125
|
return (data & 0xff00000000) >> 32;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
126
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
127
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
128
|
// Extracting temperature data from the received data
|
s_inoue_mbed |
9:056d1e9b428c
|
129
|
int DHT11::readTemperature(void)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
130
|
{
|
s_inoue_mbed |
9:056d1e9b428c
|
131
|
return (data & 0x0000ff0000) >> 16;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
132
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
133
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
134
|
// Initialization of variables
|
s_inoue_mbed |
0:4d4c5ea17d86
|
135
|
void DHT11::init(void)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
136
|
{
|
s_inoue_mbed |
0:4d4c5ea17d86
|
137
|
t_pulse_us = 0;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
138
|
data = 0;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
139
|
chksum = 0;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
140
|
cnt = 0;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
141
|
wdt = 0;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
142
|
eod = false;
|
s_inoue_mbed |
9:056d1e9b428c
|
143
|
t.reset();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
144
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
145
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
146
|
void DHT11::pos_edge(void)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
147
|
{
|
s_inoue_mbed |
0:4d4c5ea17d86
|
148
|
// Disabling the interruptions
|
s_inoue_mbed |
0:4d4c5ea17d86
|
149
|
io_irq.disable_irq();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
150
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
151
|
// Initializing the Timer
|
s_inoue_mbed |
0:4d4c5ea17d86
|
152
|
t.reset();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
153
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
154
|
// Enabling the interruptions
|
s_inoue_mbed |
0:4d4c5ea17d86
|
155
|
io_irq.enable_irq();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
156
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
157
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
158
|
void DHT11::neg_edge(void)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
159
|
{
|
s_inoue_mbed |
0:4d4c5ea17d86
|
160
|
// Disabling the interruptions
|
s_inoue_mbed |
0:4d4c5ea17d86
|
161
|
io_irq.disable_irq();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
162
|
|
s_inoue_mbed |
8:160047ca45bf
|
163
|
// Reading the positive pulse width
|
JohnnyK |
12:af1eadec17e5
|
164
|
t_pulse_us = t.elapsed_time().count();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
165
|
|
s_inoue_mbed |
9:056d1e9b428c
|
166
|
// Detecting 0 if the pulse width ranges around 25 us
|
s_inoue_mbed |
9:056d1e9b428c
|
167
|
if (25 - t_tol_pulse <= t_pulse_us && t_pulse_us <= 30 + t_tol_pulse) {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
168
|
// Shifting the data buffer and not adding 1 (because this bit is zero)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
169
|
data = data << 1;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
170
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
171
|
// Counting up the bits
|
s_inoue_mbed |
0:4d4c5ea17d86
|
172
|
cnt++;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
173
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
174
|
|
s_inoue_mbed |
9:056d1e9b428c
|
175
|
// Detecting 1 if the pulse width ranges from 70 us
|
s_inoue_mbed |
9:056d1e9b428c
|
176
|
else if (70 - t_tol_pulse <= t_pulse_us && t_pulse_us <= 70 + t_tol_pulse) {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
177
|
// Shifting the data buffer and adding 1 (because this bit is one)
|
s_inoue_mbed |
0:4d4c5ea17d86
|
178
|
data = data << 1;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
179
|
data++;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
180
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
181
|
// Counting up the bits
|
s_inoue_mbed |
0:4d4c5ea17d86
|
182
|
cnt++;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
183
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
184
|
|
s_inoue_mbed |
0:4d4c5ea17d86
|
185
|
// Detecting the end of Data
|
s_inoue_mbed |
0:4d4c5ea17d86
|
186
|
if (cnt < 40) {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
187
|
// Enabling the interruptions
|
s_inoue_mbed |
0:4d4c5ea17d86
|
188
|
io_irq.enable_irq();
|
s_inoue_mbed |
0:4d4c5ea17d86
|
189
|
} else {
|
s_inoue_mbed |
0:4d4c5ea17d86
|
190
|
eod = true;
|
s_inoue_mbed |
0:4d4c5ea17d86
|
191
|
}
|
s_inoue_mbed |
0:4d4c5ea17d86
|
192
|
} |