Сжать данные с помощью кода 8-4-2-1-BCD

lora

Здравствуйте, я хотел бы заранее оптимизировать несколько значений для передачи по радио (LoRa). У меня есть номер датчика (1-255), температура (00.00-99.99) и влажность. (00.00-99.99) Я хотел бы передать эти данные, сжатые в виде массива байтов. Я уже подсчитал, что для этого мне нужно 5 байт через BCD.

Как мне сопоставить свои числа с соответствующим байтом?

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

void setup() {
  Serial.begin(9600);
  message[0] = 12; //идентификатор датчика 12
}

void loop() {
  float temperature1 = floor(temperature);
  float temperature2 = (temperature - temperature1) * 100;
  Serial.println(temperature1, 0);
  Serial.println(temperature2, 0);  
  message[1] //?? температура1
  message[2] //?? температура2

  float humidity1 = floor(humidity);
  float humidity2 = (humidity - humidity1) * 100;
  message[3] //?? влажность1
  message[4] //?? влажность2
}

, 👍1

Обсуждение

сколько у тебя датчиков?, @jsotola

Почему вы хотите использовать BCD? Двоичные значения гораздо проще обрабатывать для любого процессора (и имеют более широкий диапазон)., @the busybee

@thebusybee преимущество заключается в меньшем пакете, который должен быть передан через Lora. Здесь есть строгие ограничения, @Tom Baires

Я не понимаю, что вы подразумеваете под "меньшим пакетом". Двоичные значения столь же малы, как BCD, и в то же время имеют более широкий диапазон. Кто-то может сказать, что двоичные значения еще меньше, чем двоично-десятичные, но это верно только в том случае, если вы можете использовать произвольные битовые числа. Например, диапазон значений от 0000 до 9999 требует 16 бит в двоично-десятичном формате, но только 14 бит в двоичном формате. -- Однако вы приняли ответ, в котором используются двоичные значения., @the busybee


2 ответа


Лучший ответ:

1

Почему бы вам не использовать следующее сопоставление:

1 байт: номер датчика (0-255)

2 байта: температура (0-65535) путем сопоставления температуры с

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

2 байта: влажность (0-65535) путем сопоставления влажности с

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

Вы немного потеряете в точности температуры и влажности. Если вы знаете диапазоны, в которых будет находиться температура/влажность, вы сможете добиться большей точности.

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

Обратите внимание, если у вас есть несколько датчиков и вы должны передать их все, вам не нужно отправлять номер датчика, отправьте в байтах 0..3 температуру/влажность для датчика 0, в байтах 4..7 температуру /влажность для датчика 1 и т.д.

,

как это? int payload = int(65536.0 * (влажность/100.0)); сообщение [1] = highByte (полезная нагрузка); сообщение [2] = младший байт (полезная нагрузка);, @Tom Baires

@TomBaires Что-то в этом роде, я обновил свой ответ, @Michel Keijzers


0

Это мое окончательное решение с BCD-кодом

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));
,