Skip to content

Commit

Permalink
Fix sensor determination.
Browse files Browse the repository at this point in the history
Add command to return device type.
Remove determineSensorType function. Replace with getFeatureSetVersion.
Move setSensorType to public.
Remove utility functions convertASCIIToHex and extractMaskedSensorType.
Adapt begin function for new sensor function.
Rev library version.
Revise keywords.txt for the above changes.
  • Loading branch information
SFE-Brudnerd committed Jun 13, 2023
1 parent 67f3677 commit c682c6c
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 128 deletions.
11 changes: 4 additions & 7 deletions examples/Example9_SensorType/Example9_SensorType.ino
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,10 @@ void setup()
;
}

char serialNumber[13];
bool success = mySensor.getSerialNumber(serialNumber);
Serial.print(F("Serial Number is: "));
Serial.println(serialNumber);

Serial.print(F("Getting the sensor type: SCD4"));
Serial.println(mySensor.getSensorType());
scd4x_sensor_type_e sensor;
bool success = mySensor.getFeatureSetVersion(&sensor);
Serial.print(F("Sensor determined to by of type: SCD4"));
Serial.println(sensor);

}

Expand Down
4 changes: 3 additions & 1 deletion keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ measureSingleShotRHTOnly KEYWORD2
sendCommand KEYWORD2
readRegister KEYWORD2
computeCRC8 KEYWORD2
determineSensorType KEYWORD2
getFeatureSetVersion KEYWORD2
getSensorType KEYWORD2
setSensorType KEYWORD2

#######################################
# Constants (LITERAL1)
Expand Down Expand Up @@ -67,5 +68,6 @@ SCD4x_COMMAND_GET_SERIAL_NUMBER LITERAL1
SCD4x_COMMAND_PERFORM_SELF_TEST LITERAL1
SCD4x_COMMAND_PERFORM_FACTORY_RESET LITERAL1
SCD4x_COMMAND_REINIT LITERAL1
SCD4x_COMMAND_GET_FEATURE_SET_VERSION LITERAL1
SCD4x_COMMAND_MEASURE_SINGLE_SHOT LITERAL1
SCD4x_COMMAND_MEASURE_SINGLE_SHOT_RHT_ONLY LITERAL1
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=SparkFun SCD4x Arduino Library
version=1.1.1
version=1.1.2
author=SparkFun Electronics
maintainer=SparkFun Electronics <sparkfun.com>
sentence=Library for the Sensirion SCD4x family of CO2 Sensors (SCD40 and SCD41)
Expand Down
154 changes: 45 additions & 109 deletions src/SparkFun_SCD4x_Arduino_Library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ bool SCD4x::begin(TwoWire &wirePort, bool measBegin, bool autoCalibrate, bool sk
if (pollAndSetDeviceType == true)
{
scd4x_sensor_type_e sensorType;
success &= determineSensorType(&sensorType, serialNumber);
success &= getFeatureSetVersion(&sensorType);

setSensorType(sensorType);

Expand Down Expand Up @@ -870,27 +870,6 @@ char SCD4x::convertHexToASCII(uint8_t digit)
return (char(digit + 0x41 - 10)); // Use upper case for A-F
}

void SCD4x::convertASCIIToHex(const char *hexstr, uint16_t *integers)
{
for (int i = 0; i < 3; i++ ) {
uint16_t val = 0;
for (int j = 0; j < 4; j++ ) {
char c = hexstr[i * 4 + j];
val <<= 4;
if (c >= '0' && c <= '9') {
val += c - '0';
}
else if (c >= 'A' && c <= 'F') {
val += c - 'A' + 10;
}
else if (c >= 'a' && c <= 'f') {
val += c - 'a' + 10;
}
}
integers[i] = val;
}
}

//Perform self test. Takes 10 seconds to complete. See 3.9.3
//The perform_self_test feature can be used as an end-of-line test to check sensor functionality
//and the customer power supply to the sensor.
Expand Down Expand Up @@ -1061,59 +1040,7 @@ bool SCD4x::measureSingleShotRHTOnly(void)
return (success);
}

// Determine Sensor type from the serial number
bool SCD4x::determineSensorType(scd4x_sensor_type_e *sensorType, char *serialNumber)
{
bool success = true;

if(strlen(serialNumber) != 12)
{
#if SCD4x_ENABLE_DEBUGLOG
if (_printDebug == true)
{
_debugPort->println(F("SCD40::getSensorType: S/N is not 13 bytes."));
_debugPort->print(F("SCD40::getSensorType: Num Bytes: "));
_debugPort->println(strlen(serialNumber));
}
#endif // if SCD4x_ENABLE_DEBUGLOG
success = false;
return (success);
}

uint16_t serNumInt[3];
convertASCIIToHex(serialNumber, serNumInt);

#if SCD4x_ENABLE_DEBUGLOG
if (_printDebug == true)
{
_debugPort->print("SCD40::getSensorType: Word 1: ");
_debugPort->println(serNumInt[0], HEX);
_debugPort->print("SCD40::getSensorType: Word 2: ");
_debugPort->println(serNumInt[1], HEX);
_debugPort->print("SCD40::getSensorType: Word 3: ");
_debugPort->println(serNumInt[2], HEX);
}
#endif // if SCD4x_ENABLE_DEBUGLOG

*sensorType = extractMaskedSensorType(serNumInt);

if (*sensorType == SCD4x_SENSOR_INVALID)
{
#if SCD4x_ENABLE_DEBUGLOG
if (_printDebug == true)
{
_debugPort->println("SCD40::getSensorType: Invalid Sensor Type Determined.");
}
#endif // if SCD4x_ENABLE_DEBUGLOG
*sensorType = SCD4x_SENSOR_SCD40; // Pick a default so we don't break things.
success = false;
return (success);
}

return (success);
}

scd4x_sensor_type_e SCD4x::getSensorType()
scd4x_sensor_type_e SCD4x::getSensorType(void)
{
return _sensorType;
}
Expand All @@ -1123,71 +1050,80 @@ void SCD4x::setSensorType(scd4x_sensor_type_e sensorType)
_sensorType = sensorType;
}

// Extract the Sensor type (SCD40 vs SCD41) from the Serial Number of the connected device.
scd4x_sensor_type_e SCD4x::extractMaskedSensorType(uint16_t *serialNumberArray)
bool SCD4x::getFeatureSetVersion(scd4x_sensor_type_e* sensorType)
{
// Of the 48-bit serial number, the Type is identified by bits 24-37
// 0bxxxx'xxxx'xx11'1111'1111'1111'xxxx'xxxx'xxxx'xxxx'xxxx'xxxx
uint16_t masks[] = {0x003F, 0xFF00};

uint16_t maskedValues[2];
uint16_t combinedValue = 0;

for (int i = 0; i < 2; i++) {
maskedValues[i] = serialNumberArray[i] & masks[i];
if (periodicMeasurementsAreRunning)
{
#if SCD4x_ENABLE_DEBUGLOG
if(_printDebug == true) {
_debugPort->print("SCD40::extractMaskedSensorType: i: ");
_debugPort->println(i);
_debugPort->print("SCD40::extractMaskedSensorType: serialNumberArray[i]: ");
_debugPort->println(serialNumberArray[i], HEX);
_debugPort->print("SCD40::extractMaskedSensorType: masks[i]: ");
_debugPort->println(masks[i], HEX);
_debugPort->print("SCD40::extractMaskedSensorType: maskedValues[i]: ");
_debugPort->println(maskedValues[i], HEX);
if (_printDebug == true)
{
_debugPort->println(F("SCD4x::getFeatureSetVersion: periodic measurements are running. Aborting..."));
}
#endif // if SCD4x_ENABLE_DEBUGLOG
#endif // SCD4x_ENABLE_DEBUGLOG
return (false);
}

combinedValue = (maskedValues[0] << 8) | (maskedValues[1] >> 8);
uint16_t featureSet;

bool success = readRegister(SCD4x_COMMAND_GET_FEATURE_SET_VERSION, &featureSet, 1);

#if SCD4x_ENABLE_DEBUGLOG
if (_printDebug == true)
if (_printDebug == true)
{
_debugPort->print("SCD40::extractMaskedSensorType: Combined Value: ");
_debugPort->println(combinedValue, HEX);
_debugPort->print(F("SCD4x::getFeatureSetVersion: Read value: 0x"));
_debugPort->println(featureSet, HEX);
}
#endif // if SCD4x_ENABLE_DEBUGLOG
#endif // SCD4x_ENABLE_DEBUGLOG

uint8_t typeOfSensor = ((featureSet & 0x1000) >> 12);

#if SCD4x_ENABLE_DEBUGLOG
if (_printDebug == true)
{
_debugPort->print(F("SCD4x::getFeatureSetVersion: Type read: 0x"));
_debugPort->println(typeOfSensor, HEX);
}
#endif // SCD4x_ENABLE_DEBUGLOG

if (combinedValue == 0x376F)
if (typeOfSensor == 0)
{
#if SCD4x_ENABLE_DEBUGLOG
if (_printDebug == true)
{
_debugPort->println("SCD40::extractMaskedSensorType: Picked SCD41");
_debugPort->println(F("SCD4x::getFeatureSetVersion: Picked SCD40"));
}
#endif // if SCD4x_ENABLE_DEBUGLOG
return SCD4x_SENSOR_SCD41;
*sensorType = SCD4x_SENSOR_SCD40;
}
else if (combinedValue == 0x2397)
else if (typeOfSensor == 1)
{
#if SCD4x_ENABLE_DEBUGLOG
if (_printDebug == true)
{
_debugPort->println("SCD40::extractMaskedSensorType: Picked SCD40");
_debugPort->println(F("SCD4x::getFeatureSetVersion: Picked SCD41"));
}
#endif // if SCD4x_ENABLE_DEBUGLOG
return SCD4x_SENSOR_SCD40;
*sensorType = SCD4x_SENSOR_SCD41;
}
else
{
#if SCD4x_ENABLE_DEBUGLOG
if (_printDebug == true) {
_debugPort->println("SCD40::extractMaskedSensorType: Something's seriously wrong here...");
if(typeOfSensor == 2)
{
_debugPort->println(F("SCD4x::getFeatureSetVersion: SCD42 is not supported by this library."));
}
else
{
_debugPort->println(F("SCD4x::getFeatureSetVersion: Unknown device type."));
}
}
#endif // if SCD4x_ENABLE_DEBUGLOG
return SCD4x_SENSOR_INVALID;
*sensorType = SCD4x_SENSOR_INVALID;
success = false;
}

return (success);
}

//Sends a command along with arguments and CRC
Expand Down
14 changes: 4 additions & 10 deletions src/SparkFun_SCD4x_Arduino_Library.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
#define SCD4x_COMMAND_PERFORM_SELF_TEST 0x3639 // execution time: 10000ms
#define SCD4x_COMMAND_PERFORM_FACTORY_RESET 0x3632 // execution time: 1200ms
#define SCD4x_COMMAND_REINIT 0x3646 // execution time: 20ms
#define SCD4x_COMMAND_GET_FEATURE_SET_VERSION 0x202F // execution time: 1ms

//Low power single shot - SCD41 only
#define SCD4x_COMMAND_MEASURE_SINGLE_SHOT 0x219d // execution time: 5000ms
Expand Down Expand Up @@ -184,8 +185,9 @@ class SCD4x

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

bool determineSensorType(scd4x_sensor_type_e *sensorType, char *serialNumber); // Determine sensor type from serial number.
scd4x_sensor_type_e getSensorType(); // Get the sensor type stored in the struct.
bool getFeatureSetVersion(scd4x_sensor_type_e* sensorType);
scd4x_sensor_type_e getSensorType(void); // Get the sensor type stored in the struct.
void setSensorType(scd4x_sensor_type_e sensorType); // Set the sensor type for the device.

private:
//Variables
Expand Down Expand Up @@ -215,14 +217,6 @@ class SCD4x
//Convert serial number digit to ASCII
char convertHexToASCII(uint8_t digit);

// Convert serial number string to hex digits.
void convertASCIIToHex(const char *hexstr, uint16_t *integers);

// Helper function to compare the serial number to known IDs.
scd4x_sensor_type_e extractMaskedSensorType(uint16_t *serialNumberArray);

void setSensorType(scd4x_sensor_type_e sensorType); // Set the sensor type for the device.

#if SCD4x_ENABLE_DEBUGLOG
//Debug
Stream *_debugPort; //The stream to send debug messages to if enabled. Usually Serial.
Expand Down

0 comments on commit c682c6c

Please sign in to comment.