Преобразование строки c integer в unsigned char

Я пытаюсь разобраться с типами между двумя разными библиотеками.

Суть в том, что я использую библиотеку ArduinoWebsockets для получения информации, поступающей из моего api, которую я затем хочу отобразить на светодиодную матрицу. Пример сообщения будет выглядеть следующим образом:

1
2
4
8
16
32
64
128

Важно отметить, что данные здесь представляют собой список строковых версий чисел, а не целых чисел.

Т.е. если вы посмотрите на двоичную версию 1 из списка, то на самом деле это 110001, который является ascii-кодом для символа 1.

Это происходит потому, что сообщение, возвращающееся с сервера websocket, извлекается в виде const char *.

Функция светодиодной матрицы, которую я вызываю, имеет сигнатуру:

void Write_Max7219(unsigned char address, unsigned char dat)

Поэтому мне нужно отправить значения в виде символовбез знака.

Я хочу:

  • проанализируйте эту информацию построчно
  • преобразуйте символ ascii для числа в его целочисленный эквивалент
  • передайте значение другой функции, чтобы записать данные в светодиодную матрицу

И я не знаю, как именно это сделать. Я боролся с типом const char pointer против обычного указателя char и как правильно разобрать возвращаемую строку с разделителями.

Любая помощь будет очень признательна!!

Уточнение

Основываясь на некоторых комментариях, я не думаю, что объяснил причину, по которой я пытаюсь сделать это преобразование очень хорошо. Вот (надеюсь) лучшее объяснение:

Причина, по которой я хочу преобразовать его, заключается в том, что я не отображаю числовой символ в виде строки, я хочу использовать двоичное представление для управления огнями в строке матрицы.

Число 1 или 0b00000001 будет гореть только самый правый светодиод в 8-м ряду светодиодов матрицы.

Идея состоит в том, что я мог бы посылать строки чисел, где каждая строка соответствует строке на светодиодной матрице.

напр .

1   -> 0b00000001
2   -> 0b00000010
4   -> 0b00000100
8   -> 0b00001000
16  -> 0b00010000
32  -> 0b00100000
64  -> 0b01000000
128 -> 0b10000000

Но сообщения, которые я получаю от сервера websocket, поступают как строковые представления чисел (ascii или utf) и самих чисел, поэтому я не могу просто передать числа в функцию для светодиодной матрицы, потому что базовый двоичный файл отличается.

Преобразование заключается в том, что я могу использовать двоичное представление 1 (0b00000001) против двоичного представления '1' (00110001).

ОБНОВЛЕНИЕ И РАЗРЕШЕНИЕ

Итак, я отправился в большое путешествие по устранению неполадок. Когда @ocrdu сказал:

Кстати, я бы попытался заставить websocket отправлять правильные одиночные байты вместо строковых представлений чисел, если это вообще возможно.

Я подумал: "Да, это реальный способ исправить это и понять, что происходит", - и начал прослеживать эту проблему. Не вдаваясь во все подробности, выясняется, что проблема, с которой я столкнулся, на самом деле начиналась с тестового клиента.

Я использую firecamp и websocat в качестве инструментов тестирования клиентов websocket. Я пытался отправить двоичные данные через оба инструмента, но когда я копнул через Wireshark, я обнаружил, что данные в полете, поступающие от самого клиента, состоят из шестнадцатеричных значений для закодированных символов 1s и 0s.

wireshark

После исследования и задания отдельного вопроса stackoverflow я нашел способ отправки фактических двоичных данных от клиента, в частности printf.

например:

 printf "\x01\x02\x03\x04\x05\x06\x07\x08" | websocat -b ws://localhost:3002

printf solution

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

Тем не менее, я очень ценю вашу помощь. Возможно, мне и не нужно было выполнять преобразования для этого конкретного экземпляра, но я хочу улучшить свои типы C, преобразования и общее понимание, чтобы знания, полученные здесь, все еще были полезны. Спасибо всем : поклоны:

, 👍2

Обсуждение

Код ASCII представлен одним байтом, который равен 8 битам, а не 6 битам, @jsotola

непонятно, почему вам нужно преобразовать символ ascii в число перед его отображением, @jsotola

точка 3 - это "void", "unsigned char" - это один байт, и ваши значения битовой маски помещаются в один байт., @Juraj

(char) strtoul(strData) http://www.cplusplus.com/reference/cstdlib/strtoul/, @dandavis

Потрясающе, спасибо @dandavis, я попробую., @Chris Schmitz

@jsotola re: длина байта ascii: я знаю, что это 8 бит, я набрал ascii без ведущих нулей. Причина, по которой я хочу преобразовать его, заключается в том, что я не отображаю числовой символ в виде строки, я хочу использовать двоичное представление для управления огнями в строке матрицы, поэтому 1 или 0b00000001 будет освещать только самый правый светодиод в строке 8 светодиодов матрицы. Преобразование заключается в том, что я могу использовать двоичное представление 1 (0b00000001) против двоичного представления '1' (00110001)., @Chris Schmitz


1 ответ


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

3

Не уверен, хотите ли вы преобразовать char * в int, но если вам это нужно, есть atoi(), atol(), strtol(), strtoul() для рассмотрения или прокатки вашей собственной функции.

Плюсы и минусы обсуждаются здесь. Главное отметить, что atoi() и atol() не имеют обработки ошибок, но если char *, который вы им скармливаете, полностью контролируется и предсказуем, это не должно быть проблемой.

Кстати, я бы попытался заставить websocket отправлять правильные одиночные байты вместо строковых представлений чисел, если это вообще возможно.

,

хорошая вещь в atoi() заключается в том, что он останавливается на цифрах, поэтому ваш ввод может быть "грязным", если он начинается с чисел, что делает его приятным для использования с существующими строковыми указателями вместо небольших вырезанных массивов символов., @dandavis

Я думаю, что это может быть решением проблемы. У меня есть более подробная информация, но я должен подождать до окончания работы, чтобы обновить вопрос., @Chris Schmitz