From ebbbd37865b9e83bd3145f00b89ee6053f73f863 Mon Sep 17 00:00:00 2001 From: device111 <48546979+device111@users.noreply.github.com> Date: Sun, 24 May 2020 12:28:08 +0200 Subject: [PATCH] add private pow function in lib for future use alternate pow function for future use in Tasmota to calculate normalized Lux and normalized white values. --- lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp | 27 +++++++++++++++++++-- lib/Adafruit_VEML7700/Adafruit_VEML7700.h | 6 +++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp b/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp index 001d4995e..b719af9fa 100644 --- a/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp +++ b/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp @@ -76,6 +76,29 @@ boolean Adafruit_VEML7700::begin(TwoWire *theWire) { return true; } +float Adafruit_VEML7700::alternate_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 Adafruit_VEML7700::normalize_resolution(float value) { // adjust for gain (1x is normalized) @@ -123,7 +146,7 @@ float Adafruit_VEML7700::readLuxNormalized() { // user-provided correction for non-linearities at high lux/white values: // https://forums.adafruit.com/viewtopic.php?f=19&t=152997&p=758582#p759346 if ((getGain() == VEML7700_GAIN_1_8) && (getIntegrationTime() == VEML7700_IT_25MS)){ - lux = 6.0135e-13*pow(lux,4) - 9.3924e-9*pow(lux,3) + 8.1488e-5*pow(lux,2) + 1.0023*lux; + lux = 6.0135e-13*alternate_pow(lux,4) - 9.3924e-9*alternate_pow(lux,3) + 8.1488e-5*alternate_pow(lux,2) + 1.0023*lux; } return lux; @@ -156,7 +179,7 @@ float Adafruit_VEML7700::readWhiteNormalized() { // user-provided correction for non-linearities at high lux values: // https://forums.adafruit.com/viewtopic.php?f=19&t=152997&p=758582#p759346 if ((getGain() == VEML7700_GAIN_1_8) && (getIntegrationTime() == VEML7700_IT_25MS)){ - white = 2E-15*pow(white,4) + 4E-12*pow(white,3) + 9E-06*pow(white,2) + 1.0179*white - 11.052; + white = 2E-15*alternate_pow(white,4) + 4E-12*alternate_pow(white,3) + 9E-06*alternate_pow(white,2) + 1.0179*white - 11.052; } return white; diff --git a/lib/Adafruit_VEML7700/Adafruit_VEML7700.h b/lib/Adafruit_VEML7700/Adafruit_VEML7700.h index b842a7bc1..13a0bded5 100644 --- a/lib/Adafruit_VEML7700/Adafruit_VEML7700.h +++ b/lib/Adafruit_VEML7700/Adafruit_VEML7700.h @@ -14,6 +14,11 @@ * BSD license (see license.txt) */ +/* + * change from device111 for Tasmota + * Add alternativ Pow function for readLuxNormalized() and readWhiteNormalized() + */ + #ifndef _ADAFRUIT_VEML7700_H #define _ADAFRUIT_VEML7700_H @@ -105,6 +110,7 @@ private: *PowerSave_Enable, *PowerSave_Mode; float normalize_resolution(float value); + float alternate_pow(float a, float b); Adafruit_I2CDevice *i2c_dev;