-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathDFRobot_MultiGasSensor.h
More file actions
333 lines (299 loc) · 9.65 KB
/
DFRobot_MultiGasSensor.h
File metadata and controls
333 lines (299 loc) · 9.65 KB
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
/*!
* @file DFRobot_MultiGasSensor.h
* @brief This is a header file of the library for the sensor that can detect gas concentration in the air.
* @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
* @license The MIT License (MIT)
* @author PengKaixing(kaixing.peng@dfrobot.com)
* @version V2.0.0
* @date 2021-09-26
* @url https://github.com/DFRobot/DFRobot_MultiGasSensor
*/
#ifndef __DFRobot_GAS_H__
#define __DFRobot_GAS_H__
#include "Arduino.h"
#include <Wire.h>
#if defined(ARDUINO_AVR_UNO) || defined(ESP8266)
#include "SoftwareSerial.h"
#else
#include "HardwareSerial.h"
#endif
#define CMD_CHANGE_GET_METHOD 0X78
#define CMD_GET_GAS_CONCENTRATION 0X86
#define CMD_GET_TEMP 0X87
#define CMD_GET_ALL_DTTA 0X88
#define CMD_SET_THRESHOLD_ALARMS 0X89
#define CMD_IIC_AVAILABLE 0X90
#define CMD_SENSOR_VOLTAGE 0X91
#define CMD_CHANGE_IIC_ADDR 0X92
// Open this macro to see the program running in detail
#define ENABLE_DBG
#ifdef ENABLE_DBG
#define DBG(...) {Serial.print("[");Serial.print(__FUNCTION__); Serial.print("(): "); Serial.print(__LINE__); Serial.print(" ] 0x"); Serial.println(__VA_ARGS__,HEX);}
#else
#define DBG(...)
#endif
/**
* @struct sProtocol_t
* @brief Data protocol package for communication
*/
typedef struct
{
uint8_t head;
uint8_t addr;
uint8_t data[6];
uint8_t check;
} sProtocol_t;
/**
* @struct sAllData_t
* @brief The struct used when getting all the data
* @note
* @n -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* @n | byte0 | byte1 | byte2 | byte3 | byte4 | byte5 | byte6 | byte7 | byte8
* @n -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* @n | Protocol Head | Command | Gas Concentrate High 8-bit | Gas Concentration Low 8-bit | Gas Type | Decimal Digits | Temperature High 8-bit | Temperature Low 8-bit | CRC
* @n -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
*/
typedef struct
{
uint8_t head;
uint8_t cmd;
uint8_t gasconcentration_h;
uint8_t gasconcentration_l;
uint8_t gastype;
uint8_t gasconcentration_decimals;
uint8_t temp_h;
uint8_t temp_l;
uint8_t check;
} sAllData_t;
extern sAllData_t AllData;
/**
* @struct sAllDataAnalysis_t
* @brief All the parsed data
*/
typedef struct
{
float gasconcentration;
String gastype;
float temp;
} sAllDataAnalysis_t;
extern sAllDataAnalysis_t AllDataAnalysis;
class DFRobot_GAS
{
public:
/**
* @enum eMethod_t
* @brief Type of the data the sensor uploads
*/
typedef enum
{
INITIATIVE = 0x03,
PASSIVITY = 0x04
} eMethod_t;
/**
* @enum eType_t
* @brief Gas Type
*/
typedef enum
{
O2 = 0x05,
CO = 0x04,
H2S = 0x03,
NO2 = 0x2C,
O3 = 0x2A,
CL2 = 0x31,
NH3 = 0x02,
H2 = 0x06,
HCL = 0X2E,
SO2 = 0X2B,
HF = 0x33,
_PH3 = 0x45
} eType_t;
/**
* @enum eSwitch_t
* @brief Whether to enable ALA alarm function
*/
typedef enum
{
ON = 0x01,
OFF = 0x00
} eSwitch_t;
/**
* @enum eSwitch_t
* @brief High and low ALA alarm function
*/
typedef enum
{
LOW_THRESHOLD_ALA = 0x00,
HIGH_THRESHOLD_ALA = 0x01
} eALA_t;
DFRobot_GAS(void){};
~DFRobot_GAS(void){};
/**
* @fn begin
* @brief Parent class init, I2C or UART init is performed in subclass function
* @return bool type, indicating whether init succeed
* @retval True succeed
* @retval False failed
*/
virtual bool begin(void) = 0;
/**
* @fn changeAcquireMode
* @brief Change the mode of acquiring sensor data
* @param mode Mode select
* @n INITIATIVE The sensor proactively reports data
* @n PASSIVITY The main controller needs to request data from sensor
* @return bool type, indicating whether the setting is successful
* @retval True succeed
* @retval False failed
*/
bool changeAcquireMode(eMethod_t mode);
/**
* @fn readGasConcentrationPPM
* @brief Get gas concentration from sensor, unit PPM
* @return float type, indicating return gas concentration, if data is transmitted normally, return gas concentration, otherwise, return 0.0
*/
float readGasConcentrationPPM(void);
/**
* @fn queryGasType
* @brief Query gas type
* @return String type, indicating return gas type string
*/
String queryGasType(void);
/**
* @fn setThresholdAlarm
* @brief Set sensor alarm threshold
* @param switchof Whether to turn on threshold alarm switch
* @n ON turn on
* @n OFF turn off
* @param threshold The threshold for starting alarm
* @param alamethod Set sensor high or low threshold alarm
* @param gasType Gas Type
* @return bool type, indicating whether the setting is successful
* @retval True succeed
* @retval False failed
*/
bool setThresholdAlarm(eSwitch_t switchof, uint16_t threshold, eALA_t alamethod, String gasType);
/**
* @fn readTempC
* @brief Get sensor onboard temperature
* @return float type, indicating return the current onboard temperature
*/
float readTempC(void);
/**
* @fn setTempCompensation
* @brief Set whether to turn on temperature compensation, values output by sensor under different temperatures are various.
* @n To get more accurate gas concentration, temperature compensation is necessary when calculating gas concentration.
* @param tempswitch Whether to turn on temperature compensation
* @n ON Turn on temperature compensation
* @n OFF Turn off temperature compensation
*/
void setTempCompensation(eSwitch_t tempswitch);
/**
* @fn readVolatageData
* @brief Get sensor gas concentration output by original voltage, which is different from reading sensor register directly.
* @n The function is mainly for detecting whether the read gas concentration is right.
* @param vopin Pin for receiving the original voltage output from sensor probe
* @return Float type, indicating return the original voltage output of sensor gas concentration
*/
float readVolatageData(uint8_t vopin);
/**
* @fn pack
* @brief Pack the protocol data for easy transmission
* @param pBuf Data to be packed
* @param len Length of data package
* @return sProtocol_t type, indicating return the packed data
*/
sProtocol_t pack(uint8_t *pBuf, uint8_t len);
/**
* @fn getSensorVoltage
* @brief Get voltage output by sensor probe (for calculating the current gas concentration)
* @return float type, indicating return voltage value
*/
float getSensorVoltage(void);
/**
* @fn dataIsAvailable
* @brief Call this function in active mode to determine the presence of data on data line
* @return bool type, indicating whether there is data coming from the sensor
* @retval True Has uploaded data
* @retval False No data uploaded
*/
virtual bool dataIsAvailable(void) = 0;
/**
* @fn changeI2cAddrGroup
* @brief Change I2C address group
* @param group Address group select
* @return int type, indicating return init status
* @retval bool type
* @retval True Change succeed
* @retval False Change failed
*/
bool changeI2cAddrGroup(uint8_t group);
protected:
/**
* @fn writeData
* @brief Write data to the specified register of the sensor
* @param Reg Register address to be written
* @param Data Data to be written to register
* @param len Length of data to be written
*/
virtual void writeData(uint8_t Reg, void *Data, uint8_t len) = 0;
/**
* @fn readData
* @brief Get the data with specified length from the specified sensor
* @param Reg Register address to be read
* @param Data Position of the data stored in the register to be read
* @param len Length of the data to be written
*/
virtual int16_t readData(uint8_t Reg, uint8_t *Data, uint8_t len) = 0;
private:
bool _tempswitch;
};
class DFRobot_GAS_I2C : public DFRobot_GAS
{
public:
DFRobot_GAS_I2C(TwoWire *pWire=&Wire,uint8_t addr=0x74);
~DFRobot_GAS_I2C(void){};
bool begin(void);
void setI2cAddr(uint8_t addr);
bool dataIsAvailable(void);
protected:
void writeData(uint8_t Reg ,void *Data ,uint8_t len);
int16_t readData(uint8_t Reg ,uint8_t *Data ,uint8_t len);
private:
TwoWire* _pWire;
uint8_t _I2C_addr;
};
#if defined(ARDUINO_AVR_UNO) || defined(ESP8266)
class DFRobot_GAS_SoftWareUart : public DFRobot_GAS
{
public:
DFRobot_GAS_SoftWareUart(SoftwareSerial *psoftUart, uint16_t Baud);
~DFRobot_GAS_SoftWareUart(void){};
bool begin(void);
bool dataIsAvailable(void);
protected:
void writeData(uint8_t Reg ,void *Data ,uint8_t len);
int16_t readData(uint8_t Reg ,uint8_t *Data ,uint8_t len);
private:
SoftwareSerial *_psoftUart;
uint32_t _baud;
};
#else
class DFRobot_GAS_HardWareUart : public DFRobot_GAS
{
public:
DFRobot_GAS_HardWareUart(HardwareSerial *phardUart, uint16_t Baud ,uint8_t txpin = 0, uint8_t rxpin = 0);
~DFRobot_GAS_HardWareUart(void){};
bool begin(void);
protected:
bool dataIsAvailable(void);
void writeData(uint8_t Reg, void *Data, uint8_t len);
int16_t readData(uint8_t Reg, uint8_t *Data, uint8_t len);
private:
HardwareSerial *_pharduart;
uint32_t _baud;
uint8_t _rxpin;
uint8_t _txpin;
};
#endif
#endif