From 31d1add07e1a7ad721a03b9be9d763b493c331c2 Mon Sep 17 00:00:00 2001 From: Tom Kooij Date: Fri, 30 Dec 2022 16:56:18 +0100 Subject: [PATCH] Raw bytes can be signed or unsigned. Cast "signed raw bytes" to signed integer first, before casting to float and applying a divider. Example: datatype = 0x92 (1-0-010-010) datatype & 0x80 (bit 8) => signed value datatype & 0x38 (bits 654) => length => 2 bytes datatype & 0x07 (bits 321) => divider => 2 datatype 0x92 value 0xFC18 datatype signed, length 2, divider 2. signed int value -1000: value -10.00 --- software/NRG_itho_wifi/src/IthoSystem.cpp | 44 ++++++++++++++++------- software/NRG_itho_wifi/src/IthoSystem.h | 2 ++ 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/software/NRG_itho_wifi/src/IthoSystem.cpp b/software/NRG_itho_wifi/src/IthoSystem.cpp index 5611fd4b..1501135f 100644 --- a/software/NRG_itho_wifi/src/IthoSystem.cpp +++ b/software/NRG_itho_wifi/src/IthoSystem.cpp @@ -711,6 +711,14 @@ void sendQueryStatusFormat(bool updateweb) } else { + if ((i2cbuf[6 + i] & 0x80) == 0) + { // unsigned value + ithoStatus.back().is_signed = false; + } + else + { + ithoStatus.back().is_signed = true; + } ithoStatus.back().type = ithoDeviceStatus::is_float; ithoStatus.back().divider = quick_pow10((i2cbuf[6 + i] & 0x07)); } @@ -732,6 +740,7 @@ void sendQueryStatusFormat(bool updateweb) if (i2cbuf[6 + i] == 0x0F) { ithoStatus.back().type = ithoDeviceStatus::is_float; + ithoStatus.back().is_signed = false; ithoStatus.back().length = 1; ithoStatus.back().divider = 2; } @@ -818,18 +827,9 @@ void sendQueryStatus(bool updateweb) } if (ithoStat.type == ithoDeviceStatus::is_int) { - if (ithoStat.length == 4) - { - tempVal = static_cast(tempVal); - } - if (ithoStat.length == 2) - { - tempVal = static_cast(tempVal); - } - if (ithoStat.length == 1) - { - tempVal = static_cast(tempVal); - } + + tempVal = cast_to_signed_int(tempVal, ithoStat.length); + if (ithoStat.value.intval == tempVal) { ithoStat.updated = 0; @@ -842,6 +842,7 @@ void sendQueryStatus(bool updateweb) } if (ithoStat.type == ithoDeviceStatus::is_float) { + double t = ithoStat.value.floatval * ithoStat.divider; if (static_cast(t) == tempVal) // better compare needed of float val, worst case this will result in an extra update of the value, so limited impact { @@ -850,6 +851,11 @@ void sendQueryStatus(bool updateweb) else { ithoStat.updated = 1; + if (ithoStat.is_signed) + { + // interpret raw bytes as signed integer + tempVal = cast_to_signed_int(tempVal, ithoStat.length); + } ithoStat.value.floatval = static_cast(tempVal) / ithoStat.divider; } } @@ -1789,3 +1795,17 @@ std::string i2cbuf2string(const uint8_t *data, size_t len) } return s; } + +int cast_to_signed_int(int val, int length) +{ + switch (length) { + case 4: + return static_cast(val); + case 2: + return static_cast(val); + case 1: + return static_cast(val); + default: + return 0; + } +} \ No newline at end of file diff --git a/software/NRG_itho_wifi/src/IthoSystem.h b/software/NRG_itho_wifi/src/IthoSystem.h index d8516c59..577fbe99 100644 --- a/software/NRG_itho_wifi/src/IthoSystem.h +++ b/software/NRG_itho_wifi/src/IthoSystem.h @@ -59,6 +59,7 @@ struct ithoDeviceStatus } value; uint32_t divider; uint8_t updated; + bool is_signed; // used for floats only ithoDeviceStatus() : updated(0){}; }; @@ -146,3 +147,4 @@ void filterReset(); void IthoPWMcommand(uint16_t value, volatile uint16_t *ithoCurrentVal, bool *updateIthoMQTT); int quick_pow10(int n); std::string i2cbuf2string(const uint8_t *data, size_t len); +int cast_to_signed_int(int val, int length);