Вывести 2 числа, хранящиеся в 24-битном формате, в десятичном формате.

Функция реализации из миленькой библиотеки Wiegand YetAnotherArduinoWiegandLibrary выводит шестнадцатеричное представление объекта # & номер карты (8-битный номер объекта, 16-битный номер карты) — 24 бита 26-битного потока, который проходит по сети.

Пример закодированного 24-битного числа: 7111097 (десятичное). Шестнадцатеричный эквивалент: 6C81B9. Часть 6C — номер объекта (десятичный: 108). 81B9 — номер карты (десятичное число 33209).

Эта функция из примера использования библиотеки serial печатает число в шестнадцатеричном формате:

void receivedData(uint8_t* data, uint8_t bits, const char* message) {
    Serial.print(message);
    Serial.print(bits);
    Serial.print("bits / ");
    //Напечатать значение в HEX
    uint8_t bytes = (bits+7)/8;
    for (int i=0; i<bytes; i++) {
        Serial.print(data[i] >> 4, 16);  //1-я, 3-я, 5-я шестнадцатеричная цифра
        Serial.print(data[i] & 0xF, 16); //2-я, 4-я, 6-я шестнадцатеричная цифра
    }
    Serial.println();
}

До сих пор я безуспешно пытался перебрать биты, чтобы также последовательно напечатать два десятичных отформатированных числа (facility:card) в окончательной выходной форме: 108:33209

, 👍1

Обсуждение

зачем вам нужно «зацикливать биты»? ... цикл for уже манипулирует байтами данных, @jsotola

@jsotola С циклом for или без него, как вывести два отдельных логических числа в десятичном формате?, @micahwittman

как преобразовать 3 байта в одно число? .... подумайте об этом ... какой математический процесс вы используете, чтобы преобразовать 4 сотни, 6 десятков и 8 единиц в 468?, @jsotola

Интересно, почему этот пример кода печатает каждый кусочек байта отдельно? Разве Serial.print(255, 16); не выводит FF? Так что не могла ли внутренняя часть цикла for просто прочитать `Serial.print(data[i], 16]);, @Duncan C


1 ответ


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

2

Ваш код повторяется от старшего байта к младшему байту, печатая каждый байт как 2 шестнадцатеричных цифры.

Если вы хотите напечатать первый байт как десятичное значение, а затем остальные байты как другое десятичное значение, сделайте следующее:

Вывести байт 0 по основанию 10:

    Serial.print(data[0]);  // первый байт
    Serial.print(":");

Затем прокрутите оставшиеся байты, создав результат в виде десятичного значения, и напечатайте его:

unsigned long total = 0;
for (int i=1; i<bytes; i++) //Пропустить первый байт
{
    total = total << 8;  //Сдвиг предыдущей суммы на 8 бит.
                         //(То же самое, что и умножение на 256, но быстрее)
    total += data[i];    //Добавить новое значение
}
Serial.println(total);

Приведенный вами пример кода написан для обработки переменного количества байтов. Приведенный выше код делает то же самое с десятичными результатами. Гораздо проще, если вы знаете, что у вас всегда будет 3 байта или 4 байта:

Для 3 байтов:

    Serial.print(data[0]);  // первый байт
    Serial.print(":");
    long total = long(data[1])*256 + data[2]);
    Serial.println(long(total); 
,

Я написал вторую версию кода, используя длинные целые числа, поскольку я начал с вывода 8-битного значения, за которым следовало 24-битное значение. Если второе значение составляет всего 2 байта (16 бит), вы можете изменить тип данных на «unsigned int»., @Duncan C

Это здорово и имеет смысл для меня, спасибо., @micahwittman