From 09d6fe6c80aeebc0bb76a2ad0931e91a3eba85cd Mon Sep 17 00:00:00 2001 From: TD-er Date: Tue, 27 Apr 2021 00:50:04 +0200 Subject: [PATCH] [BME680] Fix elevation compensation + add 2 conversion commands Also added 2 commands: - Altitude(air,sea): `%c_alt_pres_sea%(850,1000)` = `1350.03` meter. - PressureElevation(air,alt): `%c_sea_pres_alt%(850,1350.03)` = 1000.00 hPa --- docs/source/Reference/SystemVariable.rst | 6 +++++ src/_P006_BMP085.ino | 4 +--- src/_P028_BME280.ino | 2 +- src/_P032_MS5611.ino | 8 +++---- src/_P106_BME680.ino | 9 ++++++- src/src/Helpers/Convert.cpp | 28 ++++++++++++++++++++++ src/src/Helpers/Convert.h | 13 ++++++++++ src/src/Helpers/StringConverter.cpp | 2 ++ src/src/PluginStructs/P006_data_struct.cpp | 4 ---- src/src/PluginStructs/P006_data_struct.h | 3 --- src/src/PluginStructs/P028_data_struct.cpp | 18 -------------- src/src/PluginStructs/P028_data_struct.h | 13 ---------- src/src/PluginStructs/P032_data_struct.cpp | 6 ----- src/src/PluginStructs/P032_data_struct.h | 6 ----- src/src/WebServer/SysVarPage.cpp | 2 ++ 15 files changed, 65 insertions(+), 59 deletions(-) diff --git a/docs/source/Reference/SystemVariable.rst b/docs/source/Reference/SystemVariable.rst index a8f08a27b..54c9d7bd8 100644 --- a/docs/source/Reference/SystemVariable.rst +++ b/docs/source/Reference/SystemVariable.rst @@ -172,6 +172,12 @@ The conversion always outputs a string, but not all of these can be converted ba * - Dew point(T,H): ``%c_dew_th%(18.6,67)`` - Dew point(T,H): ``12.31`` - Compute dew point given 2 values, temperature and relative humidity + * - Altitude(air,sea): ``%c_alt_pres_sea%(850,1000)`` + - Altitude(air,sea): ``1350.03`` + - Compute Altitude (m) given 2 values, atmospheric pressure and pressure at sea level (hPa). (Added: 2021/04/27) + * - PressureElevation(air,alt): ``%c_sea_pres_alt%(850,1350.03)`` + - PressureElevation(air,alt): ``1000.00`` + - Compensate air pressure for measured atmospheric pressure (hPa) and given altitude (m). (Added: 2021/04/27) * - cm to imperial: ``%c_cm2imp%(190)`` - cm to imperial: ``6'2.8"`` - Centimeter to imperial units diff --git a/src/_P006_BMP085.ino b/src/_P006_BMP085.ino index 3f5bdf4b6..0f66b2bea 100644 --- a/src/_P006_BMP085.ino +++ b/src/_P006_BMP085.ino @@ -90,9 +90,7 @@ boolean Plugin_006(byte function, struct EventStruct *event, String& string) if (elev != 0) { - pressure = P006_data->pressureElevation( - pressure, - elev); + pressure = pressureElevation(pressure, elev); } UserVar[event->BaseVarIndex + 1] = pressure; diff --git a/src/_P028_BME280.ino b/src/_P028_BME280.ino index 6f30eb649..6e7f98f7f 100644 --- a/src/_P028_BME280.ino +++ b/src/_P028_BME280.ino @@ -151,7 +151,7 @@ boolean Plugin_028(byte function, struct EventStruct *event, String& string) const int elev = PCONFIG(1); if (elev != 0) { - UserVar[event->BaseVarIndex + 2] = P028_data->pressureElevation(elev); + UserVar[event->BaseVarIndex + 2] = pressureElevation(P028_data->last_press_val, elev); } else { UserVar[event->BaseVarIndex + 2] = P028_data->last_press_val; } diff --git a/src/_P032_MS5611.ino b/src/_P032_MS5611.ino index bdc7a02ba..90c502b35 100644 --- a/src/_P032_MS5611.ino +++ b/src/_P032_MS5611.ino @@ -101,11 +101,11 @@ boolean Plugin_032(byte function, struct EventStruct *event, String& string) P032_data->readout(); UserVar[event->BaseVarIndex] = P032_data->ms5611_temperature / 100; - int elev = PCONFIG(1); - - if (elev) + + const int elev = PCONFIG(1); + if (elev != 0) { - UserVar[event->BaseVarIndex + 1] = P032_data->pressureElevation(P032_data->ms5611_pressure, elev); + UserVar[event->BaseVarIndex + 1] = pressureElevation(P032_data->ms5611_pressure, elev); } else { UserVar[event->BaseVarIndex + 1] = P032_data->ms5611_pressure; } diff --git a/src/_P106_BME680.ino b/src/_P106_BME680.ino index c93112369..0d75d406f 100644 --- a/src/_P106_BME680.ino +++ b/src/_P106_BME680.ino @@ -132,8 +132,15 @@ boolean Plugin_106(byte function, struct EventStruct *event, String& string) UserVar[event->BaseVarIndex + 0] = P106_data->bme.temperature; UserVar[event->BaseVarIndex + 1] = P106_data->bme.humidity; - UserVar[event->BaseVarIndex + 2] = P106_data->bme.pressure / 100.0f; UserVar[event->BaseVarIndex + 3] = P106_data->bme.gas_resistance / 1000.0f; + + const int elev = PCONFIG(1); + if (elev != 0) + { + UserVar[event->BaseVarIndex + 2] = pressureElevation(P106_data->bme.pressure / 100.0f, elev); + } else { + UserVar[event->BaseVarIndex + 2] = P106_data->bme.pressure / 100.0f; + } } success = true; diff --git a/src/src/Helpers/Convert.cpp b/src/src/Helpers/Convert.cpp index ded1c69b3..7d769705b 100644 --- a/src/src/Helpers/Convert.cpp +++ b/src/src/Helpers/Convert.cpp @@ -181,6 +181,34 @@ float compute_humidity_from_dewpoint(float temperature, float dew_temperature) { } + +/********************************************************************************************\ + Compensate air pressure for given altitude (in meters) + \*********************************************************************************************/ +float pressureElevation(float atmospheric, float altitude) { + // Equation taken from BMP180 datasheet (page 16): + // http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf + + // Note that using the equation from wikipedia can give bad results + // at high altitude. See this thread for more information: + // http://forums.adafruit.com/viewtopic.php?f=22&t=58064 + return atmospheric / pow(1.0f - (altitude / 44330.0f), 5.255f); +} + +float altitudeFromPressure(float atmospheric, float seaLevel) +{ + // Equation taken from BMP180 datasheet (page 16): + // http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf + + // Note that using the equation from wikipedia can give bad results + // at high altitude. See this thread for more information: + // http://forums.adafruit.com/viewtopic.php?f=22&t=58064 + return 44330.0f * (1.0f - pow(atmospheric / seaLevel, 0.1903f)); +} + + + + /********************************************************************************************\ In memory convert float to long \*********************************************************************************************/ diff --git a/src/src/Helpers/Convert.h b/src/src/Helpers/Convert.h index 7e3e1ebe9..a87de80db 100644 --- a/src/src/Helpers/Convert.h +++ b/src/src/Helpers/Convert.h @@ -38,6 +38,19 @@ float compute_dew_point_temp(float temperature, float humidity_percentage); // f = 100 * ((112 - 0.1*T + Td) / (112 + 0.9 * T))^8 float compute_humidity_from_dewpoint(float temperature, float dew_temperature); +/********************************************************************************************\ + Compensate air pressure for measured atmospheric + pressure (in hPa) and given altitude (in meters) + \*********************************************************************************************/ +float pressureElevation(float atmospheric, float altitude); + +/********************************************************************************************\ + Calculates the altitude (in meters) from the specified atmospheric + pressure (in hPa), and sea-level pressure (in hPa). + @param seaLevel Sea-level pressure in hPa + @param atmospheric Atmospheric pressure in hPa + \*********************************************************************************************/ +float altitudeFromPressure(float atmospheric, float seaLevel); /********************************************************************************************\ In memory convert float to long diff --git a/src/src/Helpers/StringConverter.cpp b/src/src/Helpers/StringConverter.cpp index 1c5aa0619..1a5cd5746 100644 --- a/src/src/Helpers/StringConverter.cpp +++ b/src/src/Helpers/StringConverter.cpp @@ -904,6 +904,8 @@ void parseStandardConversions(String& s, bool useURLencode) { float arg2 = 0.0f; SMART_CONV(F("%c_dew_th%"), toString(compute_dew_point_temp(arg1, arg2), 2)) SMART_CONV(F("%c_u2ip%"), formatUnitToIPAddress(arg1, arg2)) + SMART_CONV(F("%c_alt_pres_sea%"), toString(altitudeFromPressure(arg1, arg2), 2)) + SMART_CONV(F("%c_sea_pres_alt%"), toString(pressureElevation(arg1, arg2), 2)) #undef SMART_CONV } diff --git a/src/src/PluginStructs/P006_data_struct.cpp b/src/src/PluginStructs/P006_data_struct.cpp index 9593b7eb2..14da381f8 100644 --- a/src/src/PluginStructs/P006_data_struct.cpp +++ b/src/src/PluginStructs/P006_data_struct.cpp @@ -130,8 +130,4 @@ float P006_data_struct::readTemperature(void) return temp; } -float P006_data_struct::pressureElevation(float atmospheric, int altitude) { - return atmospheric / pow(1.0f - (altitude / 44330.0f), 5.255f); -} - #endif // ifdef USES_P006 diff --git a/src/src/PluginStructs/P006_data_struct.h b/src/src/PluginStructs/P006_data_struct.h index da029a476..524ea8de5 100644 --- a/src/src/PluginStructs/P006_data_struct.h +++ b/src/src/PluginStructs/P006_data_struct.h @@ -18,9 +18,6 @@ struct P006_data_struct : public PluginTaskData_base { float readTemperature(void); - float pressureElevation(float atmospheric, - int altitude); - uint8_t oversampling = BMP085_ULTRAHIGHRES; int16_t ac1, ac2, ac3, b1, b2, mb, mc, md = 0; uint16_t ac4, ac5, ac6 = 0; diff --git a/src/src/PluginStructs/P028_data_struct.cpp b/src/src/PluginStructs/P028_data_struct.cpp index 7f95ee319..d59dc9aa5 100644 --- a/src/src/PluginStructs/P028_data_struct.cpp +++ b/src/src/PluginStructs/P028_data_struct.cpp @@ -397,22 +397,4 @@ float P028_data_struct::readHumidity() return h / 1024.0f; } -float P028_data_struct::Plugin_028_readAltitude(float seaLevel) -{ - // Equation taken from BMP180 datasheet (page 16): - // http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf - - // Note that using the equation from wikipedia can give bad results - // at high altitude. See this thread for more information: - // http://forums.adafruit.com/viewtopic.php?f=22&t=58064 - - float atmospheric = readPressure() / 100.0f; - - return 44330.0f * (1.0f - pow(atmospheric / seaLevel, 0.1903f)); -} - -float P028_data_struct::pressureElevation(int altitude) { - return last_press_val / pow(1.0f - (altitude / 44330.0f), 5.255f); -} - #endif // ifdef USES_P028 diff --git a/src/src/PluginStructs/P028_data_struct.h b/src/src/PluginStructs/P028_data_struct.h index 64e64c474..c1c275a78 100644 --- a/src/src/PluginStructs/P028_data_struct.h +++ b/src/src/PluginStructs/P028_data_struct.h @@ -156,19 +156,6 @@ struct P028_data_struct : public PluginTaskData_base { // **************************************************************************/ float readHumidity(); - // **************************************************************************/ - // Calculates the altitude (in meters) from the specified atmospheric - // pressure (in hPa), and sea-level pressure (in hPa). - // @param seaLevel Sea-level pressure in hPa - // @param atmospheric Atmospheric pressure in hPa - // **************************************************************************/ - float Plugin_028_readAltitude(float seaLevel); - - // **************************************************************************/ - // MSL pressure formula - // **************************************************************************/ - float pressureElevation(int altitude); - bme280_uncomp_data uncompensated; bme280_calib_data calib; float last_hum_val = 0.0f; diff --git a/src/src/PluginStructs/P032_data_struct.cpp b/src/src/PluginStructs/P032_data_struct.cpp index b45ac6ae7..e647b32df 100644 --- a/src/src/PluginStructs/P032_data_struct.cpp +++ b/src/src/PluginStructs/P032_data_struct.cpp @@ -117,11 +117,5 @@ void P032_data_struct::readout() { ms5611_pressure = (((D1 * SENS) / (1 << 21) - Offset) / (1 << 15)); // FIXME TD-er: This is computed twice, is that correct? } -// **************************************************************************/ -// MSL pressure formula -// **************************************************************************/ -double P032_data_struct::pressureElevation(double atmospheric, int altitude) { - return atmospheric / pow(1.0f - (altitude / 44330.0f), 5.255f); -} #endif // ifdef USES_P032 diff --git a/src/src/PluginStructs/P032_data_struct.h b/src/src/PluginStructs/P032_data_struct.h index e576a4880..be058f24e 100644 --- a/src/src/PluginStructs/P032_data_struct.h +++ b/src/src/PluginStructs/P032_data_struct.h @@ -35,12 +35,6 @@ public: // **************************************************************************/ void readout(); - // **************************************************************************/ - // MSL pressure formula - // **************************************************************************/ - double pressureElevation(double atmospheric, - int altitude); - uint8_t i2cAddress; unsigned int ms5611_prom[8] = { 0 }; double ms5611_pressure = 0; diff --git a/src/src/WebServer/SysVarPage.cpp b/src/src/WebServer/SysVarPage.cpp index 34fd89788..d76eaa804 100644 --- a/src/src/WebServer/SysVarPage.cpp +++ b/src/src/WebServer/SysVarPage.cpp @@ -203,6 +203,8 @@ void handle_sysvars() { addSysVar_html(F("{D}C to {D}F: %c_c2f%(20.4)")); addSysVar_html(F("m/s to Bft: %c_ms2Bft%(5.1)")); addSysVar_html(F("Dew point(T,H): %c_dew_th%(18.6,67)")); + addSysVar_html(F("Altitude(air,sea): %c_alt_pres_sea%(850,1000)")); + addSysVar_html(F("PressureElevation(air,alt): %c_sea_pres_alt%(850,1350.03)")); addFormSeparator(3); addSysVar_html(F("cm to imperial: %c_cm2imp%(190)")); addSysVar_html(F("mm to imperial: %c_mm2imp%(1900)"));