Skip to content

Commit 466dd76

Browse files
authored
Merge pull request #27 from Sensirion/probing
Introduce probing on detection
2 parents b1e1b84 + e9d5450 commit 466dd76

24 files changed

+236
-123
lines changed

src/I2CAutoDetector.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class I2CAutoDetector : public IAutoDetector {
2020

2121

2222
explicit I2CAutoDetector(TwoWire& wire):
23-
_wire(wire),
23+
mWire(wire),
2424
mDetectionTable{createMappingInstance<SensorMappingT>(wire)...}{};
2525

2626
virtual ~I2CAutoDetector() {
@@ -44,13 +44,18 @@ class I2CAutoDetector : public IAutoDetector {
4444
* @param sensorList SensorList to which add the found sensors
4545
*/
4646
virtual void findSensors(SensorList& sensorList) override {
47-
for (auto tableEntry:mDetectionTable){
48-
_wire.beginTransmission(tableEntry->getI2cAddress());
49-
const byte error = _wire.endTransmission();
47+
for (auto tableEntry:mDetectionTable){
48+
if (sensorList.containsSensor(tableEntry->getI2cAddress())) continue;
49+
50+
mWire.beginTransmission(tableEntry->getI2cAddress());
51+
const byte error = mWire.endTransmission();
5052
if (error){
5153
continue;
5254
}
53-
sensorList.addSensor(&tableEntry->getSensor());
55+
tableEntry->getSensor().start();
56+
if (!tableEntry->getSensor().probe()) continue;
57+
58+
sensorList.addSensorIfNotPresent(&tableEntry->getSensor());
5459
}
5560
}
5661

@@ -59,7 +64,7 @@ class I2CAutoDetector : public IAutoDetector {
5964
using DetectableSensorsT = std::array<ISensorToAddressMapping*,
6065
sizeof...(SensorMappingT)>;
6166

62-
TwoWire& _wire;
67+
TwoWire& mWire;
6368
DetectableSensorsT mDetectionTable;
6469

6570

src/ISensor.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ class ISensor {
5050
*/
5151
virtual size_t getNumberOfDataPoints() const = 0;
5252

53+
/**
54+
* @brief Get the I2C address used by this sensor
55+
*
56+
* @return uint8_t the I2C address
57+
*/
58+
virtual uint8_t getI2CAddress() const = 0;
59+
5360
/**
5461
* @brief Call driver methods to perform measurement and update DataPoints
5562
*
@@ -118,6 +125,15 @@ class ISensor {
118125
* @return void*
119126
*/
120127
virtual void* getDriver() = 0;
128+
129+
/**
130+
* @brief Probe the sensor to ensure the right sensor is detected
131+
*
132+
* @return true if sensor is responding properly, false otherwise.
133+
*/
134+
virtual bool probe() {
135+
return true;
136+
}
121137
};
122138
} // namespace sensirion::upt::i2c_autodetect
123139

src/SensorList.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,23 @@ constexpr auto TAG = "SensorList";
99

1010
SensorList::~SensorList() {}
1111

12-
void SensorList::addSensor(ISensor* pSensor) {
13-
auto found = std::find_if(mSensorCollection.begin(),
14-
mSensorCollection.end(), [pSensor](SensorStateMachine* x) {
15-
return x->getSensor()->getDeviceType() == pSensor->getDeviceType();
16-
});
17-
if (found == mSensorCollection.end()){
12+
13+
void SensorList::addSensorIfNotPresent(ISensor* pSensor) {
14+
if (!containsSensor(pSensor->getDeviceType())){
1815
mSensorCollection.push_back(new SensorStateMachine(pSensor));
1916
}
2017
}
2118

2219

20+
bool SensorList::containsSensor(uint8_t address) const{
21+
auto iter = std::find_if(mSensorCollection.begin(),
22+
mSensorCollection.end(), [address](SensorStateMachine* s) {
23+
return s->getSensor()->getI2CAddress() == address;
24+
});
25+
return iter != mSensorCollection.end();
26+
}
27+
28+
2329
size_t SensorList::getTotalNumberOfDataPoints() const {
2430
size_t totalNumberOfDataPoints = 0;
2531
for (auto s : mSensorCollection) {
@@ -56,12 +62,19 @@ bool SensorList::containsSensor(core::DeviceType deviceType) const {
5662

5763
void SensorList::removeLostSensors() {
5864
std::vector<SensorStateMachine*> livingSensors{};
65+
std::vector<SensorStateMachine*> lostSensors{};
5966
for (auto s: mSensorCollection){
6067
if(s->getSensorState() != SensorStatus::LOST){
6168
livingSensors.push_back(s);
6269
}
70+
else{
71+
lostSensors.push_back(s);
72+
}
6373
}
6474
mSensorCollection.clear();
6575
mSensorCollection = livingSensors;
76+
for (auto s: lostSensors){
77+
delete s;
78+
}
6679
}
6780
} // namespace sensirion::upt::i2c_autodetect

src/SensorList.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,17 @@ class SensorList {
3131
*
3232
* @param[in] pSensor pointer to the sensor to be added to the list
3333
*/
34-
void addSensor(ISensor* pSensor);
34+
void addSensorIfNotPresent(ISensor* pSensor);
35+
36+
/**
37+
* @brief check if the given I2C address is already used by a sensor in
38+
* the list
39+
*
40+
* @param[in] address to be checked for in the list
41+
*
42+
* @returns True if the address is found, false otherwise.
43+
*/
44+
bool containsSensor(uint8_t address) const;
3545

3646
/**
3747
* @brief Counts sensors contained in the list

src/SensorWrappers/Scd30.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@
55
namespace sensirion::upt::i2c_autodetect{
66

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

1010
uint16_t Scd30::start() {
11-
_driver.begin(_wire, _address);
11+
mDriver.begin(mWire, mAddress);
1212
return 0;
1313
}
1414

1515
uint16_t Scd30::measureAndWrite(MeasurementList& measurements,
1616
const unsigned long timeStamp) {
1717
// Check data ready
1818
uint16_t dataReadyFlag = 0;
19-
uint16_t error = _driver.getDataReady(dataReadyFlag);
19+
uint16_t error = mDriver.getDataReady(dataReadyFlag);
2020
if (error) {
2121
return error;
2222
}
@@ -29,20 +29,20 @@ uint16_t Scd30::measureAndWrite(MeasurementList& measurements,
2929
float temperature;
3030
float humidity;
3131
error =
32-
_driver.readMeasurementData(co2Concentration, temperature, humidity);
32+
mDriver.readMeasurementData(co2Concentration, temperature, humidity);
3333
if (error) {
3434
return error;
3535
}
3636

37-
measurements.emplace_back(_metaData,
37+
measurements.emplace_back(mMetadata,
3838
core::SignalType::CO2_PARTS_PER_MILLION,
3939
core::DataPoint{timeStamp, co2Concentration});
4040

41-
measurements.emplace_back(_metaData,
41+
measurements.emplace_back(mMetadata,
4242
core::SignalType::TEMPERATURE_DEGREES_CELSIUS,
4343
core::DataPoint{timeStamp, temperature});
4444

45-
measurements.emplace_back(_metaData,
45+
measurements.emplace_back(mMetadata,
4646
core::SignalType::RELATIVE_HUMIDITY_PERCENTAGE,
4747
core::DataPoint{timeStamp, humidity});
4848

@@ -53,7 +53,7 @@ uint16_t Scd30::measureAndWrite(MeasurementList& measurements,
5353
* call of this function as it then is not required to enter a wait loop
5454
* (see SensirionI2cScd30::blockingReadMeasurementData()). This procedure is
5555
* only required for SCD30. */
56-
error = _driver.getDataReady(dataReadyFlag);
56+
error = mDriver.getDataReady(dataReadyFlag);
5757
if (error) {
5858
return error;
5959
}
@@ -62,9 +62,9 @@ uint16_t Scd30::measureAndWrite(MeasurementList& measurements,
6262

6363
uint16_t Scd30::initializationStep() {
6464
// stop potentially previously started measurement
65-
_driver.stopPeriodicMeasurement();
65+
mDriver.stopPeriodicMeasurement();
6666
// Start Measurement
67-
uint16_t error = _driver.startPeriodicMeasurement(0);
67+
uint16_t error = mDriver.startPeriodicMeasurement(0);
6868
if (error) {
6969
return error;
7070
}
@@ -74,32 +74,36 @@ uint16_t Scd30::initializationStep() {
7474
for (size_t i = 0; i < 64; i++) {
7575
sensorID |= (random(2) << i);
7676
}
77-
_metaData.deviceID = sensorID;
77+
mMetadata.deviceID = sensorID;
7878

7979
/* See explanatory comment for measureAndWrite() */
8080
uint16_t dataReadyFlag;
81-
error = _driver.getDataReady(dataReadyFlag);
81+
error = mDriver.getDataReady(dataReadyFlag);
8282
return error;
8383
}
8484

8585
core::DeviceType Scd30::getDeviceType() const {
86-
return _metaData.deviceType;
86+
return mMetadata.deviceType;
8787
;
8888
}
8989

9090
core::MetaData Scd30::getMetaData() const {
91-
return _metaData;
91+
return mMetadata;
9292
}
9393

9494
size_t Scd30::getNumberOfDataPoints() const {
9595
return 3;
9696
}
9797

98+
uint8_t Scd30::getI2CAddress() const {
99+
return mAddress;
100+
};
101+
98102
unsigned long Scd30::getMinimumMeasurementIntervalMs() const {
99103
return 2000;
100104
}
101105

102106
void* Scd30::getDriver() {
103-
return reinterpret_cast<void*>(&_driver);
107+
return reinterpret_cast<void*>(&mDriver);
104108
}
105109
} // namespace sensirion::upt::i2c_autodetect

src/SensorWrappers/Scd30.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,16 @@ class Scd30 : public ISensor {
1616
uint16_t initializationStep() override;
1717
DeviceType getDeviceType() const override;
1818
core::MetaData getMetaData() const override;
19+
uint8_t getI2CAddress() const override;
1920
size_t getNumberOfDataPoints() const override;
2021
unsigned long getMinimumMeasurementIntervalMs() const override;
2122
void* getDriver() override;
2223

2324
private:
24-
TwoWire& _wire;
25-
uint16_t _address;
26-
SensirionI2cScd30 _driver;
27-
core::MetaData _metaData;
25+
TwoWire& mWire;
26+
uint16_t mAddress;
27+
SensirionI2cScd30 mDriver;
28+
core::MetaData mMetadata;
2829
};
2930
} // namespace sensirion::upt::i2c_autodetect
3031

src/SensorWrappers/Scd4x.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ core::MetaData Scd4x::getMetaData() const {
6767
return mMetadata;
6868
}
6969

70+
uint8_t Scd4x::getI2CAddress() const {
71+
return mAddress;
72+
};
73+
7074
size_t Scd4x::getNumberOfDataPoints() const {
7175
return 3;
7276
}

src/SensorWrappers/Scd4x.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class Scd4x : public ISensor {
1717
DeviceType getDeviceType() const override;
1818
core::MetaData getMetaData() const override;
1919
size_t getNumberOfDataPoints() const override;
20+
uint8_t getI2CAddress() const override;
2021
unsigned long getMinimumMeasurementIntervalMs() const override;
2122
// Same as measurement interval
2223
unsigned long getInitializationIntervalMs() const override;

0 commit comments

Comments
 (0)