Skip to content
Snippets Groups Projects
Commit 738d4e6e authored by user2684's avatar user2684
Browse files

Add forecast output to BME280 #56

parent 0772fc5f
Branches
Tags
No related merge requests found
...@@ -1174,7 +1174,7 @@ void SensorMLX90614::onReceive(const MyMessage & message) { ...@@ -1174,7 +1174,7 @@ void SensorMLX90614::onReceive(const MyMessage & message) {
#if MODULE_BME280 == 1 #if MODULE_BME280 == 1
// contructor // contructor
SensorBME280::SensorBME280(int child_id, Adafruit_BME280* bme, int sensor_type): Sensor(child_id,A4) { SensorBME280::SensorBME280(int child_id, Adafruit_BME280* bme, int sensor_type): Sensor(child_id,A4) {
// store the sensor type (0: temperature, 1: humidity, 2: pressure) // sensor type (0: temperature, 1: humidity, 2: pressure, 3: forecast)
_sensor_type = sensor_type; _sensor_type = sensor_type;
if (_sensor_type == 0) { if (_sensor_type == 0) {
// temperature sensor // temperature sensor
...@@ -1194,10 +1194,23 @@ SensorBME280::SensorBME280(int child_id, Adafruit_BME280* bme, int sensor_type): ...@@ -1194,10 +1194,23 @@ SensorBME280::SensorBME280(int child_id, Adafruit_BME280* bme, int sensor_type):
setType(V_PRESSURE); setType(V_PRESSURE);
setValueType(TYPE_FLOAT); setValueType(TYPE_FLOAT);
} }
else if (_sensor_type == 3) {
// pressure sensor
setPresentation(S_BARO);
setType(V_FORECAST);
setValueType(TYPE_STRING);
}
}
// setter/getter
void SensorBME280::setForecastSamplesCount(int value) {
_forecast_samples_count = value;
} }
// what do to during before // what do to during before
void SensorBME280::onBefore() { void SensorBME280::onBefore() {
// initialize the forecast samples array
_forecast_samples = new float[_forecast_samples_count];
} }
// what do to during setup // what do to during setup
...@@ -1237,7 +1250,7 @@ void SensorBME280::onLoop() { ...@@ -1237,7 +1250,7 @@ void SensorBME280::onLoop() {
} }
// Pressure Sensor // Pressure Sensor
else if (_sensor_type == 2) { else if (_sensor_type == 2) {
// read humidity // read pressure
float pressure = _bme->readPressure() / 100.0F; float pressure = _bme->readPressure() / 100.0F;
if (isnan(pressure)) return; if (isnan(pressure)) return;
#if DEBUG == 1 #if DEBUG == 1
...@@ -1249,12 +1262,98 @@ void SensorBME280::onLoop() { ...@@ -1249,12 +1262,98 @@ void SensorBME280::onLoop() {
// store the value // store the value
if (! isnan(pressure)) _value_float = pressure; if (! isnan(pressure)) _value_float = pressure;
} }
// Forecast Sensor
else if (_sensor_type == 3) {
// read pressure
float pressure = _bme->readPressure() / 100.0F;
if (isnan(pressure)) return;
// Calculate the average of the last n minutes.
int index = _minute_count % _forecast_samples_count;
_forecast_samples[index] = pressure;
_minute_count++;
if (_minute_count > 185) _minute_count = 6;
if (_minute_count == 5) _pressure_avg = _getLastPressureSamplesAverage();
else if (_minute_count == 35) {
float last_pressure_avg = _getLastPressureSamplesAverage();
float change = (last_pressure_avg - _pressure_avg) * 0.1;
// first time initial 3 hour
if (_first_round) _dP_dt = change * 2; // note this is for t = 0.5hour
else _dP_dt = change / 1.5; // divide by 1.5 as this is the difference in time from 0 value.
}
else if (_minute_count == 65) {
float last_pressure_avg = _getLastPressureSamplesAverage();
float change = (last_pressure_avg - _pressure_avg) * 0.1;
//first time initial 3 hour
if (_first_round) _dP_dt = change; //note this is for t = 1 hour
else _dP_dt = change / 2; //divide by 2 as this is the difference in time from 0 value
}
else if (_minute_count == 95) {
float last_pressure_avg = _getLastPressureSamplesAverage();
float change = (last_pressure_avg - _pressure_avg) * 0.1;
// first time initial 3 hour
if (_first_round)_dP_dt = change / 1.5; // note this is for t = 1.5 hour
else _dP_dt = change / 2.5; // divide by 2.5 as this is the difference in time from 0 value
}
else if (_minute_count == 125) {
float last_pressure_avg = _getLastPressureSamplesAverage();
// store for later use.
_pressure_avg2 = last_pressure_avg;
float change = (last_pressure_avg - _pressure_avg) * 0.1;
if (_first_round) _dP_dt = change / 2; // note this is for t = 2 hour
else _dP_dt = change / 3; // divide by 3 as this is the difference in time from 0 value
}
else if (_minute_count == 155) {
float last_pressure_avg = _getLastPressureSamplesAverage();
float change = (last_pressure_avg - _pressure_avg) * 0.1;
if (_first_round) _dP_dt = change / 2.5; // note this is for t = 2.5 hour
else _dP_dt = change / 3.5; // divide by 3.5 as this is the difference in time from 0 value
}
else if (_minute_count == 185) {
float last_pressure_avg = _getLastPressureSamplesAverage();
float change = (last_pressure_avg - _pressure_avg) * 0.1;
if (_first_round) _dP_dt = change / 3; // note this is for t = 3 hour
else _dP_dt = change / 4; // divide by 4 as this is the difference in time from 0 value
}
// Equating the pressure at 0 to the pressure at 2 hour after 3 hours have past.
_pressure_avg = _pressure_avg2;
// flag to let you know that this is on the past 3 hour mark. Initialized to 0 outside main loop.
_first_round = false;
// calculate the forecast (STABLE = 0, SUNNY = 1, CLOUDY = 2, UNSTABLE = 3, THUNDERSTORM = 4, UNKNOWN = 5)
int forecast = 5;
//if time is less than 35 min on the first 3 hour interval.
if (_minute_count < 35 && _first_round) forecast = 5;
else if (_dP_dt < (-0.25)) forecast = 5;
else if (_dP_dt > 0.25) forecast = 4;
else if ((_dP_dt > (-0.25)) && (_dP_dt < (-0.05))) forecast = 2;
else if ((_dP_dt > 0.05) && (_dP_dt < 0.25)) forecast = 1;
else if ((_dP_dt >(-0.05)) && (_dP_dt < 0.05)) forecast = 0;
else forecast = 5;
_value_string = _weather[forecast];
#if DEBUG == 1
Serial.print(F("BME I="));
Serial.print(_child_id);
Serial.print(F(" M="));
Serial.print(_minute_count);
Serial.print(F(" dP="));
Serial.print(_dP_dt);
Serial.print(F(" F="));
Serial.println(_value_string);
#endif
}
} }
// what do to as the main task when receiving a message // what do to as the main task when receiving a message
void SensorBME280::onReceive(const MyMessage & message) { void SensorBME280::onReceive(const MyMessage & message) {
onLoop(); onLoop();
} }
// returns the average of the latest pressure samples
float SensorBME280::_getLastPressureSamplesAverage() {
float avg = 0;
for (int i = 0; i < _forecast_samples_count; i++) avg += _forecast_samples[i];
avg /= _forecast_samples_count;
return avg;
}
#endif #endif
...@@ -1371,19 +1470,25 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) { ...@@ -1371,19 +1470,25 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) {
else if (sensor_type == SENSOR_DHT11 || sensor_type == SENSOR_DHT22) { else if (sensor_type == SENSOR_DHT11 || sensor_type == SENSOR_DHT22) {
int dht_type = sensor_type == SENSOR_DHT11 ? DHT11 : DHT22; int dht_type = sensor_type == SENSOR_DHT11 ? DHT11 : DHT22;
DHT* dht = new DHT(pin,dht_type); DHT* dht = new DHT(pin,dht_type);
// register temperature sensor
registerSensor(new SensorDHT(child_id,pin,dht,0,dht_type)); registerSensor(new SensorDHT(child_id,pin,dht,0,dht_type));
// register humidity sensor
child_id = _getAvailableChildId(); child_id = _getAvailableChildId();
return registerSensor(new SensorDHT(child_id,pin,dht,1,dht_type)); return registerSensor(new SensorDHT(child_id,pin,dht,1,dht_type));
} }
#endif #endif
#if MODULE_SHT21 == 1 #if MODULE_SHT21 == 1
else if (sensor_type == SENSOR_SHT21) { else if (sensor_type == SENSOR_SHT21) {
// register temperature sensor
registerSensor(new SensorSHT21(child_id,0)); registerSensor(new SensorSHT21(child_id,0));
// register humidity sensor
child_id = _getAvailableChildId(); child_id = _getAvailableChildId();
return registerSensor(new SensorSHT21(child_id,1)); return registerSensor(new SensorSHT21(child_id,1));
} }
else if (sensor_type == SENSOR_HTU21D) { else if (sensor_type == SENSOR_HTU21D) {
// register temperature sensor
registerSensor(new SensorHTU21D(child_id,0)); registerSensor(new SensorHTU21D(child_id,0));
// register humidity sensor
child_id = _getAvailableChildId(); child_id = _getAvailableChildId();
return registerSensor(new SensorHTU21D(child_id,1)); return registerSensor(new SensorHTU21D(child_id,1));
} }
...@@ -1427,7 +1532,9 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) { ...@@ -1427,7 +1532,9 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) {
#if MODULE_MLX90614 == 1 #if MODULE_MLX90614 == 1
else if (sensor_type == SENSOR_MLX90614) { else if (sensor_type == SENSOR_MLX90614) {
Adafruit_MLX90614* mlx = new Adafruit_MLX90614(); Adafruit_MLX90614* mlx = new Adafruit_MLX90614();
// register ambient temperature sensor
registerSensor(new SensorMLX90614(child_id,mlx,0)); registerSensor(new SensorMLX90614(child_id,mlx,0));
// register object temperature sensor
child_id = _getAvailableChildId(); child_id = _getAvailableChildId();
return registerSensor(new SensorMLX90614(child_id,mlx,1)); return registerSensor(new SensorMLX90614(child_id,mlx,1));
} }
...@@ -1441,11 +1548,17 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) { ...@@ -1441,11 +1548,17 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) {
#endif #endif
return -1; return -1;
} }
// register temperature sensor
registerSensor(new SensorBME280(child_id,bme,0)); registerSensor(new SensorBME280(child_id,bme,0));
child_id = _getAvailableChildId(); child_id = _getAvailableChildId();
// register humidity sensor
registerSensor(new SensorBME280(child_id,bme,1)); registerSensor(new SensorBME280(child_id,bme,1));
// register pressure sensor
child_id = _getAvailableChildId(); child_id = _getAvailableChildId();
return registerSensor(new SensorBME280(child_id,bme,2)); return registerSensor(new SensorBME280(child_id,bme,2));
// register forecast sensor
child_id = _getAvailableChildId();
return registerSensor(new SensorBME280(child_id,bme,3));
} }
#endif #endif
else { else {
......
...@@ -692,6 +692,8 @@ class SensorMLX90614: public Sensor { ...@@ -692,6 +692,8 @@ class SensorMLX90614: public Sensor {
class SensorBME280: public Sensor { class SensorBME280: public Sensor {
public: public:
SensorBME280(int child_id, Adafruit_BME280* bme, int sensor_type); SensorBME280(int child_id, Adafruit_BME280* bme, int sensor_type);
// define how many pressure samples to keep track of for calculating the forecast (default: 5)
void setForecastSamplesCount(int value);
// define what to do at each stage of the sketch // define what to do at each stage of the sketch
void onBefore(); void onBefore();
void onSetup(); void onSetup();
...@@ -700,6 +702,15 @@ class SensorBME280: public Sensor { ...@@ -700,6 +702,15 @@ class SensorBME280: public Sensor {
protected: protected:
Adafruit_BME280* _bme; Adafruit_BME280* _bme;
int _sensor_type; int _sensor_type;
char* _weather[6] = { "stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown" };
int _forecast_samples_count = 5;
float* _forecast_samples;
int _minute_count = 0;
float _pressure_avg;
float _pressure_avg2;
float _dP_dt;
bool _first_round = true;
float _getLastPressureSamplesAverage();
}; };
#endif #endif
......
...@@ -374,6 +374,12 @@ Each sensor class can expose additional methods. ...@@ -374,6 +374,12 @@ Each sensor class can expose additional methods.
void setResolution(int value); void setResolution(int value);
~~~ ~~~
#### SensorBME280
~~~c
// define how many pressure samples to keep track of for calculating the forecast (default: 5)
void setForecastSamplesCount(int value);
~~~
## Upload your sketch ## Upload your sketch
Upload your sketch to your arduino board as you are used to. Upload your sketch to your arduino board as you are used to.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment