Commit 4a25616f authored by Melroy van den Berg's avatar Melroy van den Berg

refactor

parent 48a278cf
Pipeline #1071 passed with stages
in 23 seconds
......@@ -24,6 +24,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <exception>
#include <stdexcept>
#include <unistd.h>
#include <stdint.h>
#include <sys/ioctl.h>
......
......@@ -48,15 +48,26 @@ public:
void Loop();
private:
BME280 *bme;
MHZ19B *mhz19b;
PMSA003 *pmsa;
SGP30 *sgp;
int i2c_fd;
uint32_t absoluteHumidity; // Store temp. absolute humidity (used by gas sensor later on)
int OpenI2C();
bool DoGasMeasurement();
bool DoDustMeasurement();
bool DoCO2Measurement();
bool DoTempMeasurement();
void InitTempSensor(int i2c_fd);
void InitCO2Sensor();
void InitDustSensor();
void InitGasSensor(int i2c_fd);
void SetAbsoluteHumidity();
bool TempHumidPressReading();
bool CO2Reading();
bool DustReading();
bool GasReading();
};
#endif
\ No newline at end of file
......@@ -25,6 +25,8 @@
#include "timeout.h"
#include <stdio.h>
#include <exception>
#include <stdexcept>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
......
......@@ -36,8 +36,7 @@
BME280::BME280(int i2c_fd, bme280_settings *settings) {
this->i2c_fd = i2c_fd;
if(settings == NULL) {
printf("Error: Null pointer settings data, please provide settings [BME280]. Exit!\n");
exit(1);
throw std::invalid_argument("Null pointer settings data, please provide settings [BME280]");
}
this->chip_id = 0;
setSettings(settings);
......
......@@ -25,9 +25,18 @@
*/
Controller::Controller() {
this->absoluteHumidity = 0;
this->i2c_fd = OpenI2C();
try {
this->i2c_fd = OpenI2C();
// TODO: Init all other sensors as well in the constructor
InitTempSensor(this->i2c_fd);
InitCO2Sensor();
InitDustSensor();
InitGasSensor(this->i2c_fd);
}
catch(const std::exception &exc) {
std::cerr << "Init sensors failed, due to: " << exc.what() << std::endl;
throw;
}
}
/**
......@@ -49,11 +58,11 @@ void Controller::Loop() {
// Eg. INSERT air_quality,machine=412 temperature=21.5,humidity=65.3,pressure=1023.0,dust1=3,dust2.5=5,dust10=2,tvoc=2,co2=421
// TODO: Show live data to some display
//DoDustMeasurement();
DoCO2Measurement();
//DustReading();
CO2Reading();
DoTempMeasurement();
//DoGasMeasurement();
TempHumidPressReading();
GasReading();
}
/**
......@@ -71,67 +80,113 @@ int Controller::OpenI2C() {
return i2c_fd;
}
/**
* \brief Execute gas measurement using SGP30
* \return true if everything went successfully
*/
bool Controller::DoGasMeasurement() {
SGP30 sgp(this->i2c_fd);
void Controller::InitTempSensor(int i2c_fd) {
bme280_settings settings;
// Set indoor settings
settings.osr_h = BME280_OVERSAMPLING_1X;
settings.osr_p = BME280_OVERSAMPLING_16X;
settings.osr_t = BME280_OVERSAMPLING_2X;
settings.filter = BME280_FILTER_COEFF_16;
this->bme = new BME280(i2c_fd, &settings);
// The OSR settings (force mode, host in control so no standby settings needed)
uint8_t settings_sel = BME280_OSR_PRESS_SEL | BME280_OSR_TEMP_SEL | BME280_OSR_HUM_SEL | BME280_FILTER_SEL;
// Select sensor on the bus
if(!bme->Select()) {
throw std::runtime_error("Could not select the temp/humid/pressure sensor!\n");
}
if(!bme->Init()) {
throw std::runtime_error("BME280 init failed!\n");
}
if(!bme->SetSensorSettings(settings_sel)) {
throw std::runtime_error("Set sensor settings failed for BME280!\n");
}
// Trigger an actual reading to calculate absolute humidity, required for gas sensor (later on)
SetAbsoluteHumidity();
}
void Controller::InitCO2Sensor() {
this->mhz19b = new MHZ19B();
}
void Controller::InitDustSensor() {
this->pmsa = new PMSA003();
if(!pmsa->Init()) {
throw std::runtime_error("Init of PMSA003 failed!\n");
}
// Wait 30 secs from sleep mode, before stable
}
void Controller::InitGasSensor(int i2c_fd) {
this->sgp = new SGP30(i2c_fd);
// Select the sensor on the bus
if(!sgp.Select()) {
printf("Error: could not select the gas sensor!\n");
return false;
if(!sgp->Select()) {
throw std::runtime_error("Could not select the gas sensor!\n");
}
// Init the sensor
if(!sgp.Init()) {
printf("Error: Could not init the gas sensor!\n");
return false;
if(!sgp->Init()) {
throw std::runtime_error("Could not init the gas sensor!\n");
}
// Set humidity compensation value
sgp.SetHumidity(this->absoluteHumidity);
if(!sgp->SetHumidity(this->absoluteHumidity)) {
// TODO: Maybe a warning?
throw std::runtime_error("Could not set humidity compenstation value to the gas sensor!\n");
}
// TODO: first 15 seconds after init, returns fixed values (so should be ignored)
// Also: According to the specs we need to sent regular internals of 1s to ensure proper dynamic baseline compensation algo.
// This time interval needs to be done forever.
// TODO: first 20 seconds after init, returns fixed values (so should be ignored)
}
int counter = 0;
while(counter < 40) {
// Do measurement
if(!sgp.DoMeasurement()) {
printf("Error: Air quality measurement failed.");
return false;
}
void Controller::SetAbsoluteHumidity() {
// TODO: Select sensor on I2C bus?
printf("TVOC : %dppb\n", sgp.TVOC);
printf("eCO2 : %dppm\n", sgp.eCO2);
bme->SetSensorMode(BME280_FORCED_MODE);
// 1/60Hz = 60000 ms
// 25Hz = 40ms (use 45ms on the safe side)
usleep(45000);
// Sleep 1 second
// TODO: embedded a delay within DoMeasurement()?
usleep(1000000);
bme280_data data = bme->getAllSensorData();
// Absolute humidity in (mg/m3)
this->absoluteHumidity = static_cast<uint32_t>(1000.0f * WeatherEnvironment::GetAbsoluteHumidity(data.temperature, data.humidity));
}
/**
* \brief Execute temperature, rel. humidity & pressure measurement using BME280
* \return true if everything went successfully
*/
bool Controller::TempHumidPressReading() {
int counter = 0;
while(counter < 60) {
bme->SetSensorMode(BME280_FORCED_MODE);
// 1/60Hz = 60000 ms
// 25Hz = 40ms (use 45ms on the safe side)
usleep(45000);
bme280_data data = bme->getAllSensorData();
printf("%.2f °C\n", data.temperature);
printf("%.2f %%\n", data.humidity);
printf("%.2f hPa\n", data.pressure);
counter++;
}
return true;
}
/**
* \brief Execute fine dust measurement using PMSA003
* \brief Execute CO2 concentration measurement using MH-Z19B
* \return true if everything went successfully
*/
bool Controller::DoDustMeasurement() {
PMSA003 pmsa;
if(!pmsa.Init()) {
printf("Error: Init of PMSA003 failed!\n");
return false;
}
bool Controller::CO2Reading() {
int counter = 0;
while(counter < 10) {
if(pmsa.DoMeasurement()) {
printf("%.3f μ g/m3 PM1.0\n", pmsa.pm1p0);
printf("%.3f μ g/m3 PM2.5\n", pmsa.pm2p5);
printf("%.3f μ g/m3 PM10\n\n", pmsa.pm10);
if(mhz19b->DoMeasurement()) {
printf("%d ppm CO2\n", mhz19b->CO2);
}
// Sleep 1 second
// TODO: embedded a delay within DoMeasurement()?
usleep(1000000);
......@@ -141,19 +196,17 @@ bool Controller::DoDustMeasurement() {
}
/**
* \brief Execute CO2 concentration measurement using MH-Z19B
* \brief Execute fine dust measurement using PMSA003
* \return true if everything went successfully
*/
bool Controller::DoCO2Measurement() {
MHZ19B mhz19b;
bool Controller::DustReading() {
int counter = 0;
while(counter < 10) {
if(mhz19b.DoMeasurement()) {
printf("%d ppm CO2\n", mhz19b.CO2);
printf("%d degrees C\n\n", mhz19b.temperature);
if(pmsa->DoMeasurement()) {
printf("%.3f μ g/m3 PM1.0\n", pmsa->pm1p0);
printf("%.3f μ g/m3 PM2.5\n", pmsa->pm2p5);
printf("%.3f μ g/m3 PM10\n\n", pmsa->pm10);
}
// Sleep 1 second
// TODO: embedded a delay within DoMeasurement()?
usleep(1000000);
......@@ -163,52 +216,33 @@ bool Controller::DoCO2Measurement() {
}
/**
* \brief Execute temperature, rel. humidity & pressure measurement using BME280
* \brief Execute gas measurement using SGP30
* \return true if everything went successfully
*/
bool Controller::DoTempMeasurement() {
// The OSR settings (force mode, host in control so no standby settings needed)
uint8_t settings_sel = BME280_OSR_PRESS_SEL | BME280_OSR_TEMP_SEL | BME280_OSR_HUM_SEL | BME280_FILTER_SEL;
bme280_settings settings;
// Set indoor settings
settings.osr_h = BME280_OVERSAMPLING_1X;
settings.osr_p = BME280_OVERSAMPLING_16X;
settings.osr_t = BME280_OVERSAMPLING_2X;
settings.filter = BME280_FILTER_COEFF_16;
BME280 bme(this->i2c_fd, &settings);
// Select sensor on the bus
if(!bme.Select()) {
printf("Error: could not select the temp/humid/pressure sensor!\n");
return false;
}
if(!bme.Init()) {
printf("Error: BME280 init failed!\n");
return false;
}
if(!bme.SetSensorSettings(settings_sel)) {
printf("Error: Set sensor settings failed!\n");
return false;
}
bool Controller::GasReading() {
// IMPORTANT: According to the specs we need to sent regular internals of 1s to ensure proper dynamic baseline compensation algo.
// This time interval needs to be done forever.
int counter = 0;
while(counter < 60) {
bme.SetSensorMode(BME280_FORCED_MODE);
// 1/60Hz = 60000 ms
// 25Hz = 40ms (use 45ms on the safe side)
usleep(45000);
while(counter < 40) {
// Do measurement
if(!sgp->DoMeasurement()) {
printf("Error: Air quality measurement failed.");
return false;
}
bme280_data data = bme.getAllSensorData();
printf("%.2f °C\n", data.temperature);
printf("%.2f %%\n", data.humidity);
printf("%.2f hPa\n", data.pressure);
printf("TVOC : %dppb\n", sgp->TVOC);
printf("eCO2 : %dppm\n", sgp->eCO2);
// Absolute humidity in (mg/m3)
this->absoluteHumidity = static_cast<uint32_t>(1000.0f * WeatherEnvironment::GetAbsoluteHumidity(data.temperature, data.humidity));
// Sleep 1 second
// TODO: embedded a delay within DoMeasurement()?
usleep(1000000);
counter++;
}
return true;
}
......@@ -29,8 +29,7 @@ MHZ19B::MHZ19B() {
this->temperature = 0;
if(!Open()) {
printf("Error during creating connection to MH-Z19B.\n");
// TODO: Throw error
throw std::runtime_error("Error during creating connection to MH-Z19B");
}
}
......
......@@ -29,8 +29,7 @@ PMSA003::PMSA003() {
this->pm10 = 0.0f;
if(!Open()) {
printf("Error during creating connection to PMSA003.\n");
// TODO: Throw error
throw std::runtime_error("Error during creating connection to PMSA003");
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment