Sorry for writing in "bad’ English, I’m living in the Flemish speaking part of Belgium.
I’m looking for an algorithm to compress data in as less bytes as possible to send them by LoRaWAN.
Of course, I also have to reconstruct the original data.
The data I have to send consists of:
3 temperatures ranging from -25.0 °C to 99.0 °C (with .1 decimal precision)
1 temperature ranging from -25 °C to 999 °C (with no decimals)
4 voltages ranging from 0.0 to 25.0 volt (with .1 decimal precision)
8 switch states (can be combined in 1 byte)
The code to retrieve these values is already written and uses the following variables:
What is the best practice to send these values in as less bytes as possible (I think LoRaWAN payload is max 12 bytes)
I was thinking:
multiplying the voltage floats by 10 to get rid of the decimal part, so they fit in an int8_t
adding 100 to the temp floats to get rid of the negative sign, then multiplying by 100 to fit in an int16_t (2 bytes)
No, the LoRaWAN max user payload size depends on the Spreading Factor (SF). E.g., even in the worst possible SF 12 in EU868, the max payload size is still 51 bytes (source).
INT8 has a range of -128 to +127. If you have a voltage range of -25.0 to 99.0 with .1 decimal precision, multiplying by 10 would give the integer numbers -250 to 990 (representing -25.0 and 99.0 each). Neither -250 nor 990 fit in a INT8 anymore. In fact, for that voltage range and precision, you have 1 + (99 - (-25)) * 10 = 1 + 1240 = 1241 possible values (+1 for the representation of 0). The number of bits that these number of possible values needs to be saved is ceil ( log_2( num_values) ), and ceil( log_2(1241)) = ceil(10.27) = 11 (bits). That is no standard size (the next one would be 16 bits), but still you can write an algorithm that converts the given temperature to an 11-bit bitstring and writes it into a continuous series of bits. Meaning there’s something like