diff --git a/zephcore/adapters/sensors/SimpleLPP.h b/zephcore/adapters/sensors/SimpleLPP.h index 441c1c4..96628d5 100644 --- a/zephcore/adapters/sensors/SimpleLPP.h +++ b/zephcore/adapters/sensors/SimpleLPP.h @@ -22,8 +22,8 @@ #define LPP_TEMPERATURE 103 /* 2 bytes, 0.1°C signed */ #define LPP_RELATIVE_HUMIDITY 104 /* 1 byte, 0.5% unsigned */ #define LPP_BAROMETRIC_PRESSURE 115 /* 2 bytes, 0.1 hPa unsigned */ -#define LPP_VOLTAGE 116 /* 2 bytes, 0.01V unsigned */ -#define LPP_CURRENT 117 /* 2 bytes, 0.001A unsigned */ +#define LPP_VOLTAGE 116 /* 2 bytes, 0.01V signed */ +#define LPP_CURRENT 117 /* 2 bytes, 0.001A signed */ #define LPP_ALTITUDE 121 /* 2 bytes, 1m signed */ #define LPP_POWER 128 /* 2 bytes, 1W unsigned */ #define LPP_DISTANCE 130 /* 4 bytes, 0.001m unsigned */ @@ -131,19 +131,26 @@ public: * @return Number of bytes written, or 0 on overflow */ uint8_t addVoltage(uint8_t channel, float volts) { - uint16_t val = (uint16_t)(volts * LPP_VOLTAGE_MULT); - return addField2Unsigned(channel, LPP_VOLTAGE, val); + int16_t val = (int16_t)(volts * LPP_VOLTAGE_MULT); + return addField2Signed(channel, LPP_VOLTAGE, val); } /** * Add current reading + * + * Type 117 is signed in CayenneLPP (and in Arduino MeshCore, which uses + * the reference encoder), so a bidirectional monitor like the INA219 can + * report discharge as a negative value. Casting a negative float to an + * unsigned type is UB and saturates to 0 on the FPU, which silently + * reported 0 mA on every discharging node. + * * @param channel Channel number - * @param amps Current in amperes + * @param amps Current in amperes (negative = reverse flow) * @return Number of bytes written, or 0 on overflow */ uint8_t addCurrent(uint8_t channel, float amps) { - uint16_t val = (uint16_t)(amps * LPP_CURRENT_MULT); - return addField2Unsigned(channel, LPP_CURRENT, val); + int16_t val = (int16_t)(amps * LPP_CURRENT_MULT); + return addField2Signed(channel, LPP_CURRENT, val); } /** diff --git a/zephcore/app/CompanionMesh.cpp b/zephcore/app/CompanionMesh.cpp index 874e984..241a930 100644 --- a/zephcore/app/CompanionMesh.cpp +++ b/zephcore/app/CompanionMesh.cpp @@ -1717,16 +1717,18 @@ int CompanionMesh::appendSelfTelemetry(uint8_t *reply, uint8_t permissions) uint8_t ch = CH_SELF + 1; for (int j = 0; j < pwr.num_channels; j++) { if (pwr.channels[j].valid) { - // Voltage: [ch][LPP_VOLTAGE=116][2-byte 0.01V] + // Voltage: [ch][LPP_VOLTAGE=116][2-byte 0.01V signed] reply[i++] = ch; reply[i++] = 116; - uint16_t v = (uint16_t)(pwr.channels[j].voltage_v * 100); + int16_t v = (int16_t)(pwr.channels[j].voltage_v * 100); reply[i++] = (v >> 8) & 0xFF; reply[i++] = v & 0xFF; - // Current: [ch][LPP_CURRENT=117][2-byte 0.001A] + // Current: [ch][LPP_CURRENT=117][2-byte 0.001A signed] + // Signed: a bidirectional monitor (INA219) reports discharge + // as negative, and an unsigned cast saturates it to 0. reply[i++] = ch; reply[i++] = 117; - uint16_t c = (uint16_t)(pwr.channels[j].current_a * 1000); + int16_t c = (int16_t)(pwr.channels[j].current_a * 1000); reply[i++] = (c >> 8) & 0xFF; reply[i++] = c & 0xFF; // Power: [ch][LPP_POWER=128][2-byte 1W]