Back in 1986 in my second first year at the University of Canterbury I did “MATH131 Numerical Methods” which was a year of looking at why mathematics in FORTRAN, C, and Pascal sometimes didn’t return the result you were expecting…
While testing my GHI Electronics TinyCLR2 RAK Wireless RAK811 LoRaWAN client I noticed the temperature numbers didn’t quite match…


I have implemented my own Cayenne Low Power Payload encoder in C# based on the sample Mbed C code
uint8_t CayenneLPP::addTemperature(uint8_t channel, float celsius) { if ((cursor + LPP_TEMPERATURE_SIZE) > maxsize) { return 0; } int16_t val = celsius * 10; buffer[cursor++] = channel; buffer[cursor++] = LPP_TEMPERATURE; buffer[cursor++] = val >> 8; buffer[cursor++] = val; return cursor; }
My translation of that code to C#
public void TemperatureAdd(byte channel, float celsius) { if ((index + TemperatureSize) > buffer.Length) { throw new ApplicationException("TemperatureAdd insufficent buffer capacity"); } short val = (short)(celsius * 10); buffer[index++] = channel; buffer[index++] = (byte)DataType.Temperature; buffer[index++] = (byte)(val >> 8); buffer[index++] = (byte)val; }
After looking at the code I think the issues was most probably due to the representation of the constant 10(int32), 10.0(double), and 10.0f(single) . To confirm my theory I modified the client to send the temperature with the calculation done with three different constants.


After some trial and error I settled on this C# code for my decoder
public void TemperatureAdd(byte channel, float celsius) { if ((index + TemperatureSize) > buffer.Length) { throw new ApplicationException("TemperatureAdd insufficent buffer capacity"); } short val = (short)(celsius * 10.0f); buffer[index++] = channel; buffer[index++] = (byte)DataType.Temperature; buffer[index++] = (byte)(val >> 8); buffer[index++] = (byte)val; }
I don’t think this is specifically an issue with the TinyCLR V2 just with number type used for the constant.
Pingback: Cayenne Low Power Payload (LPP) Encoder | devMobile's blog