Skip to content

Commit eaba184

Browse files
author
Your Name
committed
Add error handling
1 parent 97ac18d commit eaba184

File tree

2 files changed

+45
-23
lines changed

2 files changed

+45
-23
lines changed

src/SparkFun_SCD30_Arduino_Library.cpp

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -107,41 +107,46 @@ float SCD30::getTemperature(void)
107107
}
108108

109109
//Enables or disables the ASC
110-
void SCD30::setAutoSelfCalibration(boolean enable)
110+
bool SCD30::setAutoSelfCalibration(boolean enable)
111111
{
112112
if (enable)
113-
sendCommand(COMMAND_AUTOMATIC_SELF_CALIBRATION, 1); //Activate continuous ASC
113+
return sendCommand(COMMAND_AUTOMATIC_SELF_CALIBRATION, 1); //Activate continuous ASC
114114
else
115-
sendCommand(COMMAND_AUTOMATIC_SELF_CALIBRATION, 0); //Deactivate continuous ASC
115+
return sendCommand(COMMAND_AUTOMATIC_SELF_CALIBRATION, 0); //Deactivate continuous ASC
116116
}
117117

118118
//Set the forced recalibration factor. See 1.3.7.
119119
//The reference CO2 concentration has to be within the range 400 ppm ≤ cref(CO2) ≤ 2000 ppm.
120-
void SCD30::setForcedRecalibrationFactor(uint16_t concentration)
120+
bool SCD30::setForcedRecalibrationFactor(uint16_t concentration)
121121
{
122-
if(concentration < 400 || concentration > 2000) return; //Error check.
123-
sendCommand(COMMAND_SET_FORCED_RECALIBRATION_FACTOR, concentration);
122+
if(concentration < 400 || concentration > 2000) {
123+
return false; //Error check.
124+
}
125+
return sendCommand(COMMAND_SET_FORCED_RECALIBRATION_FACTOR, concentration);
124126
}
125127

126128
//Set the temperature offset. See 1.3.8.
127-
void SCD30::setTemperatureOffset(float tempOffset)
129+
bool SCD30::setTemperatureOffset(float tempOffset)
128130
{
129131
int16_t tickOffset = tempOffset * 100;
130-
sendCommand(COMMAND_SET_TEMPERATURE_OFFSET, tickOffset);
132+
return sendCommand(COMMAND_SET_TEMPERATURE_OFFSET, tickOffset);
131133
}
132134

133135
//Set the altitude compenstation. See 1.3.9.
134-
void SCD30::setAltitudeCompensation(uint16_t altitude)
136+
bool SCD30::setAltitudeCompensation(uint16_t altitude)
135137
{
136-
sendCommand(COMMAND_SET_ALTITUDE_COMPENSATION, altitude);
138+
return sendCommand(COMMAND_SET_ALTITUDE_COMPENSATION, altitude);
137139
}
138140

139141
//Set the pressure compenstation. This is passed during measurement startup.
140142
//mbar can be 700 to 1200
141-
void SCD30::setAmbientPressure(uint16_t pressure_mbar)
143+
bool SCD30::setAmbientPressure(uint16_t pressure_mbar)
142144
{
143-
if(pressure_mbar < 700 || pressure_mbar > 1200) pressure_mbar = 0; //Error check
144-
sendCommand(COMMAND_CONTINUOUS_MEASUREMENT, pressure_mbar);
145+
if(pressure_mbar < 700 || pressure_mbar > 1200)
146+
{
147+
return false;
148+
}
149+
return sendCommand(COMMAND_CONTINUOUS_MEASUREMENT, pressure_mbar);
145150
}
146151

147152
//Begins continuous measurements
@@ -162,9 +167,9 @@ boolean SCD30::beginMeasuring(void)
162167

163168
//Sets interval between measurements
164169
//2 seconds to 1800 seconds (30 minutes)
165-
void SCD30::setMeasurementInterval(uint16_t interval)
170+
bool SCD30::setMeasurementInterval(uint16_t interval)
166171
{
167-
sendCommand(COMMAND_SET_MEASUREMENT_INTERVAL, interval);
172+
return sendCommand(COMMAND_SET_MEASUREMENT_INTERVAL, interval);
168173
}
169174

170175
//Returns true when data is available
@@ -195,9 +200,11 @@ boolean SCD30::readMeasurement()
195200
if (_i2cPort->endTransmission() != 0)
196201
return (0); //Sensor did not ACK
197202

198-
_i2cPort->requestFrom((uint8_t)SCD30_ADDRESS, (uint8_t)18);
203+
const uint8_t receivedBytes = _i2cPort->requestFrom((uint8_t)SCD30_ADDRESS, (uint8_t)18);
204+
bool error = false;
199205
if (_i2cPort->available())
200206
{
207+
byte bytesToCrc[2];
201208
for (byte x = 0 ; x < 18 ; x++)
202209
{
203210
byte incoming = _i2cPort->read();
@@ -210,28 +217,43 @@ boolean SCD30::readMeasurement()
210217
case 4:
211218
tempCO2 <<= 8;
212219
tempCO2 |= incoming;
220+
bytesToCrc[x%3] = incoming;
213221
break;
214222
case 6:
215223
case 7:
216224
case 9:
217225
case 10:
218226
tempTemperature <<= 8;
219227
tempTemperature |= incoming;
228+
bytesToCrc[x%3] = incoming;
220229
break;
221230
case 12:
222231
case 13:
223232
case 15:
224233
case 16:
225234
tempHumidity <<= 8;
226235
tempHumidity |= incoming;
236+
bytesToCrc[x%3] = incoming;
227237
break;
228238
default:
229-
//Do nothing with the CRC bytes
239+
//Validate CRC
240+
const uint8_t foundCrc = computeCRC8(bytesToCrc, 2);
241+
if (foundCrc != incoming) {
242+
Serial.printf("Found CRC in byte %u, expected %u, got %u\n", x, incoming, foundCrc);
243+
error = true;
244+
}
230245
break;
231246
}
232247
}
248+
} else {
249+
Serial.printf("No SCD30 data found from I2C, i2c claims we should receive %u bytes\n", receivedBytes);
250+
return false;
233251
}
234252

253+
if (error) {
254+
Serial.println("Encountered error reading SCD30 data.");
255+
return false;
256+
}
235257
//Now copy the uint32s into their associated floats
236258
memcpy(&co2, &tempCO2, sizeof(co2));
237259
memcpy(&temperature, &tempTemperature, sizeof(temperature));

src/SparkFun_SCD30_Arduino_Library.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@ class SCD30
5959
float getHumidity(void);
6060
float getTemperature(void);
6161

62-
void setMeasurementInterval(uint16_t interval);
63-
void setAmbientPressure(uint16_t pressure_mbar);
64-
void setAltitudeCompensation(uint16_t altitude);
65-
void setAutoSelfCalibration(boolean enable);
66-
void setForcedRecalibrationFactor(uint16_t concentration);
67-
void setTemperatureOffset(float tempOffset);
62+
bool setMeasurementInterval(uint16_t interval);
63+
bool setAmbientPressure(uint16_t pressure_mbar);
64+
bool setAltitudeCompensation(uint16_t altitude);
65+
bool setAutoSelfCalibration(boolean enable);
66+
bool setForcedRecalibrationFactor(uint16_t concentration);
67+
bool setTemperatureOffset(float tempOffset);
6868

6969
boolean dataAvailable();
7070
boolean readMeasurement();

0 commit comments

Comments
 (0)