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:
float temp1
float temp2
float temp3
int16_t temp4
float volt1
float volt2
float volt3
float volt4
int8_t switch
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)
if you want to use the same packet format in the U.S. and the EU, and you want to support DR0 in both regions, the maximum payload length for any packet would be 11 bytes (the U.S. limit for DR0)
I guess I didn't ever need to know that because I'm in Europe (geographically but unfortunately not politically ).
you are thinking of Sigfox (max uplink 12bytes max downlink 8bytes)
I think LoRaWAN can be up to 250 bytes
however, it is recommended to send as few bytes as possible so don't transmit ASCII text (I have heard of people attempting to transmit JSON!)
if possible encode your float values into 8bit bytes (unsigned 0 to 255 signed -128 to 127) or 16bit ints (unsigned 65535 signed -32768 to 32767) - at the LoRaWAN server you convert back to floats using the payload formatter, e.g.
function decodeUplink(input) {
var data = {};
data.Cycles= input.bytes[0];
data.unitON= input.bytes[1];
data.unitOFF= input.bytes[2];
data.data1= input.bytes[3]*10;
data.temp= input.bytes[4]*10;
data.pressure= input.bytes[5]*10;
data.humidity= input.bytes[6]*10;
return {
data: data,
warnings: warnings
};
}
Unfortunately yes, voltages are measured at different types of batteries, standard lead acid but also LiFe.
And their condition can be checked by analyzing their voltage precisely.
Temperatures, are less important and could be without decimal part, but it would be nice to have them with decimal precision 0.1 °C
how often are you transmitting?
in a recent project I was transmitting 12 bytes every 10 minutes which was well within the recommended limits - have a look at LoRaWAN fair use policy
Perhaps you could have 2 (or more) packet formats: sometimes you send just "coarse" data - which takes fewer bits - and sometimes you send the full precision.
Remember that sending more bits also consumes more power...