mirror of https://github.com/arendst/Tasmota.git
Change converted double to float in rules, and replaced trigonometric functions from stdlib with smaller versions.
This commit is contained in:
parent
912e8b62e7
commit
15e37ef0bb
|
@ -7,6 +7,7 @@
|
|||
* Add define USE_DHT to my_user_config.h to save space in sonoff-basic.bin
|
||||
* Change TLS+AWS IoT optimization for speed, code and memory footprint
|
||||
* Add command SetOption40 0..250 to disable button functionality if activated for over 0.1 second. Needs SetOption1 1 and SetOption13 0 (#5449)
|
||||
* Change converted double to float in rules, and replaced trigonometric functions from stdlib with smaller versions.
|
||||
*
|
||||
* 6.5.0.15 20190606
|
||||
* Change pubsubclient MQTT_KEEPALIVE from 10 to 30 seconds in preparation of AWS IoT support
|
||||
|
|
|
@ -224,7 +224,7 @@ char* subStr(char* dest, char* str, const char *delim, int index)
|
|||
return sub;
|
||||
}
|
||||
|
||||
double CharToDouble(const char *str)
|
||||
float CharToFloat(const char *str)
|
||||
{
|
||||
// simple ascii to double, because atof or strtod are too large
|
||||
char strbuf[24];
|
||||
|
@ -237,23 +237,23 @@ double CharToDouble(const char *str)
|
|||
if (*pt == '-') { sign = -1; }
|
||||
if (*pt == '-' || *pt=='+') { pt++; } // Skip any sign
|
||||
|
||||
double left = 0;
|
||||
float left = 0;
|
||||
if (*pt != '.') {
|
||||
left = atoi(pt); // Get left part
|
||||
while (isdigit(*pt)) { pt++; } // Skip number
|
||||
}
|
||||
|
||||
double right = 0;
|
||||
float right = 0;
|
||||
if (*pt == '.') {
|
||||
pt++;
|
||||
right = atoi(pt); // Decimal part
|
||||
while (isdigit(*pt)) {
|
||||
pt++;
|
||||
right /= 10.0;
|
||||
right /= 10.0f;
|
||||
}
|
||||
}
|
||||
|
||||
double result = left + right;
|
||||
float result = left + right;
|
||||
if (sign < 0) {
|
||||
return -result; // Add negative sign
|
||||
}
|
||||
|
|
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
support_float.ino - support for Sonoff-Tasmota
|
||||
|
||||
Copyright (C) 2019 Theo Arends
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// All code adapted from: http://www.ganssle.com/approx.htm
|
||||
|
||||
/// ========================================
|
||||
// The following code implements approximations to various trig functions.
|
||||
//
|
||||
// This is demo code to guide developers in implementing their own approximation
|
||||
// software. This code is merely meant to illustrate algorithms.
|
||||
|
||||
inline float sinf(float x) { return sin_52(x); }
|
||||
inline float cosf(float x) { return cos_52(x); }
|
||||
inline float tanf(float x) { return tan_56(x); }
|
||||
inline float atanf(float x) { return atan_66(x); }
|
||||
inline float asinf(float x) { return asinf1(x); }
|
||||
inline float acosf(float x) { return acosf1(x); }
|
||||
inline float sqrtf(float x) { return sqrt1(x); }
|
||||
|
||||
// Math constants we'll use
|
||||
double const f_pi=3.1415926535897932384626433; // f_pi
|
||||
double const f_twopi=2.0*f_pi; // f_pi times 2
|
||||
double const f_two_over_pi= 2.0/f_pi; // 2/f_pi
|
||||
double const f_halfpi=f_pi/2.0; // f_pi divided by 2
|
||||
double const f_threehalfpi=3.0*f_pi/2.0; // f_pi times 3/2, used in tan routines
|
||||
double const f_four_over_pi=4.0/f_pi; // 4/f_pi, used in tan routines
|
||||
double const f_qtrpi=f_pi/4.0; // f_pi/4.0, used in tan routines
|
||||
double const f_sixthpi=f_pi/6.0; // f_pi/6.0, used in atan routines
|
||||
double const f_tansixthpi=tan(f_sixthpi); // tan(f_pi/6), used in atan routines
|
||||
double const f_twelfthpi=f_pi/12.0; // f_pi/12.0, used in atan routines
|
||||
double const f_tantwelfthpi=tan(f_twelfthpi); // tan(f_pi/12), used in atan routines
|
||||
|
||||
// *********************************************************
|
||||
// ***
|
||||
// *** Routines to compute sine and cosine to 5.2 digits
|
||||
// *** of accuracy.
|
||||
// ***
|
||||
// *********************************************************
|
||||
//
|
||||
// cos_52s computes cosine (x)
|
||||
//
|
||||
// Accurate to about 5.2 decimal digits over the range [0, f_pi/2].
|
||||
// The input argument is in radians.
|
||||
//
|
||||
// Algorithm:
|
||||
// cos(x)= c1 + c2*x**2 + c3*x**4 + c4*x**6
|
||||
// which is the same as:
|
||||
// cos(x)= c1 + x**2(c2 + c3*x**2 + c4*x**4)
|
||||
// cos(x)= c1 + x**2(c2 + x**2(c3 + c4*x**2))
|
||||
//
|
||||
float cos_52s(float x)
|
||||
{
|
||||
const float c1= 0.9999932946;
|
||||
const float c2=-0.4999124376;
|
||||
const float c3= 0.0414877472;
|
||||
const float c4=-0.0012712095;
|
||||
|
||||
float x2; // The input argument squared
|
||||
|
||||
x2=x * x;
|
||||
return (c1 + x2*(c2 + x2*(c3 + c4*x2)));
|
||||
}
|
||||
|
||||
//
|
||||
// This is the main cosine approximation "driver"
|
||||
// It reduces the input argument's range to [0, f_pi/2],
|
||||
// and then calls the approximator.
|
||||
// See the notes for an explanation of the range reduction.
|
||||
//
|
||||
float cos_52(float x){
|
||||
int quad; // what quadrant are we in?
|
||||
|
||||
x=fmodf(x, f_twopi); // Get rid of values > 2* f_pi
|
||||
if(x<0)x=-x; // cos(-x) = cos(x)
|
||||
quad=int(x * (float)f_two_over_pi); // Get quadrant # (0 to 3) we're in
|
||||
switch (quad){
|
||||
case 0: return cos_52s(x);
|
||||
case 1: return -cos_52s((float)f_pi-x);
|
||||
case 2: return -cos_52s(x-(float)f_pi);
|
||||
case 3: return cos_52s((float)f_twopi-x);
|
||||
}
|
||||
}
|
||||
//
|
||||
// The sine is just cosine shifted a half-f_pi, so
|
||||
// we'll adjust the argument and call the cosine approximation.
|
||||
//
|
||||
float sin_52(float x){
|
||||
return cos_52((float)f_halfpi-x);
|
||||
}
|
||||
|
||||
// *********************************************************
|
||||
// ***
|
||||
// *** Routines to compute tangent to 5.6 digits
|
||||
// *** of accuracy.
|
||||
// ***
|
||||
// *********************************************************
|
||||
//
|
||||
// tan_56s computes tan(f_pi*x/4)
|
||||
//
|
||||
// Accurate to about 5.6 decimal digits over the range [0, f_pi/4].
|
||||
// The input argument is in radians. Note that the function
|
||||
// computes tan(f_pi*x/4), NOT tan(x); it's up to the range
|
||||
// reduction algorithm that calls this to scale things properly.
|
||||
//
|
||||
// Algorithm:
|
||||
// tan(x)= x(c1 + c2*x**2)/(c3 + x**2)
|
||||
//
|
||||
float tan_56s(float x)
|
||||
{
|
||||
const float c1=-3.16783027;
|
||||
const float c2= 0.134516124;
|
||||
const float c3=-4.033321984;
|
||||
|
||||
float x2; // The input argument squared
|
||||
|
||||
x2=x * x;
|
||||
return (x*(c1 + c2 * x2)/(c3 + x2));
|
||||
}
|
||||
|
||||
//
|
||||
// This is the main tangent approximation "driver"
|
||||
// It reduces the input argument's range to [0, f_pi/4],
|
||||
// and then calls the approximator.
|
||||
// See the notes for an explanation of the range reduction.
|
||||
// Enter with positive angles only.
|
||||
//
|
||||
// WARNING: We do not test for the tangent approaching infinity,
|
||||
// which it will at x=f_pi/2 and x=3*f_pi/2. If this is a problem
|
||||
// in your application, take appropriate action.
|
||||
//
|
||||
float tan_56(float x){
|
||||
int octant; // what octant are we in?
|
||||
|
||||
x=fmodf(x, (float)f_twopi); // Get rid of values >2 *f_pi
|
||||
octant=int(x * (float)f_four_over_pi); // Get octant # (0 to 7)
|
||||
switch (octant){
|
||||
case 0: return tan_56s(x *(float)f_four_over_pi);
|
||||
case 1: return 1.0f/tan_56s(((float)f_halfpi-x) *(float)f_four_over_pi);
|
||||
case 2: return -1.0f/tan_56s((x-(float)f_halfpi) *(float)f_four_over_pi);
|
||||
case 3: return - tan_56s(((float)f_pi-x) *(float)f_four_over_pi);
|
||||
case 4: return tan_56s((x-(float)f_pi) *(float)f_four_over_pi);
|
||||
case 5: return 1.0f/tan_56s(((float)f_threehalfpi-x)*(float)f_four_over_pi);
|
||||
case 6: return -1.0f/tan_56s((x-(float)f_threehalfpi)*(float)f_four_over_pi);
|
||||
case 7: return - tan_56s(((float)f_twopi-x) *(float)f_four_over_pi);
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************
|
||||
// ***
|
||||
// *** Routines to compute arctangent to 6.6 digits
|
||||
// *** of accuracy.
|
||||
// ***
|
||||
// *********************************************************
|
||||
//
|
||||
// atan_66s computes atan(x)
|
||||
//
|
||||
// Accurate to about 6.6 decimal digits over the range [0, f_pi/12].
|
||||
//
|
||||
// Algorithm:
|
||||
// atan(x)= x(c1 + c2*x**2)/(c3 + x**2)
|
||||
//
|
||||
float atan_66s(float x)
|
||||
{
|
||||
const float c1=1.6867629106;
|
||||
const float c2=0.4378497304;
|
||||
const float c3=1.6867633134;
|
||||
|
||||
float x2; // The input argument squared
|
||||
|
||||
x2=x * x;
|
||||
return (x*(c1 + x2*c2)/(c3 + x2));
|
||||
}
|
||||
|
||||
//
|
||||
// This is the main arctangent approximation "driver"
|
||||
// It reduces the input argument's range to [0, f_pi/12],
|
||||
// and then calls the approximator.
|
||||
//
|
||||
//
|
||||
float atan_66(float x){
|
||||
float y; // return from atan__s function
|
||||
bool complement= false; // true if arg was >1
|
||||
bool region= false; // true depending on region arg is in
|
||||
bool sign= false; // true if arg was < 0
|
||||
|
||||
if (x <0 ){
|
||||
x=-x;
|
||||
sign=true; // arctan(-x)=-arctan(x)
|
||||
}
|
||||
if (x > 1.0){
|
||||
x=1.0/x; // keep arg between 0 and 1
|
||||
complement=true;
|
||||
}
|
||||
if (x > (float)f_tantwelfthpi){
|
||||
x = (x-(float)f_tansixthpi)/(1+(float)f_tansixthpi*x); // reduce arg to under tan(f_pi/12)
|
||||
region=true;
|
||||
}
|
||||
|
||||
y=atan_66s(x); // run the approximation
|
||||
if (region) y+=(float)f_sixthpi; // correct for region we're in
|
||||
if (complement)y=(float)f_halfpi-y; // correct for 1/x if we did that
|
||||
if (sign)y=-y; // correct for negative arg
|
||||
return (y);
|
||||
}
|
||||
|
||||
float asinf1(float x) {
|
||||
float d = 1.0f - x*x;
|
||||
if (d < 0.0f) { return nanf(""); }
|
||||
return 2 * atan_66(x / (1 + sqrt1(d)));
|
||||
}
|
||||
|
||||
float acosf1(float x) {
|
||||
float d = 1.0f - x*x;
|
||||
if (d < 0.0f) { return nanf(""); }
|
||||
float y = asinf1(sqrt1(d));
|
||||
if (x >= 0.0f) {
|
||||
return y;
|
||||
} else {
|
||||
return (float)f_pi - y;
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.codeproject.com/Articles/69941/Best-Square-Root-Method-Algorithm-Function-Precisi
|
||||
float sqrt1(const float x)
|
||||
{
|
||||
union
|
||||
{
|
||||
int i;
|
||||
float x;
|
||||
} u;
|
||||
u.x = x;
|
||||
u.i = (1<<29) + (u.i >> 1) - (1<<22);
|
||||
|
||||
// Two Babylonian Steps (simplified from:)
|
||||
// u.x = 0.5f * (u.x + x/u.x);
|
||||
// u.x = 0.5f * (u.x + x/u.x);
|
||||
u.x = u.x + x/u.x;
|
||||
u.x = 0.25f*u.x + x/u.x;
|
||||
|
||||
return u.x;
|
||||
}
|
|
@ -487,7 +487,7 @@ bool TimerCommand(void)
|
|||
#ifdef USE_SUNRISE
|
||||
else if (CMND_LONGITUDE == command_code) {
|
||||
if (XdrvMailbox.data_len) {
|
||||
Settings.longitude = (int)(CharToDouble(XdrvMailbox.data) *1000000);
|
||||
Settings.longitude = (int)(CharToFloat(XdrvMailbox.data) *1000000);
|
||||
}
|
||||
char lbuff[33];
|
||||
dtostrfd(((float)Settings.longitude) /1000000, 6, lbuff);
|
||||
|
@ -495,7 +495,7 @@ bool TimerCommand(void)
|
|||
}
|
||||
else if (CMND_LATITUDE == command_code) {
|
||||
if (XdrvMailbox.data_len) {
|
||||
Settings.latitude = (int)(CharToDouble(XdrvMailbox.data) *1000000);
|
||||
Settings.latitude = (int)(CharToFloat(XdrvMailbox.data) *1000000);
|
||||
}
|
||||
char lbuff[33];
|
||||
dtostrfd(((float)Settings.latitude) /1000000, 6, lbuff);
|
||||
|
|
|
@ -179,7 +179,7 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule)
|
|||
}
|
||||
|
||||
char rule_svalue[CMDSZ] = { 0 };
|
||||
double rule_value = 0;
|
||||
float rule_value = 0;
|
||||
if (compare != COMPARE_OPERATOR_NONE) {
|
||||
String rule_param = rule_name.substring(pos + strlen(compare_operator));
|
||||
for (uint32_t i = 0; i < MAX_RULE_VARS; i++) {
|
||||
|
@ -225,7 +225,7 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule)
|
|||
if (temp_value > -1) {
|
||||
rule_value = temp_value;
|
||||
} else {
|
||||
rule_value = CharToDouble((char*)rule_svalue); // 0.1 - This saves 9k code over toFLoat()!
|
||||
rule_value = CharToFloat((char*)rule_svalue); // 0.1 - This saves 9k code over toFLoat()!
|
||||
}
|
||||
rule_name = rule_name.substring(0, pos); // "CURRENT"
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule)
|
|||
JsonObject &root = jsonBuf.parseObject(event);
|
||||
if (!root.success()) { return false; } // No valid JSON data
|
||||
|
||||
double value = 0;
|
||||
float value = 0;
|
||||
const char* str_value = root[rule_task][rule_name];
|
||||
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("RUL: Task %s, Name %s, Value |%s|, TrigCnt %d, TrigSt %d, Source %s, Json %s"),
|
||||
|
@ -248,7 +248,7 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule)
|
|||
|
||||
// Step 3: Compare rule (value)
|
||||
if (str_value) {
|
||||
value = CharToDouble((char*)str_value);
|
||||
value = CharToFloat((char*)str_value);
|
||||
int int_value = int(value);
|
||||
int int_rule_value = int(rule_value);
|
||||
switch (compare) {
|
||||
|
@ -797,15 +797,15 @@ String RulesUnsubscribe(const char * data, int data_len)
|
|||
* Parse a number value
|
||||
* Input:
|
||||
* pNumber - A char pointer point to a digit started string (guaranteed)
|
||||
* value - Reference a double variable used to accept the result
|
||||
* value - Reference a float variable used to accept the result
|
||||
* Output:
|
||||
* pNumber - Pointer forward to next character after the number
|
||||
* value - double type, the result value
|
||||
* value - float type, the result value
|
||||
* Return:
|
||||
* true - succeed
|
||||
* false - failed
|
||||
*/
|
||||
bool findNextNumber(char * &pNumber, double &value)
|
||||
bool findNextNumber(char * &pNumber, float &value)
|
||||
{
|
||||
bool bSucceed = false;
|
||||
String sNumber = "";
|
||||
|
@ -818,7 +818,7 @@ bool findNextNumber(char * &pNumber, double &value)
|
|||
}
|
||||
}
|
||||
if (sNumber.length() > 0) {
|
||||
value = CharToDouble(sNumber.c_str());
|
||||
value = CharToFloat(sNumber.c_str());
|
||||
bSucceed = true;
|
||||
}
|
||||
return bSucceed;
|
||||
|
@ -826,18 +826,18 @@ bool findNextNumber(char * &pNumber, double &value)
|
|||
|
||||
/********************************************************************************************/
|
||||
/*
|
||||
* Parse a variable (like VAR1, MEM3) and get its value (double type)
|
||||
* Parse a variable (like VAR1, MEM3) and get its value (float type)
|
||||
* Input:
|
||||
* pVarname - A char pointer point to a variable name string
|
||||
* value - Reference a double variable used to accept the result
|
||||
* value - Reference a float variable used to accept the result
|
||||
* Output:
|
||||
* pVarname - Pointer forward to next character after the variable
|
||||
* value - double type, the result value
|
||||
* value - float type, the result value
|
||||
* Return:
|
||||
* true - succeed
|
||||
* false - failed
|
||||
*/
|
||||
bool findNextVariableValue(char * &pVarname, double &value)
|
||||
bool findNextVariableValue(char * &pVarname, float &value)
|
||||
{
|
||||
bool succeed = true;
|
||||
value = 0;
|
||||
|
@ -854,12 +854,12 @@ bool findNextVariableValue(char * &pVarname, double &value)
|
|||
if (sVarName.startsWith(F("VAR"))) {
|
||||
int index = sVarName.substring(3).toInt();
|
||||
if (index > 0 && index <= MAX_RULE_VARS) {
|
||||
value = CharToDouble(vars[index -1]);
|
||||
value = CharToFloat(vars[index -1]);
|
||||
}
|
||||
} else if (sVarName.startsWith(F("MEM"))) {
|
||||
int index = sVarName.substring(3).toInt();
|
||||
if (index > 0 && index <= MAX_RULE_MEMS) {
|
||||
value = CharToDouble(Settings.mems[index -1]);
|
||||
value = CharToFloat(Settings.mems[index -1]);
|
||||
}
|
||||
} else if (sVarName.equals(F("TIME"))) {
|
||||
value = MinutesPastMidnight();
|
||||
|
@ -891,15 +891,15 @@ bool findNextVariableValue(char * &pVarname, double &value)
|
|||
* - An expression enclosed with a pair of round brackets, (.....)
|
||||
* Input:
|
||||
* pointer - A char pointer point to a place of the expression string
|
||||
* value - Reference a double variable used to accept the result
|
||||
* value - Reference a float variable used to accept the result
|
||||
* Output:
|
||||
* pointer - Pointer forward to next character after next object
|
||||
* value - double type, the result value
|
||||
* value - float type, the result value
|
||||
* Return:
|
||||
* true - succeed
|
||||
* false - failed
|
||||
*/
|
||||
bool findNextObjectValue(char * &pointer, double &value)
|
||||
bool findNextObjectValue(char * &pointer, float &value)
|
||||
{
|
||||
bool bSucceed = false;
|
||||
while (*pointer)
|
||||
|
@ -984,15 +984,15 @@ bool findNextOperator(char * &pointer, int8_t &op)
|
|||
* Calculate a simple expression composed by 2 value and 1 operator, like 2 * 3
|
||||
* Input:
|
||||
* pointer - A char pointer point to a place of the expression string
|
||||
* value - Reference a double variable used to accept the result
|
||||
* value - Reference a float variable used to accept the result
|
||||
* Output:
|
||||
* pointer - Pointer forward to next character after next object
|
||||
* value - double type, the result value
|
||||
* value - float type, the result value
|
||||
* Return:
|
||||
* true - succeed
|
||||
* false - failed
|
||||
*/
|
||||
double calculateTwoValues(double v1, double v2, uint8_t op)
|
||||
float calculateTwoValues(float v1, float v2, uint8_t op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
|
@ -1025,7 +1025,7 @@ double calculateTwoValues(double v1, double v2, uint8_t op)
|
|||
* expression - The expression to be evaluated
|
||||
* len - Length of the expression
|
||||
* Return:
|
||||
* double - result.
|
||||
* float - result.
|
||||
* 0 - if the expression is invalid
|
||||
* An example:
|
||||
* MEM1 = 3, MEM2 = 6, VAR2 = 15, VAR10 = 80
|
||||
|
@ -1045,17 +1045,17 @@ double calculateTwoValues(double v1, double v2, uint8_t op)
|
|||
* 2 + 1
|
||||
* 3 / 2
|
||||
*/
|
||||
double evaluateExpression(const char * expression, unsigned int len)
|
||||
float evaluateExpression(const char * expression, unsigned int len)
|
||||
{
|
||||
char expbuf[len + 1];
|
||||
memcpy(expbuf, expression, len);
|
||||
expbuf[len] = '\0';
|
||||
char * scan_pointer = expbuf;
|
||||
|
||||
LinkedList<double> object_values;
|
||||
LinkedList<float> object_values;
|
||||
LinkedList<int8_t> operators;
|
||||
int8_t op;
|
||||
double va;
|
||||
float va;
|
||||
//Find and add the value of first object
|
||||
if (findNextObjectValue(scan_pointer, va)) {
|
||||
object_values.add(va);
|
||||
|
@ -1154,7 +1154,7 @@ bool RulesCommand(void)
|
|||
else if ((CMND_RULETIMER == command_code) && (index > 0) && (index <= MAX_RULE_TIMERS)) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
#ifdef USE_EXPRESSION
|
||||
double timer_set = evaluateExpression(XdrvMailbox.data, XdrvMailbox.data_len);
|
||||
float timer_set = evaluateExpression(XdrvMailbox.data, XdrvMailbox.data_len);
|
||||
rules_timer[index -1] = (timer_set > 0) ? millis() + (1000 * timer_set) : 0;
|
||||
#else
|
||||
rules_timer[index -1] = (XdrvMailbox.payload > 0) ? millis() + (1000 * XdrvMailbox.payload) : 0;
|
||||
|
@ -1202,7 +1202,7 @@ bool RulesCommand(void)
|
|||
}
|
||||
else if ((CMND_ADD == command_code) && (index > 0) && (index <= MAX_RULE_VARS)) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
double tempvar = CharToDouble(vars[index -1]) + CharToDouble(XdrvMailbox.data);
|
||||
float tempvar = CharToFloat(vars[index -1]) + CharToFloat(XdrvMailbox.data);
|
||||
dtostrfd(tempvar, Settings.flag2.calc_resolution, vars[index -1]);
|
||||
bitSet(vars_event, index -1);
|
||||
}
|
||||
|
@ -1210,7 +1210,7 @@ bool RulesCommand(void)
|
|||
}
|
||||
else if ((CMND_SUB == command_code) && (index > 0) && (index <= MAX_RULE_VARS)) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
double tempvar = CharToDouble(vars[index -1]) - CharToDouble(XdrvMailbox.data);
|
||||
float tempvar = CharToFloat(vars[index -1]) - CharToFloat(XdrvMailbox.data);
|
||||
dtostrfd(tempvar, Settings.flag2.calc_resolution, vars[index -1]);
|
||||
bitSet(vars_event, index -1);
|
||||
}
|
||||
|
@ -1218,7 +1218,7 @@ bool RulesCommand(void)
|
|||
}
|
||||
else if ((CMND_MULT == command_code) && (index > 0) && (index <= MAX_RULE_VARS)) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
double tempvar = CharToDouble(vars[index -1]) * CharToDouble(XdrvMailbox.data);
|
||||
float tempvar = CharToFloat(vars[index -1]) * CharToFloat(XdrvMailbox.data);
|
||||
dtostrfd(tempvar, Settings.flag2.calc_resolution, vars[index -1]);
|
||||
bitSet(vars_event, index -1);
|
||||
}
|
||||
|
@ -1229,12 +1229,12 @@ bool RulesCommand(void)
|
|||
if (strstr(XdrvMailbox.data, ",") != nullptr) { // Process parameter entry
|
||||
char sub_string[XdrvMailbox.data_len +1];
|
||||
|
||||
double valueIN = CharToDouble(subStr(sub_string, XdrvMailbox.data, ",", 1));
|
||||
double fromLow = CharToDouble(subStr(sub_string, XdrvMailbox.data, ",", 2));
|
||||
double fromHigh = CharToDouble(subStr(sub_string, XdrvMailbox.data, ",", 3));
|
||||
double toLow = CharToDouble(subStr(sub_string, XdrvMailbox.data, ",", 4));
|
||||
double toHigh = CharToDouble(subStr(sub_string, XdrvMailbox.data, ",", 5));
|
||||
double value = map_double(valueIN, fromLow, fromHigh, toLow, toHigh);
|
||||
float valueIN = CharToFloat(subStr(sub_string, XdrvMailbox.data, ",", 1));
|
||||
float fromLow = CharToFloat(subStr(sub_string, XdrvMailbox.data, ",", 2));
|
||||
float fromHigh = CharToFloat(subStr(sub_string, XdrvMailbox.data, ",", 3));
|
||||
float toLow = CharToFloat(subStr(sub_string, XdrvMailbox.data, ",", 4));
|
||||
float toHigh = CharToFloat(subStr(sub_string, XdrvMailbox.data, ",", 5));
|
||||
float value = map_double(valueIN, fromLow, fromHigh, toLow, toHigh);
|
||||
dtostrfd(value, Settings.flag2.calc_resolution, vars[index -1]);
|
||||
bitSet(vars_event, index -1);
|
||||
}
|
||||
|
@ -1254,7 +1254,7 @@ bool RulesCommand(void)
|
|||
return serviced;
|
||||
}
|
||||
|
||||
double map_double(double x, double in_min, double in_max, double out_min, double out_max)
|
||||
float map_double(float x, float in_min, float in_max, float out_min, float out_max)
|
||||
{
|
||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
}
|
||||
|
@ -1302,4 +1302,4 @@ bool Xdrv10(uint8_t function)
|
|||
}
|
||||
|
||||
#endif // Do not USE_SCRIPT
|
||||
#endif // USE_RULES
|
||||
#endif // USE_RULES
|
||||
|
|
|
@ -298,7 +298,7 @@ char *script;
|
|||
op++;
|
||||
if (*op!='"') {
|
||||
float fv;
|
||||
fv=CharToDouble(op);
|
||||
fv=CharToFloat(op);
|
||||
fvalues[nvars]=fv;
|
||||
vtypes[vars].bits.is_string=0;
|
||||
if (!vtypes[vars].bits.is_filter) vtypes[vars].index=nvars;
|
||||
|
@ -670,7 +670,7 @@ char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,Jso
|
|||
|
||||
if (isdigit(*lp) || (*lp=='-' && isdigit(*(lp+1))) || *lp=='.') {
|
||||
// isnumber
|
||||
if (fp) *fp=CharToDouble(lp);
|
||||
if (fp) *fp=CharToFloat(lp);
|
||||
if (*lp=='-') lp++;
|
||||
while (isdigit(*lp) || *lp=='.') {
|
||||
if (*lp==0 || *lp==SCRIPT_EOL) break;
|
||||
|
@ -839,7 +839,7 @@ char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,Jso
|
|||
return lp+len;
|
||||
}
|
||||
} else {
|
||||
if (fp) *fp=CharToDouble((char*)str_value);
|
||||
if (fp) *fp=CharToFloat((char*)str_value);
|
||||
*vtype=NUM_RES;
|
||||
tind->bits.constant=1;
|
||||
tind->bits.is_string=0;
|
||||
|
@ -2266,7 +2266,7 @@ int16_t Run_Scripter(const char *type, uint8_t tlen, char *js) {
|
|||
// mismatch was string, not number
|
||||
// get the string and convert to number
|
||||
lp=isvar(slp,&vtype,&ind,0,cmpstr,jo);
|
||||
fvar=CharToDouble(cmpstr);
|
||||
fvar=CharToFloat(cmpstr);
|
||||
}
|
||||
switch (lastop) {
|
||||
case OPER_EQU:
|
||||
|
@ -2398,7 +2398,7 @@ int16_t Run_Scripter(const char *type, uint8_t tlen, char *js) {
|
|||
*dfvar=fparam;
|
||||
} else {
|
||||
// mismatch
|
||||
*dfvar=CharToDouble(cmpstr);
|
||||
*dfvar=CharToFloat(cmpstr);
|
||||
}
|
||||
} else {
|
||||
// string result
|
||||
|
|
|
@ -1030,7 +1030,7 @@ bool KnxCommand(void)
|
|||
while ( i != KNX_Empty ) {
|
||||
KNX_addr.value = Settings.knx_GA_addr[i];
|
||||
|
||||
float tempvar = CharToDouble(XdrvMailbox.data);
|
||||
float tempvar = CharToFloat(XdrvMailbox.data);
|
||||
dtostrfd(tempvar,2,XdrvMailbox.data);
|
||||
|
||||
knx.write_2byte_float(KNX_addr, tempvar);
|
||||
|
|
|
@ -287,17 +287,17 @@ bool HlwCommand(void)
|
|||
}
|
||||
else if (CMND_POWERSET == energy_command_code) {
|
||||
if (XdrvMailbox.data_len && hlw_cf_power_pulse_length) {
|
||||
Settings.energy_power_calibration = ((unsigned long)(CharToDouble(XdrvMailbox.data) * 10) * hlw_cf_power_pulse_length) / hlw_power_ratio;
|
||||
Settings.energy_power_calibration = ((unsigned long)(CharToFloat(XdrvMailbox.data) * 10) * hlw_cf_power_pulse_length) / hlw_power_ratio;
|
||||
}
|
||||
}
|
||||
else if (CMND_VOLTAGESET == energy_command_code) {
|
||||
if (XdrvMailbox.data_len && hlw_cf1_voltage_pulse_length) {
|
||||
Settings.energy_voltage_calibration = ((unsigned long)(CharToDouble(XdrvMailbox.data) * 10) * hlw_cf1_voltage_pulse_length) / hlw_voltage_ratio;
|
||||
Settings.energy_voltage_calibration = ((unsigned long)(CharToFloat(XdrvMailbox.data) * 10) * hlw_cf1_voltage_pulse_length) / hlw_voltage_ratio;
|
||||
}
|
||||
}
|
||||
else if (CMND_CURRENTSET == energy_command_code) {
|
||||
if (XdrvMailbox.data_len && hlw_cf1_current_pulse_length) {
|
||||
Settings.energy_current_calibration = ((unsigned long)(CharToDouble(XdrvMailbox.data)) * hlw_cf1_current_pulse_length) / hlw_current_ratio;
|
||||
Settings.energy_current_calibration = ((unsigned long)(CharToFloat(XdrvMailbox.data)) * hlw_cf1_current_pulse_length) / hlw_current_ratio;
|
||||
}
|
||||
}
|
||||
else serviced = false; // Unknown command
|
||||
|
|
|
@ -225,17 +225,17 @@ bool CseCommand(void)
|
|||
|
||||
if (CMND_POWERSET == energy_command_code) {
|
||||
if (XdrvMailbox.data_len && power_cycle) {
|
||||
Settings.energy_power_calibration = (unsigned long)(CharToDouble(XdrvMailbox.data) * power_cycle) / CSE_PREF;
|
||||
Settings.energy_power_calibration = (unsigned long)(CharToFloat(XdrvMailbox.data) * power_cycle) / CSE_PREF;
|
||||
}
|
||||
}
|
||||
else if (CMND_VOLTAGESET == energy_command_code) {
|
||||
if (XdrvMailbox.data_len && voltage_cycle) {
|
||||
Settings.energy_voltage_calibration = (unsigned long)(CharToDouble(XdrvMailbox.data) * voltage_cycle) / CSE_UREF;
|
||||
Settings.energy_voltage_calibration = (unsigned long)(CharToFloat(XdrvMailbox.data) * voltage_cycle) / CSE_UREF;
|
||||
}
|
||||
}
|
||||
else if (CMND_CURRENTSET == energy_command_code) {
|
||||
if (XdrvMailbox.data_len && current_cycle) {
|
||||
Settings.energy_current_calibration = (unsigned long)(CharToDouble(XdrvMailbox.data) * current_cycle) / 1000;
|
||||
Settings.energy_current_calibration = (unsigned long)(CharToFloat(XdrvMailbox.data) * current_cycle) / 1000;
|
||||
}
|
||||
}
|
||||
else serviced = false; // Unknown command
|
||||
|
|
|
@ -604,7 +604,7 @@ bool McpCommand(void)
|
|||
|
||||
if (CMND_POWERSET == energy_command_code) {
|
||||
if (XdrvMailbox.data_len && mcp_active_power) {
|
||||
value = (unsigned long)(CharToDouble(XdrvMailbox.data) * 100);
|
||||
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 100);
|
||||
if ((value > 100) && (value < 200000)) { // Between 1W and 2000W
|
||||
Settings.energy_power_calibration = value;
|
||||
mcp_calibrate |= MCP_CALIBRATE_POWER;
|
||||
|
@ -614,7 +614,7 @@ bool McpCommand(void)
|
|||
}
|
||||
else if (CMND_VOLTAGESET == energy_command_code) {
|
||||
if (XdrvMailbox.data_len && mcp_voltage_rms) {
|
||||
value = (unsigned long)(CharToDouble(XdrvMailbox.data) * 10);
|
||||
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 10);
|
||||
if ((value > 1000) && (value < 2600)) { // Between 100V and 260V
|
||||
Settings.energy_voltage_calibration = value;
|
||||
mcp_calibrate |= MCP_CALIBRATE_VOLTAGE;
|
||||
|
@ -624,7 +624,7 @@ bool McpCommand(void)
|
|||
}
|
||||
else if (CMND_CURRENTSET == energy_command_code) {
|
||||
if (XdrvMailbox.data_len && mcp_current_rms) {
|
||||
value = (unsigned long)(CharToDouble(XdrvMailbox.data) * 10);
|
||||
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 10);
|
||||
if ((value > 100) && (value < 80000)) { // Between 10mA and 8A
|
||||
Settings.energy_current_calibration = value;
|
||||
mcp_calibrate |= MCP_CALIBRATE_CURRENT;
|
||||
|
@ -634,7 +634,7 @@ bool McpCommand(void)
|
|||
}
|
||||
else if (CMND_FREQUENCYSET == energy_command_code) {
|
||||
if (XdrvMailbox.data_len && mcp_line_frequency) {
|
||||
value = (unsigned long)(CharToDouble(XdrvMailbox.data) * 1000);
|
||||
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 1000);
|
||||
if ((value > 45000) && (value < 65000)) { // Between 45Hz and 65Hz
|
||||
Settings.energy_frequency_calibration = value;
|
||||
mcp_calibrate |= MCP_CALIBRATE_FREQUENCY;
|
||||
|
|
|
@ -184,7 +184,7 @@ bool Ade7953Command(void)
|
|||
{
|
||||
bool serviced = true;
|
||||
|
||||
uint32_t value = (uint32_t)(CharToDouble(XdrvMailbox.data) * 100); // 1.23 = 123
|
||||
uint32_t value = (uint32_t)(CharToFloat(XdrvMailbox.data) * 100); // 1.23 = 123
|
||||
|
||||
if (CMND_POWERCAL == energy_command_code) {
|
||||
if (1 == XdrvMailbox.payload) { XdrvMailbox.payload = ADE7953_PREF; }
|
||||
|
|
|
@ -151,7 +151,7 @@ bool AdcCommand(void)
|
|||
// Settings.adc_param_type = my_adc0;
|
||||
Settings.adc_param1 = strtol(subStr(sub_string, XdrvMailbox.data, ",", 2), nullptr, 10);
|
||||
Settings.adc_param2 = strtol(subStr(sub_string, XdrvMailbox.data, ",", 3), nullptr, 10);
|
||||
Settings.adc_param3 = (int)(CharToDouble(subStr(sub_string, XdrvMailbox.data, ",", 4)) * 10000);
|
||||
Settings.adc_param3 = (int)(CharToFloat(subStr(sub_string, XdrvMailbox.data, ",", 4)) * 10000);
|
||||
} else { // Set default values based on current adc type
|
||||
// AdcParam 2
|
||||
// AdcParam 3
|
||||
|
|
|
@ -204,7 +204,7 @@ bool HxCommand(void)
|
|||
break;
|
||||
case 6: // WeightItem
|
||||
if (strstr(XdrvMailbox.data, ",") != nullptr) {
|
||||
Settings.weight_item = (unsigned long)(CharToDouble(subStr(sub_string, XdrvMailbox.data, ",", 2)) * 10);
|
||||
Settings.weight_item = (unsigned long)(CharToFloat(subStr(sub_string, XdrvMailbox.data, ",", 2)) * 10);
|
||||
}
|
||||
show_parms = true;
|
||||
break;
|
||||
|
@ -444,7 +444,7 @@ void HandleHxAction(void)
|
|||
|
||||
if (WebServer->hasArg("calibrate")) {
|
||||
WebGetArg("p1", stemp1, sizeof(stemp1));
|
||||
Settings.weight_reference = (!strlen(stemp1)) ? 0 : (unsigned long)(CharToDouble(stemp1) * 1000);
|
||||
Settings.weight_reference = (!strlen(stemp1)) ? 0 : (unsigned long)(CharToFloat(stemp1) * 1000);
|
||||
|
||||
HxLogUpdates();
|
||||
|
||||
|
@ -471,7 +471,7 @@ void HxSaveSettings(void)
|
|||
char tmp[100];
|
||||
|
||||
WebGetArg("p2", tmp, sizeof(tmp));
|
||||
Settings.weight_item = (!strlen(tmp)) ? 0 : (unsigned long)(CharToDouble(tmp) * 10000);
|
||||
Settings.weight_item = (!strlen(tmp)) ? 0 : (unsigned long)(CharToFloat(tmp) * 10000);
|
||||
|
||||
HxLogUpdates();
|
||||
}
|
||||
|
|
|
@ -182,7 +182,7 @@ void AzEverySecond(void)
|
|||
return;
|
||||
}
|
||||
response_substr[j] = 0; // add null terminator
|
||||
az_temperature = CharToDouble((char*)response_substr); // units (C or F) depends on meter setting
|
||||
az_temperature = CharToFloat((char*)response_substr); // units (C or F) depends on meter setting
|
||||
if(az_response[i] == 'C') { // meter transmits in degC
|
||||
az_temperature = ConvertTemp((float)az_temperature); // convert to degF, depending on settings
|
||||
} else { // meter transmits in degF
|
||||
|
@ -232,7 +232,7 @@ void AzEverySecond(void)
|
|||
return;
|
||||
}
|
||||
response_substr[j] = 0; // add null terminator
|
||||
az_humidity = ConvertHumidity(CharToDouble((char*)response_substr));
|
||||
az_humidity = ConvertHumidity(CharToFloat((char*)response_substr));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue