Skip to content

Commit

Permalink
added SPS30 via i2c support and some method refactors
Browse files Browse the repository at this point in the history
  • Loading branch information
hpsaturn committed May 26, 2021
1 parent d12d2d7 commit 658b90d
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 44 deletions.
119 changes: 82 additions & 37 deletions src/Sensors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@ void Sensors::init(int pms_type, int pms_rx, int pms_tx) {
#ifdef M5COREINK
Wire.begin(25,26); // M5CoreInk hat pines (header on top)
#endif
Wire.begin();

DEBUG("-->[SENSORS] try to load temp and humidity sensor..");
DEBUG("-->[SENSORS] try to load I2C sensor..");
sps30I2CInit();
am2320Init();
sht31Init();
bme280Init();
Expand Down Expand Up @@ -204,7 +206,7 @@ int Sensors::getPmDeviceTypeSelected() {
}

/******************************************************************************
* S E N S O R P R I V A T E M E T H O D S
* U A R T S E N S O R P R I V A T E M E T H O D S
******************************************************************************/

/**
Expand All @@ -220,11 +222,11 @@ bool Sensors::pmGenericRead() {
pm25 = txtMsg[6] * 256 + byte(txtMsg[7]);
pm10 = txtMsg[8] * 256 + byte(txtMsg[9]);
if (pm25 > 1000 && pm10 > 1000) {
onPmSensorError("-->[E][PMSENSOR] out of range pm25 > 1000");
onSensorError("-->[E][PMSENSOR] out of range pm25 > 1000");
} else
return true;
} else {
onPmSensorError("-->[E][PMSENSOR] invalid Generic sensor header!");
onSensorError("-->[E][PMSENSOR] invalid Generic sensor header!");
}
}
return false;
Expand All @@ -243,11 +245,11 @@ bool Sensors::pmPanasonicRead() {
pm25 = txtMsg[6] * 256 + byte(txtMsg[5]);
pm10 = txtMsg[10] * 256 + byte(txtMsg[9]);
if (pm25 > 2000 && pm10 > 2000) {
onPmSensorError("-->[E][PMSENSOR] out of range pm25 > 2000");
onSensorError("-->[E][PMSENSOR] out of range pm25 > 2000");
} else
return true;
} else {
onPmSensorError("-->[E][PMSENSOR] invalid Panasonic sensor header!");
onSensorError("-->[E][PMSENSOR] invalid Panasonic sensor header!");
}
return false;
}
Expand All @@ -265,11 +267,11 @@ bool Sensors::pmSDS011Read() {
pm25 = (txtMsg[3] * 256 + byte(txtMsg[2])) / 10;
pm10 = (txtMsg[5] * 256 + byte(txtMsg[4])) / 10;
if (pm25 > 1000 && pm10 > 1000) {
onPmSensorError("-->[E][PMSENSOR] out of range pm25 > 1000");
onSensorError("-->[E][PMSENSOR] out of range pm25 > 1000");
} else
return true;
} else {
onPmSensorError("-->[E][PMSENSOR] invalid Generic sensor header!");
onSensorError("-->[E][PMSENSOR] invalid Generic sensor header!");
}
}
return false;
Expand All @@ -291,7 +293,7 @@ String Sensors::hwSerialRead(unsigned int lenght_buffer) {
}
}
if (try_sensor_read > SENSOR_RETRY) {
onPmSensorError("-->[E][PMSENSOR] sensor read fail!");
onSensorError("-->[E][PMSENSOR] sensor read fail!");
}
return txtMsg;
}
Expand All @@ -300,7 +302,7 @@ String Sensors::hwSerialRead(unsigned int lenght_buffer) {
* @brief Sensirion SPS30 particulate meter sensor read.
* @return true if reads succes
*/
bool Sensors::pmSensirionRead() {
bool Sensors::sps30Read() {
uint8_t ret, error_cnt = 0;
delay(35); //Delay for sincronization
do {
Expand All @@ -312,7 +314,7 @@ bool Sensors::pmSensirionRead() {
}
delay(1000);
} else if (ret != ERR_OK) {
pmSensirionErrtoMess((char *)"-->[W][SPS30] Error during reading values: ", ret);
sps30ErrToMess((char *)"-->[W][SPS30] Error during reading values: ", ret);
return false;
}
} while (ret != ERR_OK);
Expand All @@ -325,7 +327,7 @@ bool Sensors::pmSensirionRead() {
pm10 = round(val.MassPM10);

if (pm25 > 1000 && pm10 > 1000) {
onPmSensorError("-->[E][SPS30] Sensirion out of range pm25 > 1000");
onSensorError("-->[E][SPS30] Sensirion out of range pm25 > 1000");
return false;
}

Expand Down Expand Up @@ -368,7 +370,7 @@ bool Sensors::pmSensorRead() {
break;

case Sensirion:
return pmSensirionRead();
return sps30Read();
break;

case SDS011:
Expand All @@ -389,6 +391,10 @@ bool Sensors::pmSensorRead() {
}
}

/******************************************************************************
* I 2 C S E N S O R R E A D M E T H O D S
******************************************************************************/

void Sensors::am2320Read() {
float humi1 = am2320.readHumidity();
float temp1 = am2320.readTemperature();
Expand Down Expand Up @@ -490,20 +496,20 @@ void Sensors::dhtRead() {
}
}

void Sensors::onPmSensorError(const char *msg) {
void Sensors::onSensorError(const char *msg) {
DEBUG(msg);
if (_onErrorCb) _onErrorCb(msg);
}

void Sensors::pmSensirionErrtoMess(char *mess, uint8_t r) {
void Sensors::sps30ErrToMess(char *mess, uint8_t r) {
char buf[80];
sps30.GetErrDescription(r, buf, 80);
DEBUG("-->[E][SENSIRION]", buf);
}

void Sensors::pmSensirionErrorloop(char *mess, uint8_t r) {
void Sensors::sps30Errorloop(char *mess, uint8_t r) {
if (r)
pmSensirionErrtoMess(mess, r);
sps30ErrToMess(mess, r);
else
DEBUG(mess);
}
Expand Down Expand Up @@ -566,7 +572,7 @@ bool Sensors::pmSensorAutoDetect(int pms_type) {
delay(1000); // sync serial

if (pms_type == Sensirion) {
if (pmSensirionInit()) {
if (sps30UARTInit()) {
device_selected = "SENSIRION";
device_type = Sensirion;
return true;
Expand Down Expand Up @@ -673,43 +679,89 @@ bool Sensors::CO2CM1106Init() {
return true;
}

bool Sensors::pmSensirionInit() {
bool Sensors::sps30UARTInit() {
// Begin communication channel
DEBUG("-->[SPS30] starting SPS30 sensor..");
if (!devmode) sps30.EnableDebugging(0);
DEBUG("-->[SPS30] starting SPS30 (UART) sensor..");

// set driver debug level
sps30.EnableDebugging(devmode);
// Begin communication channel;
if (!sps30.begin(SENSOR_COMMS)) {
pmSensirionErrorloop((char *)"-->[E][SPS30] could not initialize communication channel.", 0);
sps30Errorloop((char *)"-->[E][SPS30] could not initialize communication channel.", 0);
return false;
}
// check for SPS30 connection
if (!sps30.probe())
pmSensirionErrorloop((char *)"-->[E][SPS30] could not probe / connect with SPS30.", 0);
if (!sps30.probe()) {
sps30Errorloop((char *)"-->[E][SPS30] could not probe with SPS30.", 0);
return false;
}
else {
DEBUG("-->[SPS30] Detected SPS30.");
pmSensirionDeviceInfo();
DEBUG("-->[SPS30] Detected SPS30 via UART.");
sps30DeviceInfo();
}
// reset SPS30 connection
if (!sps30.reset())
pmSensirionErrorloop((char *)"-->[E][SPS30] could not reset.", 0);
sps30Errorloop((char *)"-->[E][SPS30] could not reset.", 0);

// start measurement
if (sps30.start() == true) {
DEBUG("-->[SPS30] Measurement OK");
return true;
} else
pmSensirionErrorloop((char *)"-->[E][SPS30] Could NOT start measurement", 0);
sps30Errorloop((char *)"-->[E][SPS30] Could NOT start measurement", 0);

return false;
}

bool Sensors::sps30I2CInit() {
if (device_type == Sensirion) return false;

DEBUG("-->[SPS30] starting SPS30 (I2C) sensor..");

// set driver debug level
sps30.EnableDebugging(devmode);
// Begin communication channel;
if (sps30.begin(&Wire) == false) {
sps30Errorloop((char *)"-->[E][SPS30] Could not set I2C communication channel.", 0);
return false;
}

// check for SPS30 connection
if (!sps30.probe()) {
sps30Errorloop((char *)"-->[E][SPS30] Could not probe with SPS30.", 0);
return false;
}
else {
DEBUG("-->[SPS30] Detected SPS30 via I2C.");
sps30DeviceInfo();
}

// reset SPS30 connection
if (!sps30.reset())
sps30Errorloop((char *)"-->[E][SPS30] could not reset.", 0);


if (SENSOR_COMMS == I2C_COMMS) {
// start measurement
if (sps30.start()) {
delay(100);
sps30Read();
DEBUG("-->[SPS30] Measurement OK");
device_selected = "SENSIRION";
device_type = Sensirion;
if (sps30.I2C_expect() == 4)
DEBUG("-->[E][SPS30] Due to I2C buffersize only PM values \n");
return true;
}
else
sps30Errorloop((char *)"-->[E][SPS30] Could NOT start measurement.", 0);

return false;
}

/**
* @brief : read and display Sensirion device info
*/
void Sensors::pmSensirionDeviceInfo() {
void Sensors::sps30DeviceInfo() {
char buf[32];
uint8_t ret;
SPS30_version v;
Expand Down Expand Up @@ -773,13 +825,6 @@ void Sensors::bme280Init() {
void Sensors::bme680Init() {
DEBUG("-->[BME280] starting BME680 sensor..");
if (!bme680.begin()) return;

// Set up oversampling and filter in// There's no need to delay() until millis() >= endTime: bme.endReading()
// takes care of that. It's okay for parallel work to take longer than
// BME680's measurement time.

// Obtain measurement results from BME680. Note that this operation isn't
// instantaneous even if milli() >= endTime due to I2C/SPI latency.itialization
bme680.setTemperatureOversampling(BME680_OS_8X);
bme680.setHumidityOversampling(BME680_OS_2X);
bme680.setPressureOversampling(BME680_OS_4X);
Expand Down
15 changes: 8 additions & 7 deletions src/Sensors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,13 +215,14 @@ class Sensors {
bool CO2Mhz19Init();
bool CO2CM1106Init();

bool pmSensirionInit();
bool pmSensirionRead();
void pmSensirionErrtoMess(char *mess, uint8_t r);
void pmSensirionErrorloop(char *mess, uint8_t r);
void pmSensirionDeviceInfo();

void onPmSensorError(const char *msg);
bool sps30I2CInit();
bool sps30UARTInit();
bool sps30Read();
void sps30ErrToMess(char *mess, uint8_t r);
void sps30Errorloop(char *mess, uint8_t r);
void sps30DeviceInfo();

void onSensorError(const char *msg);

bool serialInit(int pms_type, long speed_baud, int pms_rx, int pms_tx);
String hwSerialRead(unsigned int lenght_buffer);
Expand Down

0 comments on commit 658b90d

Please sign in to comment.