Skip to content

Commit

Permalink
Raw bytes can be signed or unsigned.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
tomkooij committed Dec 30, 2022
1 parent 9d2c186 commit 31d1add
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 12 deletions.
44 changes: 32 additions & 12 deletions software/NRG_itho_wifi/src/IthoSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -818,18 +827,9 @@ void sendQueryStatus(bool updateweb)
}
if (ithoStat.type == ithoDeviceStatus::is_int)
{
if (ithoStat.length == 4)
{
tempVal = static_cast<int32_t>(tempVal);
}
if (ithoStat.length == 2)
{
tempVal = static_cast<int16_t>(tempVal);
}
if (ithoStat.length == 1)
{
tempVal = static_cast<int8_t>(tempVal);
}

tempVal = cast_to_signed_int(tempVal, ithoStat.length);

if (ithoStat.value.intval == tempVal)
{
ithoStat.updated = 0;
Expand All @@ -842,6 +842,7 @@ void sendQueryStatus(bool updateweb)
}
if (ithoStat.type == ithoDeviceStatus::is_float)
{

double t = ithoStat.value.floatval * ithoStat.divider;
if (static_cast<uint32_t>(t) == tempVal) // better compare needed of float val, worst case this will result in an extra update of the value, so limited impact
{
Expand All @@ -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<double>(tempVal) / ithoStat.divider;
}
}
Expand Down Expand Up @@ -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<int32_t>(val);
case 2:
return static_cast<int16_t>(val);
case 1:
return static_cast<int8_t>(val);
default:
return 0;
}
}
2 changes: 2 additions & 0 deletions software/NRG_itho_wifi/src/IthoSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ struct ithoDeviceStatus
} value;
uint32_t divider;
uint8_t updated;
bool is_signed; // used for floats only
ithoDeviceStatus() : updated(0){};
};

Expand Down Expand Up @@ -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);

0 comments on commit 31d1add

Please sign in to comment.