Skip to content

Commit 3c6b8b3

Browse files
authored
Merge pull request #29 from Sensirion/fix-probing
Fix issue with probing
2 parents 8f006f1 + 4dccb39 commit 3c6b8b3

File tree

13 files changed

+207
-212
lines changed

13 files changed

+207
-212
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ latex
55
src/html/**
66
src/latex/**
77
examples/**/*.cpp
8+
.idea/

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [3.0.1]
11+
12+
### Fixed
13+
- Fix probing not working without power cycle for certain sensors, if e.g. a measurement was still ongoing.
14+
1015
## [3.0.0]
1116

1217
### Added

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=Sensirion UPT I2C Auto Detection
2-
version=3.0.0
2+
version=3.0.1
33
author=Jonas Stolle, Maximilian Paulsen
44
maintainer=Sensirion AG <sensirion.com>
55
sentence=Automatically detects Sensirion Sensors on an I2C bus and reads out measurement data.

platformio.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ default_envs = basicUsage
1313

1414
[common]
1515
lib_deps_external =
16-
Sensirion/Sensirion Core@0.7.1
16+
Sensirion/Sensirion Core@0.7.2
1717
Sensirion/Sensirion UPT Core@^1.0.0
1818
Sensirion/Sensirion I2C SHT4x@1.1.2
1919
Sensirion/Sensirion I2C SCD4x@1.1.0
2020
Sensirion/Sensirion I2C SFA3x@1.0.0
2121
Sensirion/Sensirion I2C SVM4x@0.2.0
2222
Sensirion/Sensirion I2C SEN5X@0.3.0
23-
Sensirion/Sensirion I2C SCD30@0.1.0
23+
Sensirion/Sensirion I2C SCD30@1.0.0
2424
Sensirion/Sensirion I2C SGP41@1.0.0
2525
Sensirion/Sensirion I2C STC3x@1.0.1
2626
Sensirion/Sensirion I2C SEN66@1.1.0

src/SensorWrappers/Scd30.cpp

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
#include "SensirionCore.h"
33
#include "Sensirion_UPT_Core.h"
44

5-
namespace sensirion::upt::i2c_autodetect{
5+
namespace sensirion::upt::i2c_autodetect {
66

7-
Scd30::Scd30(TwoWire& wire, const uint16_t address) :
8-
mWire(wire), mAddress{address}, mMetadata{core::SCD30()}{};
7+
Scd30::Scd30(TwoWire& wire, const uint16_t address)
8+
: mWire(wire), mAddress{address}, mMetadata{core::SCD30()} {};
99

1010
uint16_t Scd30::start() {
1111
mDriver.begin(mWire, mAddress);
@@ -24,7 +24,6 @@ uint16_t Scd30::measureAndWrite(MeasurementList& measurements,
2424
return 1;
2525
}
2626

27-
2827
float co2Concentration;
2928
float temperature;
3029
float humidity;
@@ -34,30 +33,29 @@ uint16_t Scd30::measureAndWrite(MeasurementList& measurements,
3433
return error;
3534
}
3635

37-
measurements.emplace_back(mMetadata,
38-
core::SignalType::CO2_PARTS_PER_MILLION,
39-
core::DataPoint{timeStamp, co2Concentration});
36+
measurements.emplace_back(mMetadata,
37+
core::SignalType::CO2_PARTS_PER_MILLION,
38+
core::DataPoint{timeStamp, co2Concentration});
4039

41-
measurements.emplace_back(mMetadata,
42-
core::SignalType::TEMPERATURE_DEGREES_CELSIUS,
43-
core::DataPoint{timeStamp, temperature});
40+
measurements.emplace_back(mMetadata,
41+
core::SignalType::TEMPERATURE_DEGREES_CELSIUS,
42+
core::DataPoint{timeStamp, temperature});
4443

45-
measurements.emplace_back(mMetadata,
46-
core::SignalType::RELATIVE_HUMIDITY_PERCENTAGE,
47-
core::DataPoint{timeStamp, humidity});
44+
measurements.emplace_back(mMetadata,
45+
core::SignalType::RELATIVE_HUMIDITY_PERCENTAGE,
46+
core::DataPoint{timeStamp, humidity});
4847

49-
50-
/* Prepare next reading by querying the dataReadyFlag. We don't need the
48+
/* Prepare the next reading by querying the dataReadyFlag. We don't need the
5149
* value of the flag, but the query seems to finalize setting off the
52-
* measurement process, and enables much faster signal readout at the next
50+
* measurement process and enables a much faster signal readout at the next
5351
* call of this function as it then is not required to enter a wait loop
5452
* (see SensirionI2cScd30::blockingReadMeasurementData()). This procedure is
5553
* only required for SCD30. */
5654
error = mDriver.getDataReady(dataReadyFlag);
5755
if (error) {
5856
return error;
5957
}
60-
return HighLevelError::NoError;
58+
return NoError;
6159
}
6260

6361
uint16_t Scd30::initializationStep() {
@@ -105,11 +103,13 @@ unsigned long Scd30::getMinimumMeasurementIntervalMs() const {
105103

106104
bool Scd30::probe() {
107105
uint8_t major, minor;
108-
uint16_t error = mDriver.readFirmwareVersion(major, minor);
109-
return (error == HighLevelError::NoError);
106+
// stop potential running measurement
107+
mDriver.stopPeriodicMeasurement();
108+
const uint16_t error = mDriver.readFirmwareVersion(major, minor);
109+
return (error == NoError);
110110
}
111111

112112
void* Scd30::getDriver() {
113-
return reinterpret_cast<void*>(&mDriver);
113+
return &mDriver;
114114
}
115-
} // namespace sensirion::upt::i2c_autodetect
115+
} // namespace sensirion::upt::i2c_autodetect

src/SensorWrappers/Scd4x.cpp

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
#include "SensirionCore.h"
33
#include "Sensirion_UPT_Core.h"
44

5-
namespace sensirion::upt::i2c_autodetect{
5+
namespace sensirion::upt::i2c_autodetect {
66

7-
Scd4x::Scd4x(TwoWire& wire, const uint16_t address) : mWire(wire),
8-
mAddress{address},
9-
mMetadata{core::SCD4X()}{};
7+
Scd4x::Scd4x(TwoWire& wire, const uint16_t address)
8+
: mWire(wire), mAddress{address}, mMetadata{core::SCD4X()} {};
109

1110
uint16_t Scd4x::start() {
1211
mDriver.begin(mWire, mAddress);
@@ -18,22 +17,22 @@ uint16_t Scd4x::measureAndWrite(MeasurementList& measurements,
1817
uint16_t co2;
1918
float temp;
2019
float humi;
21-
uint16_t error = mDriver.readMeasurement(co2, temp, humi);
20+
const uint16_t error = mDriver.readMeasurement(co2, temp, humi);
2221
if (error) {
2322
return error;
2423
}
2524

26-
measurements.emplace_back(mMetadata,
27-
core::SignalType::CO2_PARTS_PER_MILLION,
25+
measurements.emplace_back(
26+
mMetadata, core::SignalType::CO2_PARTS_PER_MILLION,
2827
core::DataPoint{timeStamp, static_cast<float>(co2)});
2928

30-
measurements.emplace_back(mMetadata,
31-
core::SignalType::TEMPERATURE_DEGREES_CELSIUS,
32-
core::DataPoint{timeStamp, temp});
29+
measurements.emplace_back(mMetadata,
30+
core::SignalType::TEMPERATURE_DEGREES_CELSIUS,
31+
core::DataPoint{timeStamp, temp});
3332

34-
measurements.emplace_back(mMetadata,
35-
core::SignalType::RELATIVE_HUMIDITY_PERCENTAGE,
36-
core::DataPoint{timeStamp, humi});
33+
measurements.emplace_back(mMetadata,
34+
core::SignalType::RELATIVE_HUMIDITY_PERCENTAGE,
35+
core::DataPoint{timeStamp, humi});
3736

3837
return HighLevelError::NoError;
3938
}
@@ -86,16 +85,19 @@ unsigned long Scd4x::getInitializationIntervalMs() const {
8685
}
8786

8887
bool Scd4x::probe() {
88+
// stop potential running measurement
89+
mDriver.stopPeriodicMeasurement();
8990
SCD4xSensorVariant aSensorVariant = SCD4X_SENSOR_VARIANT_MASK;
90-
uint16_t error = mDriver.getSensorVariant(aSensorVariant);
91-
bool isKnownVariant = (aSensorVariant == SCD4X_SENSOR_VARIANT_SCD40) ||
92-
(aSensorVariant == SCD4X_SENSOR_VARIANT_SCD41) ||
93-
(aSensorVariant == SCD4X_SENSOR_VARIANT_SCD42) ||
94-
(aSensorVariant == SCD4X_SENSOR_VARIANT_SCD43);
91+
const uint16_t error = mDriver.getSensorVariant(aSensorVariant);
92+
const bool isKnownVariant =
93+
(aSensorVariant == SCD4X_SENSOR_VARIANT_SCD40) ||
94+
(aSensorVariant == SCD4X_SENSOR_VARIANT_SCD41) ||
95+
(aSensorVariant == SCD4X_SENSOR_VARIANT_SCD42) ||
96+
(aSensorVariant == SCD4X_SENSOR_VARIANT_SCD43);
9597
return (error == 0 && isKnownVariant);
9698
}
9799

98100
void* Scd4x::getDriver() {
99-
return std::addressof(mDriver);
101+
return &mDriver;
100102
}
101-
} // namespace sensirion::upt::i2c_autodetect
103+
} // namespace sensirion::upt::i2c_autodetect

src/SensorWrappers/Sen5x.cpp

Lines changed: 34 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22
#include "SensirionCore.h"
33
#include <map>
44

5-
namespace sensirion::upt::i2c_autodetect{
5+
namespace sensirion::upt::i2c_autodetect {
66

7-
Sen5x::Sen5x(TwoWire& wire, uint16_t address) :
8-
mWire(wire),
9-
mAddress{address},
10-
mMetadata{core::SEN5X()} {};
7+
Sen5x::Sen5x(TwoWire& wire, uint16_t address)
8+
: mWire(wire), mAddress{address}, mMetadata{core::SEN5X()} {};
119

1210
uint16_t Sen5x::start() {
1311
mDriver.begin(mWire);
@@ -37,48 +35,41 @@ uint16_t Sen5x::measureAndWrite(MeasurementList& measurements,
3735
return error;
3836
}
3937

40-
measurements.emplace_back(mMetadata,
41-
core::SignalType::PM1P0_MICRO_GRAMM_PER_CUBIC_METER,
38+
measurements.emplace_back(
39+
mMetadata, core::SignalType::PM1P0_MICRO_GRAMM_PER_CUBIC_METER,
4240
core::DataPoint{timeStamp, massConcentrationPm1p0});
4341

44-
measurements.emplace_back(mMetadata,
45-
core::SignalType::PM2P5_MICRO_GRAMM_PER_CUBIC_METER,
42+
measurements.emplace_back(
43+
mMetadata, core::SignalType::PM2P5_MICRO_GRAMM_PER_CUBIC_METER,
4644
core::DataPoint{timeStamp, massConcentrationPm2p5});
4745

48-
measurements.emplace_back(mMetadata,
49-
core::SignalType::PM4P0_MICRO_GRAMM_PER_CUBIC_METER,
46+
measurements.emplace_back(
47+
mMetadata, core::SignalType::PM4P0_MICRO_GRAMM_PER_CUBIC_METER,
5048
core::DataPoint{timeStamp, massConcentrationPm4p0});
5149

52-
measurements.emplace_back(mMetadata,
53-
core::SignalType::PM10P0_MICRO_GRAMM_PER_CUBIC_METER,
50+
measurements.emplace_back(
51+
mMetadata, core::SignalType::PM10P0_MICRO_GRAMM_PER_CUBIC_METER,
5452
core::DataPoint{timeStamp, massConcentrationPm10p0});
5553

54+
// Versions 54, 55
55+
if (getDeviceType() == core::SEN54() or getDeviceType() == core::SEN55()) {
5656

57-
58-
// Verions 54, 55
59-
if (getDeviceType() == core::SEN54() or
60-
getDeviceType() == core::SEN55()) {
61-
62-
measurements.emplace_back(mMetadata,
63-
core::SignalType::RELATIVE_HUMIDITY_PERCENTAGE,
57+
measurements.emplace_back(
58+
mMetadata, core::SignalType::RELATIVE_HUMIDITY_PERCENTAGE,
6459
core::DataPoint{timeStamp, ambientHumidity});
6560

66-
measurements.emplace_back(mMetadata,
67-
core::SignalType::TEMPERATURE_DEGREES_CELSIUS,
61+
measurements.emplace_back(
62+
mMetadata, core::SignalType::TEMPERATURE_DEGREES_CELSIUS,
6863
core::DataPoint{timeStamp, ambientTemperature});
6964

70-
measurements.emplace_back(mMetadata,
71-
core::SignalType::VOC_INDEX,
72-
core::DataPoint{timeStamp, vocIndex});
73-
65+
measurements.emplace_back(mMetadata, core::SignalType::VOC_INDEX,
66+
core::DataPoint{timeStamp, vocIndex});
7467
}
7568
// Version 55
7669
if (getDeviceType() == core::SEN55()) {
7770

78-
measurements.emplace_back(mMetadata,
79-
core::SignalType::NOX_INDEX,
80-
core::DataPoint{timeStamp, noxIndex});
81-
71+
measurements.emplace_back(mMetadata, core::SignalType::NOX_INDEX,
72+
core::DataPoint{timeStamp, noxIndex});
8273
}
8374
return HighLevelError::NoError;
8475
}
@@ -97,14 +88,14 @@ uint16_t Sen5x::initializationStep() {
9788
}
9889

9990
// Get sensor unique ID (last 8 chars of serial no.)
100-
uint8_t serialNumberSize = 32;
91+
constexpr uint8_t serialNumberSize = 32;
10192
unsigned char serialNumber[serialNumberSize];
10293
error = mDriver.getSerialNumber(serialNumber, serialNumberSize);
10394
if (error) {
10495
return error;
10596
}
106-
size_t actualLen = strlen((const char*)serialNumber);
107-
size_t numBytesToCopy = min(8, (int)actualLen);
97+
size_t actualLen = strlen(reinterpret_cast<const char*>(serialNumber));
98+
size_t numBytesToCopy = min(8, static_cast<int>(actualLen));
10899
uint64_t sensorID = 0;
109100
for (int i = 0; i < numBytesToCopy - 1; i++) {
110101
sensorID |= (serialNumber[actualLen - numBytesToCopy - 1 + i]);
@@ -139,7 +130,7 @@ size_t Sen5x::getNumberOfDataPoints() const {
139130
{core::SEN55(), 8},
140131
};
141132
const auto iter = deviceToSignalCount.find(getDeviceType());
142-
if (iter == deviceToSignalCount.cend()){
133+
if (iter == deviceToSignalCount.cend()) {
143134
return 0;
144135
}
145136
return iter->second;
@@ -150,21 +141,25 @@ unsigned long Sen5x::getMinimumMeasurementIntervalMs() const {
150141
}
151142

152143
bool Sen5x::probe() {
153-
return _determineSensorVersion() == HighLevelError::NoError;
144+
// reset the device before probing to ensure a clean state
145+
mDriver.deviceReset();
146+
147+
return _determineSensorVersion() == NoError;
154148
}
155149

156150
void* Sen5x::getDriver() {
157-
return reinterpret_cast<void*>(&mDriver);
151+
return &mDriver;
158152
}
159153

160154
uint8_t Sen5x::getI2CAddress() const {
161155
return mAddress;
162156
};
163157

164158
uint16_t Sen5x::_determineSensorVersion() {
165-
uint8_t sensorNameSize = 32;
159+
constexpr uint8_t sensorNameSize = 32;
166160
unsigned char sensorNameStr[sensorNameSize];
167-
uint16_t error = mDriver.getProductName(sensorNameStr, sensorNameSize);
161+
const uint16_t error =
162+
mDriver.getProductName(sensorNameStr, sensorNameSize);
168163

169164
if (error) {
170165
return error;
@@ -183,4 +178,4 @@ uint16_t Sen5x::_determineSensorVersion() {
183178
}
184179
return 0;
185180
}
186-
} // namespace sensirion::upt::i2c_autodetect
181+
} // namespace sensirion::upt::i2c_autodetect

0 commit comments

Comments
 (0)