-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathMHZ19.cpp
164 lines (138 loc) · 3.04 KB
/
MHZ19.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
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
164
#include "MHZ19.h"
MHZ19::MHZ19(Stream * stream)
{
_serial = stream;
}
MHZ19::~MHZ19()
{
_serial = nullptr;
}
int MHZ19::getCO2()
{
if (_result == MHZ19_RESULT_OK)
{
return bytes2int(_response[2], _response[3]);
}
return _result;
}
int MHZ19::getMinCO2()
{
if (_result == MHZ19_RESULT_OK)
{
return bytes2int(_response[6], _response[7]);
}
return _result;
}
int MHZ19::getTemperature()
{
if (_result == MHZ19_RESULT_OK)
{
int value = static_cast<int>(_response[4]);
return value - 40;
}
return _result;
}
int MHZ19::getAccuracy()
{
if (_result == MHZ19_RESULT_OK)
{
int value = static_cast<int>(_response[5]);
return value;
}
return _result;
}
void MHZ19::setAutoCalibration(bool mode)
{
byte value = mode ? 0xA0 : 0x00;
sendCommand(0x79, value, 0x00, 0x00, 0x00, 0x00);
}
MHZ19_RESULT MHZ19::setRange(MHZ19_RANGE range)
{
switch (range) {
case MHZ19_RANGE_1000:
sendCommand(0x99, 0x00, 0x00, 0x00, 0x03, 0xE8);
break;
case MHZ19_RANGE_2000:
sendCommand(0x99, 0x00, 0x00, 0x00, 0x07, 0xD0);
break;
case MHZ19_RANGE_3000:
sendCommand(0x99, 0x00, 0x00, 0x00, 0x0B, 0xB8);
break;
case MHZ19_RANGE_5000:
sendCommand(0x99, 0x00, 0x00, 0x00, 0x13, 0x88);
break;
case MHZ19_RANGE_10000:
sendCommand(0x99, 0x00, 0x00, 0x00, 0x27, 0x10);
break;
default:
return MHZ19_RESULT_ERR_UNKNOWN;
}
return receiveResponse(_response);
}
void MHZ19::calibrateZero() {
sendCommand(0x87, 0x00, 0x00, 0x00, 0x00, 0x00);
}
void MHZ19::calibrateSpan(int span) {
if (span < 1000)
return;
byte low = static_cast<byte>(span / 256);
byte high = static_cast<byte>(span % 256);
sendCommand(0x88, low, high, 0x00, 0x00, 0x00);
}
MHZ19_RESULT MHZ19::retrieveData()
{
sendCommand(0x86);
return receiveResponse(_response);
}
void MHZ19::sendCommand(byte command, byte b3, byte b4, byte b5, byte b6, byte b7)
{
_cmd = command;
byte cmd[9] = { 0xFF,0x01,command,b3,b4,b5,b6,b7,0x00 };
cmd[8] = calcCRC(cmd);
write(cmd, 9);
}
MHZ19_RESULT MHZ19::receiveResponse(byte cmd[9]) {
unsigned long time = millis();
while (_serial->available() <= 0)
{
if (millis() - time >= SERIAL_TIMEOUT)
{
return MHZ19_RESULT_ERR_TIMEOUT;
}
}
memset(cmd, 0, 9);
_serial->readBytes(cmd, 9);
byte crc = calcCRC(cmd);
_result = MHZ19_RESULT_OK;
if (cmd[0] != 0xFF)
_result = MHZ19_RESULT_ERR_FB;
if (cmd[1] != _cmd)
_result = MHZ19_RESULT_ERR_SB;
if (cmd[8] != crc)
_result = MHZ19_RESULT_ERR_CRC;
return _result;
}
void MHZ19::write(byte data[], byte len)
{
while (_serial->available() > 0) { _serial->read(); }
_serial->write(data, len);
_serial->flush();
}
int MHZ19::bytes2int(byte h, byte l)
{
int high = static_cast<int>(h);
int low = static_cast<int>(l);
return (256 * high) + low;
}
byte MHZ19::calcCRC(byte data[])
{
byte i;
byte crc = 0;
for (i = 1; i < 8; i++)
{
crc += data[i];
}
crc = 255 - crc;
crc++;
return crc;
}