Печать из строки HEX в UTF-текст

gear2003
Offline
Зарегистрирован: 15.02.2017

Всем привет!

Помогите реализовать вот такую задачу. Ардуино принимает текстовую информацию он внешнего устройства в шестнадцатиричном виде. После этого нужно полученную информацию преобразовать в текст и вывести при помощи Serial.print в терминал.

Например пришло сообщение "48 65 6с 6с 6f 20 77 6f 72 6c 64" - и его нужно вывести в терминал как "hello world". Есть ли методы, библиотеки, которые позволят выполнить эту операцию без необходимости прописывать отдельно значение каждого символа для замены?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

1. Вам точно нужен UTF?

2. Что Вы понимаете под выражением "принимает текстовую информацию он внешнего устройства в шестнадцатиричном виде"? Может она просто принимает готовый текст? Например, в Вашем примере 48 - это один байт или два символа '4' и '8'?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

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

gear2003
Offline
Зарегистрирован: 15.02.2017

Я принимаю данные пакетами. Изначально их количество точно неизвестно. Каждый пакет состоит из 8 символов, кодированных в HEX. При первом приеме переменной типа стринг присваивается набор пришедших символов. После получения следующего пакета я пользуюсь методом добавления к существующей строке пришедшего вновь пакета. И т.д. до получения специфичной команды, при которой строка обнуляется. Так вот, необходимо полученную строку, содержащую HEX-коды символов, разделенные пробелами, вывести в терминал как готовый текст.

Вот примерно так происходит формирование моей строки из приходящих сообщений:

string textmes;

Serial.print("Text: ");
	            for(int kk = 0; kk<len; kk++)
        	    {
				textmes += (" ") +  String(buf[kk]);
		    }
Serial.print(textmes); 

Как мне строку textmes преобразовать в текст?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, здесь нет приёма, Вы его не привели. Что такое buf, какого он типа и откуда берётся тоже непонятно, так что тут ничего сказать нельзя.

У меня сильное подозрение, что Вы принимаете строку в готовом виде, преобразуете её в строковое представление 16-ричного числа (да ещё на кой-то чёрт с пробелами) а потом геройски хотите преобразовывать обратно.

Как и откуда Вы получаете свои пакеты?

gear2003
Offline
Зарегистрирован: 15.02.2017

Имеем unsigned char buf[8];

Каждый из ее элементов является hex-значением.

Преобразование в тип стринг я сделал для того, чтобы можно было выводить в терминал все сообщение одной строкой (не придумал другого метода). Количество сообщений - до 22 включительно.

Пакеты получаю с магнитолы автомобиля (кан-шина). Использую can bus shield и его библиотеку. Соответственно buf - это значение сообщения, преходящего от конкретного ID.

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, тогда они приходят в виде нормальной строки. Понимаете нормальной. Вы можете её просто печатать.

Попробуйте просто не выпендриваясь напчатать свой buf. Примерно так

for (int i=0; i<8; i++) Serial.print(buf[i]);

Вы получите нормальные символы.

И еще, пожалуйста запомните на всю оставшуюся жизнь. Не бывает никаких HEX-значений и никаких строк в формате HEX - не бывает от слова вообще.

Допустим в памяти компьютера в некотором байте лежит следующая комбинация битов

0110 1101

Если этот байт у Вас обписан как int8_t, то при печати Serial.print(b) вы увидите число 109. При печати Serial.print(b,HEX) вы увидите число 6D, если же этот самый байт у Вас объявлен как char, то при печати Вы увидите букву 'm'. А в байте ровно одни и те же биты - ровно одна и таже информация - это тот же самый байт!

Так в каком формате хранится в том байте число? В десятичном? Шестнадцатиричном? Символьном? Нет таких форматов хранения - все эти форматы связаны не с внутренним представлением, а только с преобразованием в вид понятный человеку - внутри всё хранится одинаково.

gear2003
Offline
Зарегистрирован: 15.02.2017

Спасибо Вам большое за подробное разъяснение!

Метод Serial.print(char(buf[i])) работает, но к сожалению только с ASCII символами. А как быть с выводом кириллицы? 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так у Вас там ещё и кириллица есть?

С нею не так просто. Очень много вопросов. например, куда именно Вы собираетесь её выводить. В разные места она выводится по-разному. Если Она у Вас для окончательного проекта, то стоит мучаться. а если только типа для отладочной печати, я бы забил и выводил транслитом.

gear2003
Offline
Зарегистрирован: 15.02.2017

Вывод необходим именно для окончательного проекта. Вывожу на экран планшета сразу функцией serial.print(). Поэтому все же придется помучиться. Советуете прописать каждый символ русского алфавита в скетче?

Поясните, пожалуйста - как реализовать вывод транслитом?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, смотрите. Кто выводит информацию на планшете? Ваша программа? Ардуиновский монитор порта? Ещё кто-то? Вы можете поменять ту программы или нет? Если можете, то лучше в ней посмотреть. что она полуает от Ардуино и преобразовать к нормальным русским буквам. Если же не можете, то надо из Ардуино исхтриться передать так, чтобы та поняла правильно.

Как у Вас? Можете менять, нет?

gear2003
Offline
Зарегистрирован: 15.02.2017

На планшете информацию выводит моя программа. И да, я могу прописать все в ней. Я уже давно склоняюсь ииенно к этому варианту. Но для общего развития, только в теории - как можно было бы реализовать вывод кириллицы? 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, вот, смотрите откуда Вы берёте эту кириллицу в Ардуино? Я не уверен, но думаю, что там она кодируется однобайтовым кодом (т.е. расширенная таблица ASCII или там ещё что). В планшете же у Вас двухбайтовая кодировка UNICODE (скорее всего). 

Для преобразования есть специальные алгоритмы и готовые библиотеки. тут на форуме нарл это обсуждал и выкладывались коды как это делать. Поищите поиском по форуму по ключевому слову wchar (это тип данных для unicode символов)

gear2003
Offline
Зарегистрирован: 15.02.2017

Ок, спасибо!

Я пробовал именно wchar, но стандартные библиотеки не понимали этот тип данных. Поищу готовые решения, еще раз спасибо за консультацию.