SparkFun_SCD30_Arduino_Library.h 4.67 KB
Newer Older
1
2
3
4
5
6
7
8
/*
  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

  Written by Nathan Seidle @ SparkFun Electronics, May 22nd, 2018

9
10
11
12
13
	Updated February 1st 2021 to include some of the features of paulvha's version of the library
	(while maintaining backward-compatibility):
	https://github.com/paulvha/scd30
	Thank you Paul!

14
15
16
17
18
19
20
21
  The SCD30 measures CO2 with accuracy of +/- 30ppm.

  This library handles the initialization of the SCD30 and outputs
  CO2 levels, relative humidty, and temperature.

  https://github.com/sparkfun/SparkFun_SCD30_Arduino_Library

  Development environment specifics:
22
  Arduino IDE 1.8.13
23

24
25
	SparkFun code, firmware, and software is released under the MIT License.
  Please see LICENSE.md for more details.
26
27
28
29
30
*/

#ifndef __SparkFun_SCD30_ARDUINO_LIBARARY_H__
#define __SparkFun_SCD30_ARDUINO_LIBARARY_H__

31
32
33
34
35
// Uncomment the next #define if using an Teensy >= 3 or Teensy LC and want to use the dedicated I2C-Library for it
// Then you also have to include <i2c_t3.h> on your application instead of <Wire.h>

// #define USE_TEENSY3_I2C_LIB

36
#include "Arduino.h"
37
38
39
#ifdef USE_TEENSY3_I2C_LIB
#include <i2c_t3.h>
#else
40
#include <Wire.h>
41
#endif
42

Eric Duminil's avatar
Eric Duminil committed
43
// The default I2C address for the SCD30 is 0x61.
44
45
#define SCD30_ADDRESS 0x61

Eric Duminil's avatar
Eric Duminil committed
46
// Available commands
47
48
49
50
51
52
53
54
55

#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
56
57
58
59
#define COMMAND_RESET 0xD304 // Soft reset
#define COMMAND_STOP_MEAS 0x0104
#define COMMAND_READ_FW_VER 0xD100

Eric Duminil's avatar
Eric Duminil committed
60
61
62
63
typedef union
{
	byte array[4];
	float value;
64
} ByteToFl; // paulvha
65
66
67
68
69

class SCD30
{
public:
	SCD30(void);
70

71
	bool begin(bool autoCalibrate) { return begin(Wire, autoCalibrate); }
72
#ifdef USE_TEENSY3_I2C_LIB
Eric Duminil's avatar
Eric Duminil committed
73
	bool begin(i2c_t3 &wirePort = Wire, bool autoCalibrate = false, bool measBegin = true); // By default use Wire port
74
#else
Eric Duminil's avatar
Eric Duminil committed
75
	bool begin(TwoWire &wirePort = Wire, bool autoCalibrate = false, bool measBegin = true); // By default use Wire port
76
77
#endif

Eric Duminil's avatar
Eric Duminil committed
78
79
	bool isConnected();
	void enableDebugging(Stream &debugPort = Serial); // Turn on debug printing. If user doesn't specify then Serial will be used.
80
81
82

	bool beginMeasuring(uint16_t pressureOffset);
	bool beginMeasuring(void);
83
84
	bool StopMeasurement(void); // paulvha

Eric Duminil's avatar
Eric Duminil committed
85
86
	bool setAmbientPressure(uint16_t pressure_mbar);

87
	bool getSettingValue(uint16_t registerAddress, uint16_t *val);
Eric Duminil's avatar
Eric Duminil committed
88
	bool getFirmwareVersion(uint16_t *val) { return (getSettingValue(COMMAND_READ_FW_VER, val)); }
89
90
91
92
	uint16_t getCO2(void);
	float getHumidity(void);
	float getTemperature(void);

Eric Duminil's avatar
Eric Duminil committed
93
94
	uint16_t getMeasurementInterval(void);
	bool getMeasurementInterval(uint16_t *val) { return (getSettingValue(COMMAND_SET_MEASUREMENT_INTERVAL, val)); }
95
	bool setMeasurementInterval(uint16_t interval);
Eric Duminil's avatar
Eric Duminil committed
96
97
98

	uint16_t getAltitudeCompensation(void);
	bool getAltitudeCompensation(uint16_t *val) { return (getSettingValue(COMMAND_SET_ALTITUDE_COMPENSATION, val)); }
99
	bool setAltitudeCompensation(uint16_t altitude);
Eric Duminil's avatar
Eric Duminil committed
100
101

	bool getAutoSelfCalibration(void);
102
	bool setAutoSelfCalibration(bool enable);
Eric Duminil's avatar
Eric Duminil committed
103
104

	bool getForcedRecalibration(uint16_t *val) { return (getSettingValue(COMMAND_SET_FORCED_RECALIBRATION_FACTOR, val)); }
105
	bool setForcedRecalibrationFactor(uint16_t concentration);
Eric Duminil's avatar
Eric Duminil committed
106
107
108

	float getTemperatureOffset(void);
	bool getTemperatureOffset(uint16_t *val) { return (getSettingValue(COMMAND_SET_TEMPERATURE_OFFSET, val)); }
109
110
111
112
113
	bool setTemperatureOffset(float tempOffset);

	bool dataAvailable();
	bool readMeasurement();

114
115
	void reset();

116
117
118
119
120
121
122
123
	bool sendCommand(uint16_t command, uint16_t arguments);
	bool sendCommand(uint16_t command);

	uint16_t readRegister(uint16_t registerAddress);

	uint8_t computeCRC8(uint8_t data[], uint8_t len);

private:
Eric Duminil's avatar
Eric Duminil committed
124
	// Variables
125
#ifdef USE_TEENSY3_I2C_LIB
Eric Duminil's avatar
Eric Duminil committed
126
	i2c_t3 *_i2cPort; // The generic connection to user's chosen I2C hardware
127
#else
Eric Duminil's avatar
Eric Duminil committed
128
	TwoWire *_i2cPort;																		 // The generic connection to user's chosen I2C hardware
129
#endif
Eric Duminil's avatar
Eric Duminil committed
130
	// Global main datums
131
132
133
134
	float co2 = 0;
	float temperature = 0;
	float humidity = 0;

Eric Duminil's avatar
Eric Duminil committed
135
136
	// These track the staleness of the current data
	// This allows us to avoid calling readMeasurement() every time individual datums are requested
137
138
139
	bool co2HasBeenReported = true;
	bool humidityHasBeenReported = true;
	bool temperatureHasBeenReported = true;
140

Eric Duminil's avatar
Eric Duminil committed
141
142
143
	// Debug
	Stream *_debugPort;			 // The stream to send debug messages to if enabled. Usually Serial.
	boolean _printDebug = false; // Flag to print debugging variables
144
145
};
#endif