Commit 7b50295d authored by Eric Duminil's avatar Eric Duminil
Browse files

Updating Spark SCD30 lib from 1.0.8 to 1.0.11

parent 26f6619a
SparkFun SCD30 CO2 Sensor Library SparkFun SCD30 CO Sensor Library
=========================================================== ===========================================================
![SparkFun SCD30 CO2 Sensor](https://cdn.sparkfun.com//assets/parts/1/2/9/8/4/SparkFun_Sensirion_SCD30.jpg) ![SparkFun SCD30 CO Sensor](https://cdn.sparkfun.com//assets/parts/1/2/9/8/4/SparkFun_Sensirion_SCD30.jpg)
[*SparkX CO₂ Humidity and Temperature Sensor - SCD30 (SPX-14751)*](https://www.sparkfun.com/products/14751) [*SparkX CO₂ Humidity and Temperature Sensor - SCD30 (SPX-14751)*](https://www.sparkfun.com/products/14751)
The SCD30 from Sensirion is a high quality [NDIR](https://en.wikipedia.org/wiki/Nondispersive_infrared_sensor) based CO₂ sensor capable of detecting 400 to 10000ppm with an accuracy of ±(30ppm+3%). In order to improve accuracy the SCD30 has temperature and humidity sensing built-in, as well as commands to set the current altitude. The SCD30 from Sensirion is a high quality [NDIR](https://en.wikipedia.org/wiki/Nondispersive_infrared_sensor) based CO₂ sensor capable of detecting 400 to 10000ppm with an accuracy of ±(30ppm+3%). In order to improve accuracy the SCD30 has temperature and humidity sensing built-in, as well as commands to compensate for altitude.
We've written an Arduino library to make reading the CO₂, humidity, and temperature very easy. It can be downloaded through the Arduino Library manager: search for 'SparkFun SCD30'. We recommend using a [Qwiic Breadboard Cable](https://www.sparkfun.com/products/14425) to connect the SCD30 to a Qwiic compatible board. The Ye*LL*ow wire goes in the SC*L* pin. The SCD30 also supports a serial interface but we haven't worked with it. We've written an Arduino library to make reading the CO₂, humidity, and temperature very easy. It can be downloaded through the Arduino Library manager: search for 'SparkFun SCD30'. We recommend using a [Qwiic Breadboard Cable](https://www.sparkfun.com/products/14425) to connect the SCD30 to a Qwiic compatible board. The Ye*LL*ow wire goes in the SC*L* pin. The SCD30 also supports a serial interface but we haven't worked with it.
...@@ -20,14 +20,18 @@ Thanks to! ...@@ -20,14 +20,18 @@ Thanks to!
* [jobr97](https://github.com/jobr97) for adding the getTemperatureOffset() method * [jobr97](https://github.com/jobr97) for adding the getTemperatureOffset() method
* [bobobo1618](https://github.com/bobobo1618) for writing a CRC check and improving the return values of the library * [bobobo1618](https://github.com/bobobo1618) for writing a CRC check and improving the return values of the library
* [labeneator](https://github.com/labeneator) for adding method to disable calibrate at begin * [labeneator](https://github.com/labeneator) for adding method to disable calibrate at begin
* [AndreasExner](https://github.com/AndreasExner) for adding [reset and getAutoSelfCalibration methods](https://github.com/sparkfun/SparkFun_SCD30_Arduino_Library/pull/17)
* [awatterott](https://github.com/awatterott) for adding [getAltitudeCompensation()](https://github.com/sparkfun/SparkFun_SCD30_Arduino_Library/pull/18)
* [jogi-k](https://github.com/jogi-k) for adding [teensy i2clib](https://github.com/sparkfun/SparkFun_SCD30_Arduino_Library/pull/19) support
* [paulvha](https://github.com/paulvha) for the suggestions and corrections in [his version of the library](https://github.com/paulvha/scd30)
Repository Contents Repository Contents
------------------- -------------------
* **/examples** - Example sketches for the library (.ino). Run these from the Arduino IDE. * **/examples** - Example sketches for the library (.ino). Run these from the Arduino IDE.
* **/src** - Source files for the library (.cpp, .h). * **/src** - Source files for the library (.cpp, .h).
* **keywords.txt** - Keywords from this library that will be highlighted in the Arduino IDE. * **keywords.txt** - Keywords from this library that will be highlighted in the Arduino IDE.
* **library.properties** - General library properties for the Arduino package manager. * **library.properties** - General library properties for the Arduino package manager.
Documentation Documentation
-------------- --------------
...@@ -37,9 +41,9 @@ Documentation ...@@ -37,9 +41,9 @@ Documentation
License Information License Information
------------------- -------------------
This product is _**open source**_! This product is _**open source**_!
Various bits of the code have different licenses applied. Anything SparkFun wrote is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round! Various bits of the code have different licenses applied. Anything SparkFun wrote is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round!
Please use, reuse, and modify these files as you see fit. Please maintain attribution to SparkFun Electronics and release anything derivative under the same license. Please use, reuse, and modify these files as you see fit. Please maintain attribution to SparkFun Electronics and release anything derivative under the same license.
......
...@@ -6,42 +6,53 @@ ...@@ -6,42 +6,53 @@
# Datatypes (KEYWORD1) # Datatypes (KEYWORD1)
####################################### #######################################
SCD30 KEYWORD1 SCD30 KEYWORD1
####################################### #######################################
# Methods and Functions (KEYWORD2) # Methods and Functions (KEYWORD2)
####################################### #######################################
SCD30 KEYWORD2 SCD30 KEYWORD2
begin KEYWORD2 begin KEYWORD2
beginMeasuring KEYWORD2 enableDebugging KEYWORD2
getCO2 KEYWORD2 beginMeasuring KEYWORD2
getHumidity KEYWORD2 StopMeasurement KEYWORD2
getTemperature KEYWORD2 getSettingValue KEYWORD2
getTemperatureOffset KEYWORD2 getForcedRecalibration KEYWORD2
setMeasurementInterval KEYWORD2 getMeasurementInterval KEYWORD2
setAmbientPressure KEYWORD2 getTemperatureOffset KEYWORD2
setAltitudeCompensation KEYWORD2 getAltitudeCompensation KEYWORD2
setAutoSelfCalibration KEYWORD2 getFirmwareVersion KEYWORD2
setTemperatureOffset KEYWORD2 getCO2 KEYWORD2
setForcedRecalibrationFactor KEYWORD2 getHumidity KEYWORD2
dataAvailable KEYWORD2 getTemperature KEYWORD2
readMeasurement KEYWORD2 setMeasurementInterval KEYWORD2
sendCommand KEYWORD2 setAmbientPressure KEYWORD2
sendCommand KEYWORD2 setAltitudeCompensation KEYWORD2
readRegister KEYWORD2 setAutoSelfCalibration KEYWORD2
computeCRC8 KEYWORD2 setForcedRecalibrationFactor KEYWORD2
setTemperatureOffset KEYWORD2
getAutoSelfCalibration KEYWORD2
dataAvailable KEYWORD2
readMeasurement KEYWORD2
reset KEYWORD2
sendCommand KEYWORD2
readRegister KEYWORD2
computeCRC8 KEYWORD2
####################################### #######################################
# Constants (LITERAL1) # Constants (LITERAL1)
####################################### #######################################
SCD30_ADDRESS LITERAL1 SCD30_ADDRESS LITERAL1
COMMAND_CONTINUOUS_MEASUREMENT LITERAL1 COMMAND_CONTINUOUS_MEASUREMENT LITERAL1
COMMAND_SET_MEASUREMENT_INTERVAL LITERAL1 COMMAND_SET_MEASUREMENT_INTERVAL LITERAL1
COMMAND_GET_DATA_READY LITERAL1 COMMAND_GET_DATA_READY LITERAL1
COMMAND_READ_MEASUREMENT LITERAL1 COMMAND_READ_MEASUREMENT LITERAL1
COMMAND_AUTOMATIC_SELF_CALIBRATION LITERAL1 COMMAND_AUTOMATIC_SELF_CALIBRATION LITERAL1
COMMAND_SET_FORCED_RECALIBRATION_FACTOR LITERAL1 COMMAND_SET_FORCED_RECALIBRATION_FACTOR LITERAL1
COMMAND_SET_TEMPERATURE_OFFSET LITERAL1 COMMAND_SET_TEMPERATURE_OFFSET LITERAL1
COMMAND_SET_ALTITUDE_COMPENSATION LITERAL1 COMMAND_SET_ALTITUDE_COMPENSATION LITERAL1
COMMAND_RESET LITERAL1
COMMAND_STOP_MEAS LITERAL1
COMMAND_READ_FW_VER LITERAL1
name=SparkFun SCD30 Arduino Library name=SparkFun SCD30 Arduino Library
version=1.0.8 version=1.0.11
author=SparkFun Electronics author=SparkFun Electronics
maintainer=SparkFun Electronics <sparkfun.com> maintainer=SparkFun Electronics <sparkfun.com>
sentence=Library for the Sensirion SCD30 CO2 Sensor sentence=Library for the Sensirion SCD30 CO2 Sensor
......
...@@ -6,6 +6,11 @@ ...@@ -6,6 +6,11 @@
Written by Nathan Seidle @ SparkFun Electronics, May 22nd, 2018 Written by Nathan Seidle @ SparkFun Electronics, May 22nd, 2018
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!
The SCD30 measures CO2 with accuracy of +/- 30ppm. The SCD30 measures CO2 with accuracy of +/- 30ppm.
This library handles the initialization of the SCD30 and outputs This library handles the initialization of the SCD30 and outputs
...@@ -14,15 +19,10 @@ ...@@ -14,15 +19,10 @@
https://github.com/sparkfun/SparkFun_SCD30_Arduino_Library https://github.com/sparkfun/SparkFun_SCD30_Arduino_Library
Development environment specifics: Development environment specifics:
Arduino IDE 1.8.5 Arduino IDE 1.8.13
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 General Public License for more details.
You should have received a copy of the GNU General Public License SparkFun code, firmware, and software is released under the MIT License.
along with this program. If not, see <http://www.gnu.org/licenses/>. Please see LICENSE.md for more details.
*/ */
#include "SparkFun_SCD30_Arduino_Library.h" #include "SparkFun_SCD30_Arduino_Library.h"
...@@ -33,7 +33,11 @@ SCD30::SCD30(void) ...@@ -33,7 +33,11 @@ SCD30::SCD30(void)
} }
//Initialize the Serial port //Initialize the Serial port
bool SCD30::begin(TwoWire &wirePort, bool autoCalibrate) #ifdef USE_TEENSY3_I2C_LIB
bool SCD30::begin(i2c_t3 &wirePort, bool autoCalibrate, bool measBegin)
#else
bool SCD30::begin(TwoWire &wirePort, bool autoCalibrate, bool measBegin)
#endif
{ {
_i2cPort = &wirePort; //Grab which port the user wants us to use _i2cPort = &wirePort; //Grab which port the user wants us to use
...@@ -46,7 +50,7 @@ bool SCD30::begin(TwoWire &wirePort, bool autoCalibrate) ...@@ -46,7 +50,7 @@ bool SCD30::begin(TwoWire &wirePort, bool autoCalibrate)
* *
* To set ClockStretchlimit() a check for ESP8266 boards has been added in the driver. * To set ClockStretchlimit() a check for ESP8266 boards has been added in the driver.
* *
* With setting to 20000, we set a max timeout of 20mS (> 20x the maximum measured) basically disabling the time-out * With setting to 20000, we set a max timeout of 20mS (> 20x the maximum measured) basically disabling the time-out
* and now wait for clock stretch to be controlled by the client. * and now wait for clock stretch to be controlled by the client.
*/ */
...@@ -54,6 +58,19 @@ bool SCD30::begin(TwoWire &wirePort, bool autoCalibrate) ...@@ -54,6 +58,19 @@ bool SCD30::begin(TwoWire &wirePort, bool autoCalibrate)
_i2cPort->setClockStretchLimit(200000); _i2cPort->setClockStretchLimit(200000);
#endif #endif
uint16_t fwVer;
if (getFirmwareVersion(&fwVer) == false) // Read the firmware version. Return false if the CRC check fails.
return (false);
if (_printDebug == true)
{
_debugPort->print(F("SCD30 begin: got firmware version 0x"));
_debugPort->println(fwVer, HEX);
}
if (measBegin == false) // Exit now if measBegin is false
return (true);
//Check for device to respond correctly //Check for device to respond correctly
if (beginMeasuring() == true) //Start continuous measurements if (beginMeasuring() == true) //Start continuous measurements
{ {
...@@ -66,6 +83,14 @@ bool SCD30::begin(TwoWire &wirePort, bool autoCalibrate) ...@@ -66,6 +83,14 @@ bool SCD30::begin(TwoWire &wirePort, bool autoCalibrate)
return (false); //Something went wrong return (false); //Something went wrong
} }
//Calling this function with nothing sets the debug port to Serial
//You can also call it with other streams like Serial1, SerialUSB, etc.
void SCD30::enableDebugging(Stream &debugPort)
{
_debugPort = &debugPort;
_printDebug = true;
}
//Returns the latest available CO2 level //Returns the latest available CO2 level
//If the current level has already been reported, trigger a new read //If the current level has already been reported, trigger a new read
uint16_t SCD30::getCO2(void) uint16_t SCD30::getCO2(void)
...@@ -123,22 +148,28 @@ bool SCD30::setForcedRecalibrationFactor(uint16_t concentration) ...@@ -123,22 +148,28 @@ bool SCD30::setForcedRecalibrationFactor(uint16_t concentration)
} }
//Get the temperature offset. See 1.3.8. //Get the temperature offset. See 1.3.8.
float SCD30::getTemperatureOffset() float SCD30::getTemperatureOffset(void)
{ {
//WARNING: convention is surprising. TemperatureOffset can only be positive. +2.0f means that the sensor outputs 2 Kelvin too much, and should be 2K lower.
uint16_t response = readRegister(COMMAND_SET_TEMPERATURE_OFFSET); uint16_t response = readRegister(COMMAND_SET_TEMPERATURE_OFFSET);
return (float)response / 100; return (((float)response) / 100.0);
} }
//Set the temperature offset. See 1.3.8. //Set the temperature offset. See 1.3.8.
bool SCD30::setTemperatureOffset(float tempOffset) bool SCD30::setTemperatureOffset(float tempOffset)
{ {
if (tempOffset < 0){ union
return false; {
} int16_t signed16;
//WARNING: convention is surprising. TemperatureOffset can only be positive. +2.0f means that the sensor outputs 2 Kelvin too much, and should be 2K lower. uint16_t unsigned16;
int16_t tickOffset = tempOffset * 100; } signedUnsigned; // Avoid any ambiguity casting int16_t to uint16_t
return sendCommand(COMMAND_SET_TEMPERATURE_OFFSET, tickOffset); signedUnsigned.signed16 = tempOffset * 100;
return sendCommand(COMMAND_SET_TEMPERATURE_OFFSET, signedUnsigned.unsigned16);
}
//Get the altitude compenstation. See 1.3.9.
uint16_t SCD30::getAltitudeCompensation(void)
{
return readRegister(COMMAND_SET_ALTITUDE_COMPENSATION);
} }
//Set the altitude compenstation. See 1.3.9. //Set the altitude compenstation. See 1.3.9.
...@@ -158,6 +189,25 @@ bool SCD30::setAmbientPressure(uint16_t pressure_mbar) ...@@ -158,6 +189,25 @@ bool SCD30::setAmbientPressure(uint16_t pressure_mbar)
return sendCommand(COMMAND_CONTINUOUS_MEASUREMENT, pressure_mbar); return sendCommand(COMMAND_CONTINUOUS_MEASUREMENT, pressure_mbar);
} }
// SCD30 soft reset
void SCD30::reset()
{
sendCommand(COMMAND_RESET);
}
// Get the current ASC setting
bool SCD30::getAutoSelfCalibration()
{
uint16_t response = readRegister(COMMAND_AUTOMATIC_SELF_CALIBRATION);
if (response == 1) {
return true;
}
else {
return false;
}
}
//Begins continuous measurements //Begins continuous measurements
//Continuous measurement status is saved in non-volatile memory. When the sensor //Continuous measurement status is saved in non-volatile memory. When the sensor
//is powered down while continuous measurement mode is active SCD30 will measure //is powered down while continuous measurement mode is active SCD30 will measure
...@@ -174,6 +224,12 @@ bool SCD30::beginMeasuring(void) ...@@ -174,6 +224,12 @@ bool SCD30::beginMeasuring(void)
return (beginMeasuring(0)); return (beginMeasuring(0));
} }
// Stop continuous measurement
bool SCD30::StopMeasurement(void)
{
return(sendCommand(COMMAND_STOP_MEAS));
}
//Sets interval between measurements //Sets interval between measurements
//2 seconds to 1800 seconds (30 minutes) //2 seconds to 1800 seconds (30 minutes)
bool SCD30::setMeasurementInterval(uint16_t interval) bool SCD30::setMeasurementInterval(uint16_t interval)
...@@ -200,9 +256,9 @@ bool SCD30::readMeasurement() ...@@ -200,9 +256,9 @@ bool SCD30::readMeasurement()
if (dataAvailable() == false) if (dataAvailable() == false)
return (false); return (false);
uint32_t tempCO2 = 0; ByteToFl tempCO2; tempCO2.value = 0;
uint32_t tempHumidity = 0; ByteToFl tempHumidity; tempHumidity.value = 0;
uint32_t tempTemperature = 0; ByteToFl tempTemperature; tempTemperature.value = 0;
_i2cPort->beginTransmission(SCD30_ADDRESS); _i2cPort->beginTransmission(SCD30_ADDRESS);
_i2cPort->write(COMMAND_READ_MEASUREMENT >> 8); //MSB _i2cPort->write(COMMAND_READ_MEASUREMENT >> 8); //MSB
...@@ -225,32 +281,37 @@ bool SCD30::readMeasurement() ...@@ -225,32 +281,37 @@ bool SCD30::readMeasurement()
case 1: case 1:
case 3: case 3:
case 4: case 4:
tempCO2 <<= 8; tempCO2.array[x < 3 ? 3-x : 4-x] = incoming;
tempCO2 |= incoming;
bytesToCrc[x % 3] = incoming; bytesToCrc[x % 3] = incoming;
break; break;
case 6: case 6:
case 7: case 7:
case 9: case 9:
case 10: case 10:
tempTemperature <<= 8; tempTemperature.array[x < 9 ? 9-x : 10-x] = incoming;
tempTemperature |= incoming;
bytesToCrc[x % 3] = incoming; bytesToCrc[x % 3] = incoming;
break; break;
case 12: case 12:
case 13: case 13:
case 15: case 15:
case 16: case 16:
tempHumidity <<= 8; tempHumidity.array[x < 15 ? 15-x : 16-x] = incoming;
tempHumidity |= incoming;
bytesToCrc[x % 3] = incoming; bytesToCrc[x % 3] = incoming;
break; break;
default: default:
//Validate CRC //Validate CRC
const uint8_t foundCrc = computeCRC8(bytesToCrc, 2); uint8_t foundCrc = computeCRC8(bytesToCrc, 2);
if (foundCrc != incoming) if (foundCrc != incoming)
{ {
//Serial.printf("Found CRC in byte %u, expected %u, got %u\n", x, incoming, foundCrc); if (_printDebug == true)
{
_debugPort->print(F("readMeasurement: found CRC in byte "));
_debugPort->print(x);
_debugPort->print(F(", expected 0x"));
_debugPort->print(foundCrc, HEX);
_debugPort->print(F(", got 0x"));
_debugPort->println(incoming, HEX);
}
error = true; error = true;
} }
break; break;
...@@ -259,19 +320,25 @@ bool SCD30::readMeasurement() ...@@ -259,19 +320,25 @@ bool SCD30::readMeasurement()
} }
else else
{ {
//Serial.printf("No SCD30 data found from I2C, i2c claims we should receive %u bytes\n", receivedBytes); if (_printDebug == true)
{
_debugPort->print(F("readMeasurement: no SCD30 data found from I2C, i2c claims we should receive "));
_debugPort->print(receivedBytes);
_debugPort->println(F(" bytes"));
}
return false; return false;
} }
if (error) if (error)
{ {
//Serial.println("Encountered error reading SCD30 data."); if (_printDebug == true)
_debugPort->println(F("readMeasurement: encountered error reading SCD30 data."));
return false; return false;
} }
//Now copy the uint32s into their associated floats //Now copy the uint32s into their associated floats
memcpy(&co2, &tempCO2, sizeof(co2)); co2 = tempCO2.value;
memcpy(&temperature, &tempTemperature, sizeof(temperature)); temperature = tempTemperature.value;
memcpy(&humidity, &tempHumidity, sizeof(humidity)); humidity = tempHumidity.value;
//Mark our global variables as fresh //Mark our global variables as fresh
co2HasBeenReported = false; co2HasBeenReported = false;
...@@ -281,6 +348,38 @@ bool SCD30::readMeasurement() ...@@ -281,6 +348,38 @@ bool SCD30::readMeasurement()
return (true); //Success! New data available in globals. return (true); //Success! New data available in globals.
} }
//Gets a setting by reading the appropriate register.
//Returns true if the CRC is valid.
bool SCD30::getSettingValue(uint16_t registerAddress, uint16_t *val)
{
_i2cPort->beginTransmission(SCD30_ADDRESS);
_i2cPort->write(registerAddress >> 8); //MSB
_i2cPort->write(registerAddress & 0xFF); //LSB
if (_i2cPort->endTransmission() != 0)
return (false); //Sensor did not ACK
_i2cPort->requestFrom((uint8_t)SCD30_ADDRESS, (uint8_t)3); // Request data and CRC
if (_i2cPort->available())
{
uint8_t data[2];
data[0] = _i2cPort->read();
data[1] = _i2cPort->read();
uint8_t crc = _i2cPort->read();
*val = (uint16_t)data[0] << 8 | data[1];
uint8_t expectedCRC = computeCRC8(data, 2);
if (crc == expectedCRC) // Return true if CRC check is OK
return (true);
if (_printDebug == true)
{
_debugPort->print(F("getSettingValue: CRC fail: expected 0x"));
_debugPort->print(expectedCRC, HEX);
_debugPort->print(F(", got 0x"));
_debugPort->println(crc, HEX);
}
}
return (false);
}
//Gets two bytes from SCD30 //Gets two bytes from SCD30
uint16_t SCD30::readRegister(uint16_t registerAddress) uint16_t SCD30::readRegister(uint16_t registerAddress)
{ {
......
...@@ -6,6 +6,11 @@ ...@@ -6,6 +6,11 @@
Written by Nathan Seidle @ SparkFun Electronics, May 22nd, 2018 Written by Nathan Seidle @ SparkFun Electronics, May 22nd, 2018
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!
The SCD30 measures CO2 with accuracy of +/- 30ppm. The SCD30 measures CO2 with accuracy of +/- 30ppm.
This library handles the initialization of the SCD30 and outputs This library handles the initialization of the SCD30 and outputs
...@@ -14,22 +19,26 @@ ...@@ -14,22 +19,26 @@
https://github.com/sparkfun/SparkFun_SCD30_Arduino_Library https://github.com/sparkfun/SparkFun_SCD30_Arduino_Library
Development environment specifics: Development environment specifics:
Arduino IDE 1.8.5 Arduino IDE 1.8.13
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 General Public License for more details.
You should have received a copy of the GNU General Public License SparkFun code, firmware, and software is released under the MIT License.
along with this program. If not, see <http://www.gnu.org/licenses/>. Please see LICENSE.md for more details.
*/ */
#ifndef __SparkFun_SCD30_ARDUINO_LIBARARY_H__ #ifndef __SparkFun_SCD30_ARDUINO_LIBARARY_H__
#define __SparkFun_SCD30_ARDUINO_LIBARARY_H__ #define __SparkFun_SCD30_ARDUINO_LIBARARY_H__
// 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
#include "Arduino.h" #include "Arduino.h"
#ifdef USE_TEENSY3_I2C_LIB
#include <i2c_t3.h>
#else
#include <Wire.h> #include <Wire.h>
#endif
//The default I2C address for the SCD30 is 0x61. //The default I2C address for the SCD30 is 0x61.
#define SCD30_ADDRESS 0x61 #define SCD30_ADDRESS 0x61
...@@ -44,22 +53,46 @@ ...@@ -44,22 +53,46 @@
#define COMMAND_SET_FORCED_RECALIBRATION_FACTOR 0x5204 #define COMMAND_SET_FORCED_RECALIBRATION_FACTOR 0x5204
#define COMMAND_SET_TEMPERATURE_OFFSET 0x5403 #define COMMAND_SET_TEMPERATURE_OFFSET 0x5403
#define COMMAND_SET_ALTITUDE_COMPENSATION 0x5102 #define COMMAND_SET_ALTITUDE_COMPENSATION 0x5102
#define COMMAND_RESET 0xD304 // Soft reset
#define COMMAND_STOP_MEAS 0x0104
#define COMMAND_READ_FW_VER 0xD100
typedef union {
byte array[4];
float value;
} ByteToFl; // paulvha
class SCD30 class SCD30
{ {
public: public:
SCD30(void); SCD30(void);
bool begin(bool autoCalibrate) { return begin(Wire, autoCalibrate); } bool begin(bool autoCalibrate) { return begin(Wire, autoCalibrate); }
bool begin(TwoWire &wirePort = Wire, bool autoCalibrate=true); //By default use Wire port #ifdef USE_TEENSY3_I2C_LIB
bool begin(i2c_t3 &wirePort = Wire, bool autoCalibrate=true, bool measBegin=true); //By default use Wire port
#else
bool begin(TwoWire &wirePort = Wire, bool autoCalibrate=true, bool measBegin=true); //By default use Wire port
#endif
void enableDebugging(Stream &debugPort = Serial); //Turn on debug printing. If user doesn't specify then Serial will be used.
bool beginMeasuring(uint16_t pressureOffset); bool beginMeasuring(uint16_t pressureOffset);
bool beginMeasuring(void); bool beginMeasuring(void);
bool StopMeasurement(void); // paulvha
// based on paulvha
bool getSettingValue(uint16_t registerAddress, uint16_t *val);
bool getForcedRecalibration(uint16_t *val) {return(getSettingValue(COMMAND_SET_FORCED_RECALIBRATION_FACTOR, val));}
bool getMeasurementInterval(uint16_t *val) {return(getSettingValue(COMMAND_SET_MEASUREMENT_INTERVAL, val));}
bool getTemperatureOffset(uint16_t *val) {return(getSettingValue(COMMAND_SET_TEMPERATURE_OFFSET, val));}
bool getAltitudeCompensation(uint16_t *val) {return(getSettingValue(COMMAND_SET_ALTITUDE_COMPENSATION, val));}
bool getFirmwareVersion(uint16_t *val) {return(getSettingValue(COMMAND_READ_FW_VER, val));}
uint16_t getCO2(void); uint16_t getCO2(void);
float getHumidity(void); float getHumidity(void);
float getTemperature(void); float getTemperature(void);
float getTemperatureOffset(void); float getTemperatureOffset(void);
uint16_t getAltitudeCompensation(void);
bool setMeasurementInterval(uint16_t interval); bool setMeasurementInterval(uint16_t interval);
bool setAmbientPressure(uint16_t pressure_mbar); bool setAmbientPressure(uint16_t pressure_mbar);
...@@ -67,10 +100,13 @@ public: ...@@ -67,10 +100,13 @@ public:
bool setAutoSelfCalibration(bool enable); bool setAutoSelfCalibration(bool enable);
bool setForcedRecalibrationFactor(uint16_t concentration); bool setForcedRecalibrationFactor(uint16_t concentration);
bool setTemperatureOffset(float tempOffset); bool setTemperatureOffset(float tempOffset);
bool getAutoSelfCalibration(void);
bool dataAvailable(); bool dataAvailable();
bool readMeasurement(); bool readMeasurement();
void reset();
bool sendCommand(uint16_t command, uint16_t arguments); bool sendCommand(uint16_t command, uint16_t arguments);
bool sendCommand(uint16_t command); bool sendCommand(uint16_t command);
...@@ -79,9 +115,13 @@ public: ...@@ -79,9 +115,13 @@ public:
uint8_t computeCRC8(uint8_t data[], uint8_t len); uint8_t computeCRC8(uint8_t data[], uint8_t len);
private: private:
//Variables //Variables
#ifdef USE_TEENSY3_I2C_LIB
i2c_t3 *_i2cPort; //The generic connection to user's chosen I2C hardware
#else
TwoWire *_i2cPort; //The generic connection to user's chosen I2C hardware TwoWire *_i2cPort; //The generic connection to user's chosen I2C hardware
#endif
//Global main datums //Global main datums
float co2 = 0; float co2 = 0;
float temperature = 0; float temperature = 0;
...@@ -92,5 +132,10 @@ private: ...@@ -92,5 +132,10 @@ private:
bool co2HasBeenReported = true; bool co2HasBeenReported = true;
bool humidityHasBeenReported = true; bool humidityHasBeenReported = true;
bool temperatureHasBeenReported = true; bool temperatureHasBeenReported = true;
//Debug
Stream *_debugPort; //The stream to send debug messages to if enabled. Usually Serial.
boolean _printDebug = false; //Flag to print debugging variables
}; };
#endif #endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment