0.3.0 SGP30

This commit is contained in:
Rob Tillaart 2023-12-08 19:50:19 +01:00
parent 9b179fd414
commit ae3eb4f466
15 changed files with 122 additions and 93 deletions

View File

@ -6,11 +6,18 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/). and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.3.0] - 2023-12-08
- refactor API, begin()
- update readme.md
- update examples
- minor edits
----
## [0.2.1] - 2023-09-25 ## [0.2.1] - 2023-09-25
- add Wire1 support for ESP32 - add Wire1 support for ESP32
- update readme.md - update readme.md
## [0.2.0] - 2023-01-27 ## [0.2.0] - 2023-01-27
- Fix setBaseline() ==> PR #11 (kudos to countrysidecowboy) - Fix setBaseline() ==> PR #11 (kudos to countrysidecowboy)
- update GitHub actions - update GitHub actions

View File

@ -34,6 +34,15 @@ Note: the sync interface is implemented with the async interface.
Note: versions prior to 0.2.0 are obsolete due to a bug in **setBaseline()**. Note: versions prior to 0.2.0 are obsolete due to a bug in **setBaseline()**.
#### 0.3.0 Breaking change
Version 0.3.0 introduced a breaking change.
You cannot set the pins in **begin()** any more.
This reduces the dependency of processor dependent Wire implementations.
The user has to call **Wire.begin()** and can optionally set the Wire pins
before calling **begin()**.
#### Sample frequency #### Sample frequency
The CO2 and TVOC values can be read up to once per second (1 Hz). The CO2 and TVOC values can be read up to once per second (1 Hz).
@ -70,11 +79,20 @@ or switch the VCC as a sort of ChipSelect signal.
- https://github.com/RobTillaart/TCA9548 (I2C 8 channel multiplexer) - https://github.com/RobTillaart/TCA9548 (I2C 8 channel multiplexer)
#### Links #### Related
- https://www.adafruit.com/product/3709 - the sensor. CO2 sensors and more.
- https://www.adafruit.com/product/3709 - the SGP30 sensor.
- https://emariete.com/en/sensor-co2-mh-z19b/
- https://emariete.com/en/sensor-co2-low-consumption-mh-z1311a-winsen/
- https://revspace.nl/MHZ19
- https://www.co2.earth/ - current outdoor CO2 level can be used for calibrating. - https://www.co2.earth/ - current outdoor CO2 level can be used for calibrating.
- https://keelingcurve.ucsd.edu/ - historical outdoor CO2 level. - https://keelingcurve.ucsd.edu/ - historical outdoor CO2 level.
- https://github.com/RobTillaart/ACD10
- https://github.com/RobTillaart/MTP40C
- https://github.com/RobTillaart/MTP40F
- https://github.com/RobTillaart/Cozir
## Interface ## Interface
@ -86,9 +104,9 @@ or switch the VCC as a sort of ChipSelect signal.
#### Constructor #### Constructor
- **SGP30(TwoWire \*wire = &Wire)** Constructor with optional the Wire interface as parameter. - **SGP30(TwoWire \*wire = &Wire)** Constructor with optional the Wire interface as parameter.
- **bool begin()** starts the I2C bus and returns true if the device address 0x58 is visible on the I2C bus. - **bool begin()** initializes the library.
- **bool begin(uint8_t sda, uint8_t scl)** idem, for the ESP32 where one can choose the I2C pins. Returns true if the (fixed) device address 0x58 is visible on the I2C bus.
- **bool isConnected()** checks if the address 0x58 is visible on the I2C bus. - **bool isConnected()** checks if the device address 0x58 is visible on the I2C bus.
- **void GenericReset()** WARNING resets all I2C devices on the bus that support this call! - **void GenericReset()** WARNING resets all I2C devices on the bus that support this call!
@ -198,23 +216,18 @@ The used references are based upon
## Future ## Future
#### Must #### Must
- improve documentation - improve documentation
#### Should #### Should
- test - test
- different boards - different boards
- different gasses / atmosphere if possible. - different gasses / atmosphere if possible.
#### Could #### Could
- redo **getID()**
- make defines for the magic numbers (commands)
- move code from .h to .cpp - move code from .h to .cpp
- improve/merge the private **command()** function - improve/merge the private **command()** function
- add/extend error handling - add/extend error handling
@ -222,10 +235,12 @@ The used references are based upon
The CRC checking + error handling (since 0.1.4) adds around 330 bytes PROGMEM on an UNO. The CRC checking + error handling (since 0.1.4) adds around 330 bytes PROGMEM on an UNO.
There might be a need for a minimal class that only reads CO2 and TVOC, no baselines etc. There might be a need for a minimal class that only reads CO2 and TVOC, no baselines etc.
for the smallest platforms. for the smallest platforms e.g. tiny.
#### Wont (unless)
#### Wont - make defines for the magic numbers (commands)
- only used once.
## Support ## Support

View File

@ -1,7 +1,7 @@
// //
// FILE: SGP30.cpp // FILE: SGP30.cpp
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.2.1 // VERSION: 0.3.0
// DATE: 2021-06-24 // DATE: 2021-06-24
// PURPOSE: Arduino library for SGP30 environment sensor. // PURPOSE: Arduino library for SGP30 environment sensor.
// URL: https://github.com/RobTillaart/SGP30 // URL: https://github.com/RobTillaart/SGP30
@ -30,24 +30,8 @@ SGP30::SGP30(TwoWire *wire)
} }
#if defined (ESP8266) || defined(ESP32)
bool SGP30::begin(uint8_t dataPin, uint8_t clockPin)
{
if ((dataPin < 255) && (clockPin < 255))
{
_wire->begin(dataPin, clockPin);
} else {
_wire->begin();
}
if (! isConnected()) return false;
return true;
}
#endif
bool SGP30::begin() bool SGP30::begin()
{ {
_wire->begin();
if (! isConnected()) return false; if (! isConnected()) return false;
_init(); _init();
return true; return true;
@ -61,19 +45,21 @@ bool SGP30::isConnected()
} }
// INITIAL VERSION - needs optimization
bool SGP30::getID() bool SGP30::getID()
{ {
_command(0x3682); _command(0x3682);
delay(1); delay(1);
if (_wire->requestFrom(_address, (uint8_t)9) == 9) if (_wire->requestFrom(_address, (uint8_t)9) != 9)
{ {
for (uint8_t i = 0, j = 0; i < 3; i++) _error = SGP30_ERROR_I2C;
return false;
}
for (uint8_t i = 0; i < 6; )
{ {
_id[j++] = _wire->read(); _id[i++] = _wire->read();
_id[j++] = _wire->read(); _id[i++] = _wire->read();
uint8_t crc = _wire->read(); uint8_t crc = _wire->read();
uint16_t val = _id[j-2] * 256 + _id[j-1]; uint16_t val = _id[i-2] * 256 + _id[i-1];
if (_CRC8(val) != crc) if (_CRC8(val) != crc)
{ {
_error = SGP30_ERROR_CRC; _error = SGP30_ERROR_CRC;
@ -82,9 +68,7 @@ bool SGP30::getID()
} }
_error = SGP30_OK; _error = SGP30_OK;
return true; return true;
}
_error = SGP30_ERROR_I2C;
return false;
} }

View File

@ -2,7 +2,7 @@
// //
// FILE: SGP30.h // FILE: SGP30.h
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.2.1 // VERSION: 0.3.0
// DATE: 2021-06-24 // DATE: 2021-06-24
// PURPOSE: Arduino library for SGP30 environment sensor. // PURPOSE: Arduino library for SGP30 environment sensor.
// URL: https://github.com/RobTillaart/SGP30 // URL: https://github.com/RobTillaart/SGP30
@ -12,7 +12,7 @@
#include "Arduino.h" #include "Arduino.h"
#include "Wire.h" #include "Wire.h"
#define SGP30_LIB_VERSION (F("0.2.1")) #define SGP30_LIB_VERSION (F("0.3.0"))
#define SGP30_OK 0x00 #define SGP30_OK 0x00
#define SGP30_ERROR_CRC 0xFF #define SGP30_ERROR_CRC 0xFF
@ -24,9 +24,6 @@ class SGP30
public: public:
explicit SGP30(TwoWire *wire = &Wire); explicit SGP30(TwoWire *wire = &Wire);
#if defined (ESP8266) || defined(ESP32)
bool begin(uint8_t sda, uint8_t scl);
#endif
bool begin(); bool begin();
bool isConnected(); bool isConnected();
// WARNING resets all I2C devices that support this call !! // WARNING resets all I2C devices that support this call !!

View File

@ -2,7 +2,6 @@
// FILE: SGP30_I2C_performance.ino // FILE: SGP30_I2C_performance.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// PURPOSE: demo SGP30 // PURPOSE: demo SGP30
// DATE: 2021-06-25
// URL: https://github.com/RobTillaart/SGP30 // URL: https://github.com/RobTillaart/SGP30
// https://www.adafruit.com/product/3709 // https://www.adafruit.com/product/3709
@ -22,10 +21,13 @@ void setup()
yield(); yield();
}; };
Serial.print(__FILE__); Serial.println(__FILE__);
Serial.print("SGP30_LIB_VERSION: ");
Serial.println(SGP30_LIB_VERSION); Serial.println(SGP30_LIB_VERSION);
Serial.println(); Serial.println();
Wire.begin();
Serial.print("BEGIN:\t"); Serial.print("BEGIN:\t");
Serial.println(SGP.begin()); Serial.println(SGP.begin());
Serial.print("TEST:\t"); Serial.print("TEST:\t");
@ -47,6 +49,7 @@ void setup()
delay(1000); delay(1000);
} }
// has 40 millisecond delay build in... // has 40 millisecond delay build in...
Serial.println("\nMEASURE()"); Serial.println("\nMEASURE()");
for (uint32_t sp = 100000; sp <= 500000; sp += 50000) for (uint32_t sp = 100000; sp <= 500000; sp += 50000)
@ -75,6 +78,7 @@ void setup()
delay(1000); delay(1000);
} }
Serial.println("\nREAD()"); Serial.println("\nREAD()");
for (uint32_t sp = 100000; sp <= 500000; sp += 50000) for (uint32_t sp = 100000; sp <= 500000; sp += 50000)
{ {

View File

@ -2,14 +2,12 @@
// FILE: SGP30_baseline.ino // FILE: SGP30_baseline.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// PURPOSE: demo SGP30 // PURPOSE: demo SGP30
// DATE: 2021-06-25
// URL: https://github.com/RobTillaart/SGP30 // URL: https://github.com/RobTillaart/SGP30
// https://www.adafruit.com/product/3709 // https://www.adafruit.com/product/3709
#include "SGP30.h" #include "SGP30.h"
SGP30 SGP; SGP30 SGP;
uint8_t count = 0; uint8_t count = 0;
@ -23,10 +21,13 @@ void setup()
yield(); yield();
}; };
Serial.print(__FILE__); Serial.println(__FILE__);
Serial.print("SGP30_LIB_VERSION: ");
Serial.println(SGP30_LIB_VERSION); Serial.println(SGP30_LIB_VERSION);
Serial.println(); Serial.println();
Wire.begin();
SGP.begin(); SGP.begin();
} }

View File

@ -2,7 +2,6 @@
// FILE: SGP30_demo.ino // FILE: SGP30_demo.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// PURPOSE: demo SGP30 // PURPOSE: demo SGP30
// DATE: 2021-06-24
// URL: https://github.com/RobTillaart/SGP30 // URL: https://github.com/RobTillaart/SGP30
// https://www.adafruit.com/product/3709 // https://www.adafruit.com/product/3709
@ -23,10 +22,13 @@ void setup()
yield(); yield();
}; };
Serial.print(__FILE__); Serial.println(__FILE__);
Serial.print("SGP30_LIB_VERSION: ");
Serial.println(SGP30_LIB_VERSION); Serial.println(SGP30_LIB_VERSION);
Serial.println(); Serial.println();
Wire.begin();
Serial.print("BEGIN:\t"); Serial.print("BEGIN:\t");
Serial.println(SGP.begin()); Serial.println(SGP.begin());
Serial.print("TEST:\t"); Serial.print("TEST:\t");
@ -39,7 +41,8 @@ void setup()
SGP.getID(); SGP.getID();
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
{ {
if (SGP._id[i] < 0x10) Serial.print(0); // ÏD: 00.00.01.9B.57.23 // ÏD looks like: 00.00.01.9B.57.23
if (SGP._id[i] < 0x10) Serial.print(0);
Serial.print(SGP._id[i], HEX); Serial.print(SGP._id[i], HEX);
} }
Serial.println(); Serial.println();

View File

@ -2,7 +2,6 @@
// FILE: SGP30_demo_H2_Ethanol.ino // FILE: SGP30_demo_H2_Ethanol.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// PURPOSE: demo SGP30 // PURPOSE: demo SGP30
// DATE: 2021-06-24
// URL: https://github.com/RobTillaart/SGP30 // URL: https://github.com/RobTillaart/SGP30
// https://www.adafruit.com/product/3709 // https://www.adafruit.com/product/3709
// //
@ -15,6 +14,7 @@
SGP30 SGP; SGP30 SGP;
uint8_t count = 0; uint8_t count = 0;
uint32_t lastTime = 0; uint32_t lastTime = 0;
@ -31,10 +31,13 @@ void setup()
yield(); yield();
}; };
Serial.print(__FILE__); Serial.println(__FILE__);
Serial.print("SGP30_LIB_VERSION: ");
Serial.println(SGP30_LIB_VERSION); Serial.println(SGP30_LIB_VERSION);
Serial.println(); Serial.println();
Wire.begin();
Serial.print("BEGIN:\t"); Serial.print("BEGIN:\t");
Serial.println(SGP.begin()); Serial.println(SGP.begin());
Serial.print("TEST:\t"); Serial.print("TEST:\t");

View File

@ -2,18 +2,15 @@
// FILE: SGP30_demo_async.ino // FILE: SGP30_demo_async.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// PURPOSE: demo SGP30 // PURPOSE: demo SGP30
// DATE: 2021-06-24
// URL: https://github.com/RobTillaart/SGP30 // URL: https://github.com/RobTillaart/SGP30
// https://www.adafruit.com/product/3709 // https://www.adafruit.com/product/3709
#include "SGP30.h" #include "SGP30.h"
SGP30 SGP; SGP30 SGP;
uint8_t count = 0; uint8_t count = 0;
uint32_t lastTime = 0; uint32_t lastTime = 0;
@ -22,10 +19,13 @@ void setup()
Serial.begin(115200); Serial.begin(115200);
while (!Serial) delay(1); while (!Serial) delay(1);
Serial.print(__FILE__); Serial.println(__FILE__);
Serial.print("SGP30_LIB_VERSION: ");
Serial.println(SGP30_LIB_VERSION); Serial.println(SGP30_LIB_VERSION);
Serial.println(); Serial.println();
Wire.begin();
Serial.print("BEGIN:\t"); Serial.print("BEGIN:\t");
Serial.println(SGP.begin()); Serial.println(SGP.begin());
Serial.print("TEST:\t"); Serial.print("TEST:\t");

View File

@ -2,7 +2,6 @@
// FILE: SGP30_demo_error.ino // FILE: SGP30_demo_error.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// PURPOSE: demo SGP30 // PURPOSE: demo SGP30
// DATE: 2021-07-01
// URL: https://github.com/RobTillaart/SGP30 // URL: https://github.com/RobTillaart/SGP30
// https://www.adafruit.com/product/3709 // https://www.adafruit.com/product/3709
@ -23,10 +22,13 @@ void setup()
yield(); yield();
}; };
Serial.print(__FILE__); Serial.println(__FILE__);
Serial.print("SGP30_LIB_VERSION: ");
Serial.println(SGP30_LIB_VERSION); Serial.println(SGP30_LIB_VERSION);
Serial.println(); Serial.println();
Wire.begin();
Serial.print("BEGIN:\t"); Serial.print("BEGIN:\t");
Serial.println(SGP.begin()); Serial.println(SGP.begin());
Serial.print("TEST:\t"); Serial.print("TEST:\t");
@ -39,7 +41,8 @@ void setup()
SGP.getID(); SGP.getID();
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
{ {
if (SGP._id[i] < 0x10) Serial.print(0); // ÏD: 00.00.01.9B.57.23 // ÏD looks like: 00.00.01.9B.57.23
if (SGP._id[i] < 0x10) Serial.print(0);
Serial.print(SGP._id[i], HEX); Serial.print(SGP._id[i], HEX);
} }
Serial.println(); Serial.println();

View File

@ -9,6 +9,7 @@
#include "SGP30.h" #include "SGP30.h"
#define PLOT_HEADER "TVOC\tCO2"
SGP30 SGP; SGP30 SGP;
@ -18,8 +19,15 @@ void setup()
Serial.begin(115200); Serial.begin(115200);
while (!Serial) delay(1); while (!Serial) delay(1);
Serial.print(__FILE__); // Serial.println(__FILE__);
// Serial.print("SGP30_LIB_VERSION: ");
// Serial.println(SGP30_LIB_VERSION);
// Serial.println();
Wire.begin();
SGP.begin(); SGP.begin();
Serial.println(PLOT_HEADER);
} }

View File

@ -21,15 +21,15 @@ void setup()
delay(1); delay(1);
yield(); yield();
}; };
Serial.println(__FILE__);
Serial.print(__FILE__); Serial.print("SGP30_LIB_VERSION: ");
Serial.println(SGP30_LIB_VERSION); Serial.println(SGP30_LIB_VERSION);
Serial.println(); Serial.println();
Wire.begin();
SGP.begin(); SGP.begin();
Serial.println(SGP.setRelHumidity(21, 50), HEX); Serial.println(SGP.setRelHumidity(21, 50), HEX);
Serial.println(); Serial.println();
} }

View File

@ -15,7 +15,7 @@
"type": "git", "type": "git",
"url": "https://github.com/RobTillaart/SGP30.git" "url": "https://github.com/RobTillaart/SGP30.git"
}, },
"version": "0.2.1", "version": "0.3.0",
"license": "MIT", "license": "MIT",
"frameworks": "*", "frameworks": "*",
"platforms": "*", "platforms": "*",

View File

@ -1,5 +1,5 @@
name=SGP30 name=SGP30
version=0.2.1 version=0.3.0
author=Rob Tillaart <rob.tillaart@gmail.com> author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com> maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for SGP30 environment sensor. sentence=Arduino library for SGP30 environment sensor.

View File

@ -52,6 +52,7 @@ unittest(test_constructor)
{ {
SGP30 SGP; SGP30 SGP;
Wire.begin();
assertTrue(SGP.begin()); assertTrue(SGP.begin());
assertTrue(SGP.isConnected()); assertTrue(SGP.isConnected());
@ -72,6 +73,7 @@ unittest(test_defaults_core)
{ {
SGP30 SGP; SGP30 SGP;
Wire.begin();
assertEqual(0x00, SGP.getCO2()); assertEqual(0x00, SGP.getCO2());
assertEqual(0x00, SGP.getTVOC()); assertEqual(0x00, SGP.getTVOC());
assertEqual(0x00, SGP.getH2_raw()); assertEqual(0x00, SGP.getH2_raw());
@ -85,6 +87,7 @@ unittest(test_sref_H2)
{ {
SGP30 SGP; SGP30 SGP;
Wire.begin();
assertEqual(13119, SGP.getSrefH2()); assertEqual(13119, SGP.getSrefH2());
SGP.setSrefH2(0); SGP.setSrefH2(0);
@ -102,6 +105,7 @@ unittest(test_sref_Ethanol)
{ {
SGP30 SGP; SGP30 SGP;
Wire.begin();
assertEqual(18472, SGP.getSrefEthanol()); assertEqual(18472, SGP.getSrefEthanol());
SGP.setSrefEthanol(0); SGP.setSrefEthanol(0);