compress data with 8-4-2-1-BCD-Code

Hello I would like to optimise a few values for transmission via radio (LoRa) beforehand. I have a sensor number (1-255), temperature (00.00-99.99) and humidity. (00.00-99.99) I would like to transmit this data compressed as a byte array. I have already calculated that I need 5 bytes via BCD for this.

How do I get my numbers mapped into the respective byte?

``````float temperature = 24.12;
float humidity = 60.12;
byte message[5];

void setup() {
Serial.begin(9600);
message[0] = 12; //sensor id 12
}

void loop() {
float temperature1 = floor(temperature);
float temperature2 = (temperature - temperature1) * 100;
Serial.println(temperature1, 0);
Serial.println(temperature2, 0);
message[1] //?? temperature1
message[2] //?? temperature2

float humidity1 = floor(humidity);
float humidity2 = (humidity - humidity1) * 100;
message[3] //?? humidity1
message[4] //?? humidity2
}
``````
• how many sensors do you have? Commented Aug 24, 2022 at 0:45
• Why do you want to use BCD? Binary values are much simpler to handle for any processor (and have a wider range). Commented Sep 6, 2022 at 6:40
• @thebusybee the benefit lies in the smaller package that has to be transmitted via Lora. There are strict limits here Commented Sep 6, 2022 at 20:37
• I don't grasp what you mean by "smaller package". Binary values are as small as BCD, and have a wider range at the same time. Some might say that binary values are even smaller than BCD, but this is only true if you can use arbitrary bit numbers. For example, a value range of 0000 to 9999 needs 16 bits in BCD, but only 14 bits as binary value. -- However, you accepted an answer that uses binary values. Commented Sep 7, 2022 at 6:15

Why don't you use the following mapping:

1 byte: sensor number (0-255)

2 bytes: temperature (0-65535) by mapping the temperature to

``````(int) (65536.0 * (temperature / 100.0))
``````

2 bytes: humidity (0-65535) by mapping the humidity to

``````(int) (65536.0 * (humidity / 100.0))
``````

You will lose a little bit of accuracy for the temperature and humidity. If you know ranges in which the temperature/humidity will be, you can get a better accuracy.

``````message[0] = 12; // Sensor id 12
message[1] = highByte(temperature);
message[2] = lowByte(temperature);
message[3] = highByte(humidity);
message[4] = lowByte(humidity);
``````

Note if you have multiple sensors and have to transmit them all, you don't need to send the sensor number, send in bytes 0..3 the temperature/humidity for sensor 0, in bytes 4..7 the temperature/humidity for sensor 1 etc.

• like this? int payload = int(65536.0 * (humidity / 100.0)); message[1] = highByte(payload); message[2] = lowByte(payload); Commented Aug 23, 2022 at 21:05
• @TomBaires Something like that, I updated my answer Commented Aug 23, 2022 at 23:24

This is my final solution with BCD-Code

``````int temperature1 = int(floor(temperature));
int temperature2 = int(round((temperature - temperature1) * 100));
uint8_t bcdTemperature1 = uint8_t((temperature1/10) <<4) | (temperature1 %10);
uint8_t bcdTemperature2 = uint8_t((temperature2/10) <<4) | (temperature2 %10);

message[0] = moduleUniqueidentifier;
message[1] = bcdTemperature1;
message[2] = bcdTemperature2;
message[3] = uint8_t(ceil(humidity));
``````