Преобразовать Int в HEX, HEX в строку и в байт? Общая проблема конвертации
Поскольку Cpp не является моим основным языком, я изо всех сил пытаюсь найти лучший способ преобразования между типами для моих нужд. Итак, моя отправная точка
struct can_frame {
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
__u8 can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
__u8 data[CAN_MAX_DLEN] __attribute__((aligned(8)));
};
Итак, сначала мне нужно было отправить его в Serial в виде шестнадцатеричной строки, поэтому решение, которое я нашел и использовал, было
String frame = "CAN:";
char dataString[1] = {0};
sprintf(dataString, "%03X", can1Msg.can_id);
frame += dataString;
for (int i = 0; i < can1Msg.can_dlc; i++) { // вывести данные
char dataString[1] = {0};
sprintf(dataString, "%02X", can1Msg.data[i]);
frame += " " + String(dataString);
}
Выглядит не очень элегантно, потому что работает.
Но затем мне нужно было проверить идентификатор и определенные байты
Итак, я сохранил все String ins String bytes[8]
Итак, теперь я мог бы что-то вроде
if (id == "2A0" && bytes[0] == "A0") {
И это было почти закончено, но потом я понял, что мне нужно сделать некоторую проверку целого числа, которое сохраняется на 3 байта.
Например, byte[2] + byte[3] + byte[4]
, что-то вроде 0020A0
, которое будет 8352
как Int
Но преобразование вещей вызвало все проблемы, такие как String to const char*
и т. д.
Я хотел преобразовать __u8
в массив байтов, чтобы я мог выполнять проверки и преобразования и в конечном итоге преобразовать его в строку, но мне это не удалось.
Может ли кто-нибудь предложить лучший подход для этого?
@uneasy, 👍-2
Обсуждение1 ответ
Лучший ответ:
Основная проблема, с которой вы столкнулись, — непонимание того, что такое "шестнадцатеричный", "байтовый" и т. п.
Вы пытаетесь работать с четырьмя типами данных (целое, шестнадцатеричное, строковое и байтовое), хотя на самом деле существует только два типа: строковый и двоичный. Все остальное — это просто представление, которое мы, люди, используем для облегчения понимания двоичных данных.
У вас есть "источник" тип (can1Msg.data
), который одновременно является двоичным, целым, шестнадцатеричным и байтовым. Единственное, чем он не является, это String
, и вы создаете его вручную с помощью вызовов sprintf
.
Чтобы сравнить третью "шестнадцатеричную пару" значение в ваших данных, вы просто:
if (can1Msg.data[2] == 0x42) { ...
То есть сравните 8-битное двоичное значение, хранящееся в фрагменте массива 2 (массивы отсчитываются от 0, поэтому 2 – третья запись), с двоичным значением, представленным шестнадцатеричным представлением 42. То же самое можно сделать с помощью:
if (can1Msg.data[2] == 66) { ...
66 — это десятичный (с основанием 10) эквивалент 0x42. Вы также можете использовать двоичный или восьмеричный формат. Эти два также точно такие же:
if (can1Msg.data[2] == 0102) { ... // восьмеричное число
if (can1Msg.data[2] == 0b01000010) { ... // двоичный
Если вам нужно проверить группы байтов, например, если у вас есть два байта, которые образуют 16-битное целое число, вы просто объединяете эти два байта в целое число, соблюдая правильный порядок байтов значений. Например, если у вас есть 16-битное целое число, которое хранится как can1Msg.data[7]
и can1Msg.data[8]
в формате big endian можно использовать:
uint16_t val = (can1Msg.data[7] << 8) | can1Msg.data[8];
Затем просто сравните числовое (двоичное) целое значение по желанию. Все, что делает эта строка, это берет первое 8-битное значение и "shift" это 8 бит влево, чтобы сделать его 16-битным значением с младшими 8 битами, установленными на 0, затем наложить второе значение на эти младшие 8 нулей, чтобы сделать его одним 16-битным значением.
Большое спасибо. Моя ошибка заключалась в том, что я почему-то предположил, что то, что у меня есть в данных, не является байтом и в голове засело, что мне нужно преобразовать это в байт., @uneasy
- Как объявить массив переменного размера (глобально)
- Программирование Arduino с использованием Python, а не C/C ++
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Как справиться с rollover millis()?
- Является ли использование malloc() и free() действительно плохой идеей для Arduino?
- Можно ли сделать несколько функций loop() с помощью Arduino Uno?
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- устаревшее преобразование из строковой константы в 'char*'
Обратите внимание, что вы переполняете массивы
dataString
из 1 ячейки. Вероятно, это портит часть вашей памяти., @Edgar Bonet