-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathSCD30.h
executable file
·343 lines (294 loc) · 10.7 KB
/
SCD30.h
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
334
335
336
337
338
339
340
341
342
343
/****************************************************************
*
* Based on original library from Sparkfun :
*
* This is a library written for the SCD30
* SparkFun sells these at its website: www.sparkfun.com
* Do you like this library? Help support SparkFun. Buy a board!
* https://www.sparkfun.com/products/14751
*
* The SCD30 measures CO2 with accuracy of +/- 30ppm.
*
* This library handles the initialization of the SCD30 and outputs
* CO2 levels, relative humidty, and temperature.
******************************************************************
* October 2018 : Changed, enhanced and extended for raspberry Pi
* by Paul van Haastrecht (paulvha@hotmail.com)
*
* version 1.0 : initial Raspberry Pi
*
* version 2.0 : October 2018
* - added softreset
*
* version 3.0 : October 2018
* - added dewpoint and heatindex
*
* Version 3.0.1 : November 2018
* - fixed humidity type in printf
*
* version 3.0.2: January 2019
* - changed to use p_printf in do_output to fix an issue with providing
* output as a sub-program to python.
*
* Version 3.1.0 : August 2020
* Changes based on Datasheet May 2020
* - added functions : getForceRecalibration, getMeasurementInterval,
* getTemperatureOffset, getAltitudeCompensation, getFirmwareLevel
*
* Resources / dependencies:
* BCM2835 library (http://www.airspayce.com/mikem/bcm2835/)
* twowire library (https://github.com/paulvha/twowire)
*
* *****************************************************************
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
********************************************************************/
#ifndef __SCD30_H__
#define __SCD30_H__
# include <twowire.h>
# include <getopt.h>
# include <signal.h>
# include <stdint.h>
# include <stdarg.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <time.h>
# include <math.h>
/* set version number */
# define VERSIONMAJOR 3
# define VERSIONMINOR 1
/* The default I2C address for the SCD30 is 0x61 */
#define SCD30_ADDRESS 0x61
/* default speed 100 Khz*/
# define SCD30_SPEED 100
/* default GPIO for SOFT_I2C */
#define DEF_SDA 2
#define DEF_SCL 3
# define MAXBUF 100
# define RESET_RETRY 5
/* Available commands */
#define COMMAND_CONTINUOUS_MEASUREMENT 0x0010
#define COMMAND_SET_MEASUREMENT_INTERVAL 0x4600
#define COMMAND_GET_DATA_READY 0x0202
#define COMMAND_READ_MEASUREMENT 0x0300
#define COMMAND_AUTOMATIC_SELF_CALIBRATION 0x5306
#define COMMAND_SET_FORCED_RECALIBRATION_FACTOR 0x5204
#define COMMAND_SET_TEMPERATURE_OFFSET 0x5403
#define COMMAND_SET_ALTITUDE_COMPENSATION 0x5102
#define CMD_READ_SERIALNBR 0xD033
//#define CMD_READ_ARTICLECODE 0XD025 // ONLY ZERO'S
//#define CMD_START_SINGLE_MEAS 0x0006 // NOT used due to issues
#define CMD_STOP_MEAS 0x0104
#define CMD_SOFT_RESET 0xD304
#define CMD_GET_FW_LEVEL 0xD100 // added August 2020
#define SCD30_SERIAL_NUM_WORDS 16 // added August 2020
struct scd30_p
{
/*! driver information */
bool hw_initialized; // initialized or not
bool I2C_interface; // hard_I2C or soft_I2C
uint8_t I2C_Address; // slave address
uint16_t baudrate; // speed
uint8_t sda; // SDA GPIO (soft_I2C only)
uint8_t scl; // SCL GPIO (soft_I2C only)
bool pullup; // enable internal BCM2835 resistor
};
class SCD30
{
public:
/*! structure with share I2C values */
scd30_p settings;
/*! constructor */
SCD30(void);
/*! Initialize the hardware, twowire library and SCD30
* @param asc true : perform ASC
* @param interval >0 : set for continuous mode, else stop.
*
* @return true = OK, false is error
*/
bool begin(bool asc, uint16_t interval);
/*! begin continuous measurements
* @param pressureoffset : to compensate for the pressure
*
* @return true = OK, false is error
*/
bool beginMeasuring(uint16_t pressureOffset);
bool beginMeasuring(void);
/*! perform a softreset on the sensor
* and reload parameters
*
* @return true = OK, false is error
*/
bool SoftReset(void);
/*! stop continuous measurements
*
* @return true = OK, false is error */
bool StopMeasurement(void);
/*! perform single measurement
*
* Will perform a single read of the values
* the result get be obtained with getTemperature, getHumidity
* or getCO2 right after succesfull completion of this call.
*
* @return true = OK, false is error
*/
bool StartSingleMeasurement(void);
/*! get serial number of the SCD30
*
* will store a 6 digit serial number + 0x0 termination in
* character buffer "val".
*
* User needs to assign at least 7 positions in the buffer
*
* @return true = OK, false is error
*/
bool getSerialNumber(char *val);
/*! Check whether new data is available in the SCD30
*
* @return true = new data available to read
*/
bool dataAvailable();
/*! get latest CO2 value
* between 0 and 10.000 PPM
*
* @return : 0 in case of error
*/
uint16_t getCO2(void);
/*! get latest humidity value
* between 0 and 100% RH
*
* @return : 0 in case of error
*/
float getHumidity(void);
/*! get latest temperature value in Celsius
* between -40 and 120*C
*
* @return : 0 in case of error
*/
float getTemperature(void);
/*! get latest temperature value in Fahrenheit
* between -40 and 248*F
*
* @return : 0 in case of error
*/
float getTemperatureF(void);
/*!read 16 bit value from a register
* @param command : command to sent
* @param val : return the read 16 bit value
*
* @return true = OK, false is error.
*/
bool getSettingValue(uint16_t command, uint16_t *val);
/*! set interval for continuous measurement
* between 2 and 1800 seconds
*
* @return true = OK, false is error.
*
*/
bool setMeasurementInterval(uint16_t interval);
/*! set pressure compensation for SCD30
* between 700 and 1200 mbar
*
* either set pressure or altitude.
*
* @return true = OK, false is error.
*/
bool setAmbientPressure(uint16_t pressure_mbar);
/*! set altitude compensation for SCD30
* between -1520 and 3040 meter
*
* either set pressure or altitude.
*
* @return true = OK, false is error.
*/
bool setAltitudeCompensation(uint16_t altitude);
/*! enable of disable Auto Self Calibration (ASC) for SCD30
*
* will overwrite forced calibration
*
* @return true = OK, false is error.
*/
bool setAutoSelfCalibration(bool enable);
/*! set forced calibration for SCD30
* between 400 and 2000 PPM
*
* will overwrite ASC
*
* @return true = OK, false is error.
*/
bool setForceRecalibration(uint16_t val);
/*! only to compensate for the temperature reading
* value must between 0 and 25 *C
*
* @return true = OK, false is error.
*/
bool setTemperatureOffset(float tempOffset);
/*! calculation */
float calc_dewpoint(float in_temperature, float hum, bool isFahrenheit);
float computeHeatIndex(float in_temperature, float percentHumidity, bool isFahrenheit);
/*! close driver and release memory */
void close(void);
/*! enable debug messages */
void setDebug(int val);
/*! display the clock stretch statistics */
void DispClockStretch();
private:
/*! display debug messages */
void debug_cmd(uint16_t command);
/*! perform a read a store the values in the driver
* It is triggered bygetTemperature(),getHumidity() or
* getCO2();
*
* @return true = OK, false is error.
*/
bool readMeasurement();
/*! Read from SCD30 the amount of requested bytes
* @param val : to store the data received
* @param cnt : number of data bytes requested
*
* @return
* OK number of bytes read
* 0 error
*/
uint8_t ReadFromSCD30(uint16_t command, uint8_t *val, uint8_t cnt);
/*! initialize the SCD30 based on the ASC and interval values
* @return true = OK, false is error.
*/
bool begin_scd30();
/*! low level communication routines */
bool sendCommand(uint16_t command, uint16_t arguments);
bool sendCommand(uint16_t command);
bool sendCommand(uint16_t command, uint16_t arguments, uint8_t len);
uint16_t readRegister(uint16_t registerAddress);
bool readbytes(char *buff, uint8_t len);
bool checkCrc(uint8_t *data, uint8_t len, uint8_t crc_rec);
uint8_t computeCRC8(uint8_t data[], uint8_t len);
};
/*! to display in color */
void p_printf (int level, char *format, ...);
// color display enable
#define RED 1
#define GREEN 2
#define YELLOW 3
#define BLUE 4
#define WHITE 5
#define REDSTR "\e[1;31m%s\e[00m"
#define GRNSTR "\e[1;92m%s\e[00m"
#define YLWSTR "\e[1;93m%s\e[00m"
#define BLUSTR "\e[1;34m%s\e[00m"
// disable color output
extern bool NoColor;
#endif // End of definition check