Merge pull request #6181 from s-hadinger/tuya_no_float

Removed float conversion and used changeUIntScale instead
This commit is contained in:
Theo Arends 2019-08-05 15:21:13 +02:00 committed by GitHub
commit f2d01949c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 50 deletions

View File

@ -371,3 +371,40 @@ float sqrt1(const float x)
return u.x; return u.x;
} }
//
// changeUIntScale
// Change a value for range a..b to c..d, using only unsigned int math
//
// PRE-CONDITIONS (if not satisfied, you may 'halt and catch fire')
// from_min < from_max (not checked)
// to_min < to_max (not checked)
// from_min <= num <= from-max (chacked)
// POST-CONDITIONS
// to_min <= result <= to_max
//
uint16_t changeUIntScale(uint16_t inum, uint16_t ifrom_min, uint16_t ifrom_max,
uint16_t ito_min, uint16_t ito_max) {
// guard-rails
if ((ito_min >= ito_max) || (ifrom_min >= ifrom_max)) {
return ito_min; // invalid input, return arbitrary value
}
// convert to uint31, it's more verbose but code is more compact
uint32_t num = inum;
uint32_t from_min = ifrom_min;
uint32_t from_max = ifrom_max;
uint32_t to_min = ito_min;
uint32_t to_max = ito_max;
// check source range
num = (num > from_max ? from_max : (num < from_min ? from_min : num));
uint32_t numerator = (num - from_min) * (to_max - to_min);
uint32_t result;
if (numerator >= 0x80000000L) {
// don't do rounding as it would create an overflow
result = numerator / (from_max - from_min) + to_min;
} else {
result = (((numerator * 2) / (from_max - from_min)) + 1) / 2 + to_min;
}
return (uint32_t) (result > to_max ? to_max : (result < to_min ? to_min : result));
}

View File

@ -259,43 +259,6 @@ static uint32_t min3(uint32_t a, uint32_t b, uint32_t c) {
return (a < b && a < c) ? a : (b < c) ? b : c; return (a < b && a < c) ? a : (b < c) ? b : c;
} }
//
// changeUIntScale
// Change a value for range a..b to c..d, using only unsigned int math
//
// PRE-CONDITIONS (if not satisfied, you may 'halt and catch fire')
// from_min < from_max (not checked)
// to_min < to_max (not checked)
// from_min <= num <= from-max (chacked)
// POST-CONDITIONS
// to_min <= result <= to_max
//
uint16_t changeUIntScale(uint16_t inum, uint16_t ifrom_min, uint16_t ifrom_max,
uint16_t ito_min, uint16_t ito_max) {
// guard-rails
if ((ito_min >= ito_max) || (ifrom_min >= ifrom_max)) {
return ito_min; // invalid input, return arbitrary value
}
// convert to uint31, it's more verbose but code is more compact
uint32_t num = inum;
uint32_t from_min = ifrom_min;
uint32_t from_max = ifrom_max;
uint32_t to_min = ito_min;
uint32_t to_max = ito_max;
// check source range
num = (num > from_max ? from_max : (num < from_min ? from_min : num));
uint32_t numerator = (num - from_min) * (to_max - to_min);
uint32_t result;
if (numerator >= 0x80000000L) {
// don't do rounding as it would create an overflow
result = numerator / (from_max - from_min) + to_min;
} else {
result = (((numerator * 2) / (from_max - from_min)) + 1) / 2 + to_min;
}
return (uint32_t) (result > to_max ? to_max : (result < to_min ? to_min : result));
}
// //
// LightStateClass // LightStateClass
// This class is an abstraction of the current light state. // This class is an abstraction of the current light state.

View File

@ -146,9 +146,8 @@ void LightSerialDuty(uint8_t duty)
if (duty < 25) { duty = 25; } // dimming acts odd below 25(10%) - this mirrors the threshold set on the faceplate itself if (duty < 25) { duty = 25; } // dimming acts odd below 25(10%) - this mirrors the threshold set on the faceplate itself
if (Settings.flag3.tuya_show_dimmer == 0) { if (Settings.flag3.tuya_show_dimmer == 0) {
if(Settings.flag3.tuya_dimmer_range_255 == 0) if(Settings.flag3.tuya_dimmer_range_255 == 0) {
{ duty = changeUIntScale(duty, 0, 255, 0, 100);
duty = round(duty * (100. / 255.));
} }
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Send dim value=%d (id=%d)"), duty, Settings.param[P_TUYA_DIMMER_ID]); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Send dim value=%d (id=%d)"), duty, Settings.param[P_TUYA_DIMMER_ID]);
TuyaSendValue(Settings.param[P_TUYA_DIMMER_ID], duty); TuyaSendValue(Settings.param[P_TUYA_DIMMER_ID], duty);
@ -156,9 +155,8 @@ void LightSerialDuty(uint8_t duty)
} else { } else {
tuya_ignore_dim = false; // reset flag tuya_ignore_dim = false; // reset flag
if (Settings.flag3.tuya_show_dimmer == 0) { if (Settings.flag3.tuya_show_dimmer == 0) {
if(Settings.flag3.tuya_dimmer_range_255 == 0) if(Settings.flag3.tuya_dimmer_range_255 == 0) {
{ duty = changeUIntScale(duty, 0, 255, 0, 100);
duty = round(duty * (100. / 255.));
} }
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Send dim skipped value=%d"), duty); // due to 0 or already set AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Send dim skipped value=%d"), duty); // due to 0 or already set
} }
@ -217,13 +215,10 @@ void TuyaPacketProcess(void)
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Autoconfiguring Dimmer ID %d"), tuya_buffer[6]); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Autoconfiguring Dimmer ID %d"), tuya_buffer[6]);
Settings.param[P_TUYA_DIMMER_ID] = tuya_buffer[6]; Settings.param[P_TUYA_DIMMER_ID] = tuya_buffer[6];
} }
if(Settings.flag3.tuya_dimmer_range_255 == 0) if(Settings.flag3.tuya_dimmer_range_255 == 0) {
{ tuya_new_dim = (uint8_t) tuya_buffer[13];
tuya_new_dim = round(tuya_buffer[13]); } else {
} tuya_new_dim = changeUIntScale((uint8_t) tuya_buffer[13], 0, 255, 0, 100);
else
{
tuya_new_dim = round(tuya_buffer[13] * (100. / 255.));
} }
if ((power || Settings.flag3.tuya_apply_o20) && (tuya_new_dim > 0) && (abs(tuya_new_dim - Settings.light_dimmer) > 1)) { if ((power || Settings.flag3.tuya_apply_o20) && (tuya_new_dim > 0) && (abs(tuya_new_dim - Settings.light_dimmer) > 1)) {
tuya_ignore_dim = true; tuya_ignore_dim = true;