From 3829265e6dc80d23deb2d39a0677591d81433550 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 24 May 2020 17:13:10 +0200 Subject: [PATCH] Consolidate FastPrecisePowf --- .../src/MutichannelGasSensor.cpp | 50 +++++-------------- .../src/MutichannelGasSensor.h | 18 ++++--- .../esp-knx-ip-conversion.cpp | 26 +--------- lib/esp-knx-ip-0.5.2/esp-knx-ip.h | 5 ++ 4 files changed, 30 insertions(+), 69 deletions(-) diff --git a/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.cpp b/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.cpp index 66e62fa4a..2d4d4c5dd 100644 --- a/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.cpp +++ b/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.cpp @@ -327,30 +327,6 @@ int16_t MutichannelGasSensor::readR(void) ** Returns: float value - concentration of the gas *********************************************************************************************************/ -float MutichannelGasSensor_pow(float a, float b) -{ - // https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/ - // calculate approximation with fraction of the exponent - int e = abs((int)b); - union { - double d; - int x[2]; - } u = { a }; - u.x[1] = (int)((b - e) * (u.x[1] - 1072632447) + 1072632447); - u.x[0] = 0; - // exponentiation by squaring with the exponent's integer part - // double r = u.d makes everything much slower, not sure why - double r = 1.0; - while (e) { - if (e & 1) { - r *= a; - } - a *= a; - e >>= 1; - } - return r * u.d; -} - float MutichannelGasSensor::calcGas(int gas) { @@ -382,9 +358,9 @@ float MutichannelGasSensor::calcGas(int gas) int An_1 = get_addr_dta(CH_VALUE_CO); int An_2 = get_addr_dta(CH_VALUE_NO2); - ratio0 = (float)An_0/(float)A0_0*(1023.0-A0_0)/(1023.0-An_0); - ratio1 = (float)An_1/(float)A0_1*(1023.0-A0_1)/(1023.0-An_1); - ratio2 = (float)An_2/(float)A0_2*(1023.0-A0_2)/(1023.0-An_2); + ratio0 = (float)An_0/(float)A0_0*(1023.0f-A0_0)/(1023.0f-An_0); + ratio1 = (float)An_1/(float)A0_1*(1023.0f-A0_1)/(1023.0f-An_1); + ratio2 = (float)An_2/(float)A0_2*(1023.0f-A0_2)/(1023.0f-An_2); } @@ -394,42 +370,42 @@ float MutichannelGasSensor::calcGas(int gas) { case CO: { - c = MutichannelGasSensor_pow(ratio1, -1.179)*4.385; //mod by jack + c = pow(ratio1, -1.179f)*4.385f; //mod by jack break; } case NO2: { - c = MutichannelGasSensor_pow(ratio2, 1.007)/6.855; //mod by jack + c = pow(ratio2, 1.007f)/6.855f; //mod by jack break; } case NH3: { - c = MutichannelGasSensor_pow(ratio0, -1.67)/1.47; //modi by jack + c = pow(ratio0, -1.67f)/1.47f; //modi by jack break; } case C3H8: //add by jack { - c = MutichannelGasSensor_pow(ratio0, -2.518)*570.164; + c = pow(ratio0, -2.518f)*570.164f; break; } case C4H10: //add by jack { - c = MutichannelGasSensor_pow(ratio0, -2.138)*398.107; + c = pow(ratio0, -2.138f)*398.107f; break; } case GAS_CH4: //add by jack { - c = MutichannelGasSensor_pow(ratio1, -4.363)*630.957; + c = pow(ratio1, -4.363f)*630.957f; break; } case H2: //add by jack { - c = MutichannelGasSensor_pow(ratio1, -1.8)*0.73; + c = pow(ratio1, -1.8f)*0.73f; break; } case C2H5OH: //add by jack { - c = MutichannelGasSensor_pow(ratio1, -1.552)*1.622; + c = pow(ratio1, -1.552f)*1.622f; break; } default: @@ -630,7 +606,7 @@ float MutichannelGasSensor::getR0(unsigned char ch) // 0:CH3, 1:CO, 2:NO default:; } - float r = 56.0*(float)a/(1023.0-(float)a); + float r = 56.0f*(float)a/(1023.0f-(float)a); return r; } @@ -661,7 +637,7 @@ float MutichannelGasSensor::getRs(unsigned char ch) // 0:CH3, 1:CO, 2:NO default:; } - float r = 56.0*(float)a/(1023.0-(float)a); + float r = 56.0f*(float)a/(1023.0f-(float)a); return r; } diff --git a/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.h b/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.h index 5f4ce7c7f..87ad10b46 100644 --- a/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.h +++ b/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.h @@ -6,7 +6,7 @@ 2015-3-17 http://www.seeed.cc/ modi by Jack, 2015-8 - + V2 by Loovee 2016-11-11 @@ -38,7 +38,7 @@ #define DEFAULT_I2C_ADDR 0x04 -#define ADDR_IS_SET 0 // if this is the first time to run, if 1126, set +#define ADDR_IS_SET 0 // if this is the first time to run, if 1126, set #define ADDR_FACTORY_ADC_NH3 2 #define ADDR_FACTORY_ADC_CO 4 #define ADDR_FACTORY_ADC_NO2 6 @@ -68,19 +68,23 @@ enum{CO, NO2, NH3, C3H8, C4H10, GAS_CH4, H2, C2H5OH}; +// FastPrecisePowf from tasmota/support_float.ino +extern float FastPrecisePowf(const float x, const float y); + class MutichannelGasSensor{ private: + static inline float pow(float a, float b) { return FastPrecisePowf(a, b); } int __version; int __send_error; unsigned char dta_test[20]; - + unsigned int readChAdcValue(int ch); unsigned int adcValueR0_NH3_Buf; unsigned int adcValueR0_CO_Buf; unsigned int adcValueR0_NO2_Buf; - + public: uint8_t i2cAddress; //I2C address of this MCU @@ -98,7 +102,7 @@ public: int16_t readR0(void); int16_t readR(void); float calcGas(int gas); - + public: void begin(int address); @@ -107,7 +111,7 @@ public: void powerOn(void); void powerOff(void); void doCalibrate(void); - + //get gas concentration, unit: ppm float measure_CO(){return calcGas(CO);} float measure_NO2(){return calcGas(NO2);} @@ -117,7 +121,7 @@ public: float measure_CH4(){return calcGas(GAS_CH4);} float measure_H2(){return calcGas(H2);} float measure_C2H5OH(){return calcGas(C2H5OH);} - + float getR0(unsigned char ch); // 0:CH3, 1:CO, 2:NO2 float getRs(unsigned char ch); // 0:CH3, 1:CO, 2:NO2 diff --git a/lib/esp-knx-ip-0.5.2/esp-knx-ip-conversion.cpp b/lib/esp-knx-ip-0.5.2/esp-knx-ip-conversion.cpp index 02f2f59be..9dc2fd563 100644 --- a/lib/esp-knx-ip-0.5.2/esp-knx-ip-conversion.cpp +++ b/lib/esp-knx-ip-0.5.2/esp-knx-ip-conversion.cpp @@ -35,36 +35,12 @@ uint16_t ESPKNXIP::data_to_2byte_uint(uint8_t *data) return (uint16_t)((data[1] << 8) | data[2]); } -float esp_knx_pow(float a, float b) -{ - // https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/ - // calculate approximation with fraction of the exponent - int e = abs((int)b); - union { - double d; - int x[2]; - } u = { a }; - u.x[1] = (int)((b - e) * (u.x[1] - 1072632447) + 1072632447); - u.x[0] = 0; - // exponentiation by squaring with the exponent's integer part - // double r = u.d makes everything much slower, not sure why - double r = 1.0; - while (e) { - if (e & 1) { - r *= a; - } - a *= a; - e >>= 1; - } - return r * u.d; -} - float ESPKNXIP::data_to_2byte_float(uint8_t *data) { //uint8_t sign = (data[1] & 0b10000000) >> 7; uint8_t expo = (data[1] & 0b01111000) >> 3; int16_t mant = ((data[1] & 0b10000111) << 8) | data[2]; - return 0.01f * mant * esp_knx_pow(2, expo); + return 0.01f * mant * pow(2, expo); } time_of_day_t ESPKNXIP::data_to_3byte_time(uint8_t *data) diff --git a/lib/esp-knx-ip-0.5.2/esp-knx-ip.h b/lib/esp-knx-ip-0.5.2/esp-knx-ip.h index 7c6377bec..ea711825f 100644 --- a/lib/esp-knx-ip-0.5.2/esp-knx-ip.h +++ b/lib/esp-knx-ip-0.5.2/esp-knx-ip.h @@ -397,6 +397,9 @@ typedef struct __callback_assignment callback_id_t callback_id; } callback_assignment_t; +// FastPrecisePowf from tasmota/support_float.ino +extern float FastPrecisePowf(const float x, const float y); + class ESPKNXIP { public: ESPKNXIP(); @@ -564,6 +567,8 @@ class ESPKNXIP { callback_assignment_id_t __callback_register_assignment(address_t address, callback_id_t id); void __callback_delete_assignment(callback_assignment_id_t id); + static inline float pow(float a, float b) { return FastPrecisePowf(a, b); } + ESP8266WebServer *server; address_t physaddr;