-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdht.cpp
126 lines (101 loc) · 3.23 KB
/
dht.cpp
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
#include "dht.h"
static DHTInterface* _interfaceDHT;
bool readDHT(int16_t* temp, int16_t* humid){
uint16_t checksum = 0, hm, tmp;
uint32_t lastTimeUs;
uint32_t currentTimeUs = timerUsStart();
int16_t tempCache = 0, humCache =0;
if ( ( currentTimeUs - lastTimeUs ) > DHT_DATA_HOLD_TIME_US ){
gpioSet(_interfaceDHT->signal, LOW);
sleepUs(DHT_START_LOW_TIME_US);
gpioSet(_interfaceDHT->signal, HIGH);
sleepUs(DHT_START_HIGH_TIME_US);
gpioInit(_interfaceDHT->signal, GPIO_IN);
if(_pollSignal(HIGH, DHT_TIMEOUT_US)){
resetDHT();
return false;
}
if(_pollSignal(LOW, DHT_TIMEOUT_US)){
resetDHT();
return false;
}
// read sensor values sequantially
if( !_readPulses( &hm, 16U ) ){ resetDHT(); return false; }
if( !_readPulses( &tmp, 16U ) ){ resetDHT(); return false; }
if( !_readPulses( &checksum, 8U ) ){ resetDHT(); return false; }
resetDHT();
// validate sensor data
uint8_t sum = (tmp >> 8) + (tmp & 0xff) + (hm >> 8) + (hm & 0xff);
if (sum != checksum) {
print("incorrect checksum! \n");
return false;
}
// parse values based on type of sensor used
switch (_interfaceDHT->sensorType){
case DHT11:
tempCache = (int16_t)((tmp >> 8) * 10);
humCache = (int16_t)((hm >> 8) * 10);
break;
case DHT21:
case DHT22:
humCache = (int16_t)(hm);
if (tmp & 0x8000){
tempCache = (int16_t)((tmp & ~0x8000) * -1); // negative
}else{
tempCache = (int16_t)tmp;
}
break;
default:
print("No or incorrect DHT version specified\n");
return false;
}
lastTimeUs = currentTimeUs;
}
if(temp != nullptr){
*temp = tempCache;
}
if(hum != nullptr){
*hum = humCache;
}
return true;
}
void startDHT(void){
resetDHT();
sleepMs(2000);
print("DHT sensor is online!\n");
}
void resetDHT(void){
gpioInit(_interfaceDHT->signal, GPIO_OUT);
gpioSet(_interfaceDHT->signal, HIGH);
}
void createDHT(WeatherSensor* self, DHTInterface* interface){
_interfaceDHT = interface;
self->read = &readDHT;
self->start = &startDHT;
self->reset = &resetDHT;
print( "DHT sensor sucessfully created! \n" );
}
int32_t _pollSignal(uint8_t state, uint32_t timeout){
while(
( gpioRead( _interfaceDHT->signal ) > 0 ) != state )
&& timeout
){
sleepUs(1);
timeout--;
}
return (timeout > 0) ? 0 : -1;
}
bool _readPulses(uint16_t* buff, uint8_t size){
uint16_t result = 0;
for(uint8_t i=0; i<size; i++){
uint32_t beginTime, endTimeUs;
result <<= 1;
if(_pollSignal(HIGH, DHT_TIMEOUT_US)){ return false; }
beginTimeUs = timerUsStart();
if(_pollSignal(LOW, DHT_TIMEOUT_US)){ return false; }
endTimeUs = timerUsStart();
if( (endTimeUs - beginTimeUs) > DHT_PULSE_WIDTH_THRESHOLD_US ){ result |= 0x001; }
}
*buff = result;
return true;
}