Получение данных через монитор порта

leks
Offline
Зарегистрирован: 22.10.2017
byte Str[10];

byte i=0;
void setup()  
{ 
  Serial.begin(9600); 
} 

void loop()  
{ 
  if (Serial.available() > 0)  
 {
  byte k= Serial.available(); 
 for ( i=0; i < k-1; i++) 
 {Str[i] = Serial.read();Serial.println(Str[i]);Serial.println((char)Str[i]); }
 
 } 
  delay(100);
 
}  

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

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

использовать или другой монитор порта понимающий однобайтовый русский или выводить в UTF-8

leks
Offline
Зарегистрирован: 22.10.2017

А как выводить в UTF-8 ? Хотя я неверно задаю вопрос. Имея самолепное приложение на смартфоне, через блютуз модуль на Ардуину посылаю 3 буквенные команды на англицком, там, собирая функцией байты в String строку, проверяю соответствие строки предполагаемым шаблонам команд и выполняю нужные действия. Теперь хочу переделать приложение на отсылку русских слов, с преобразованием на стороне Ардуино букв в массив кодов ASCII - где наша А это 192. Или это гораздо сложнее? 

b707
Offline
Зарегистрирован: 26.05.2017

leks пишет:

Теперь хочу переделать приложение на отсылку русских слов, с преобразованием на стороне Ардуино букв в массив кодов ASCII - где наша А это 192. Или это гораздо сложнее? 

А зачем? - если это просто комбинации букв, зачем их по русски посылать?

Обратите внимание. что команды в программах никто не переводит. Даже в русской винде команды копирования и удаления  - copy и del., а не КОП и СТЕР :)

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

leks пишет:

 Или это гораздо сложнее? 

кому как....

что бы вывести русскую букву А в монитор порта, необходимо последовательно выполнить две команды:

Serial.write(0xD0);
Serial.write(0x90);

 

leks
Offline
Зарегистрирован: 22.10.2017

b707 пишет:

leks пишет:

Теперь хочу переделать приложение на отсылку русских слов, с преобразованием на стороне Ардуино букв в массив кодов ASCII - где наша А это 192. Или это гораздо сложнее? 

А зачем? - если это просто комбинации букв, зачем их по русски посылать?

Обратите внимание. что команды в программах никто не переводит. Даже в русской винде команды копирования и удаления  - copy и del., а не КОП и СТЕР :)

Да балуюсь с манипулятором на сервах. В смартфон говорим "ракета", в Ардуино идёт "RKT", манипулятор рисует картинку по этой команде. А хочется "ракета", в Ардуино идёт "ракета" и преобразуется для рисования "р", "а" и т.д. в коды ASCII.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

leks пишет:

...хочу переделать приложение на отсылку русских слов, с преобразованием на стороне Ардуино букв в массив кодов ASCII - где наша А это 192. Или это гораздо сложнее? 

Это действительно гораздо сложнее.

Строго говоря, Вы хотите невозможного: в ASCII только 128 кодов от 0 до 127 и никакого 192 в таблице нет.

А раз так - нужно разбираться с кодировками. А это - само по себе сложно. Для начала подумайте, сможете ли Вы сформулировать Вашу хотелку так, чтобы она не была внутренне противоречивой? (см. мой второй абзац)

leks
Offline
Зарегистрирован: 22.10.2017

andriano пишет:

leks пишет:

...хочу переделать приложение на отсылку русских слов, с преобразованием на стороне Ардуино букв в массив кодов ASCII - где наша А это 192. Или это гораздо сложнее? 

Это действительно гораздо сложнее.

Строго говоря, Вы хотите невозможного: в ASCII только 128 кодов от 0 до 127 и никакого 192 в таблице нет.

А раз так - нужно разбираться с кодировками. А это - само по себе сложно. Для начала подумайте, сможете ли Вы сформулировать Вашу хотелку так, чтобы она не была внутренне противоречивой? (см. мой второй абзац)

Значит я чего то не понимаю в этих кодировках, забиваю в поисковик ASCII, смотрю таблицы, наша А - 192, в мониторе порта отсылаю А, получаю её как 192. Но меня больше смущает - в какой кодировке отсылает смартфон на Ардуину? (приложение делал на APP INVENTOR и в настройках его указывал именно эту кодировку). Значит русские в ней не проходят.

sadman41
Offline
Зарегистрирован: 19.10.2016

А что вам показывает Serial Monitor, когда вы кидаете ардуине со смартфона букву?

Вообще - для микроконтроллеров нет никаких букв, есть байты. Ваш смартфон может отослать один байт, два байта, четыре - любое соответствие кода символа нарисованной на экране букве "А". МК примет эти байты и далее, руководствуясь прошивкой, должен как-то на них отреагировать - мигнуть, пискнуть, щелкнуть и т.п. 

leks
Offline
Зарегистрирован: 22.10.2017

sadman41 пишет:

А что вам показывает Serial Monitor, когда вы кидаете ардуине со смартфона букву?

Вообще - для микроконтроллеров нет никаких букв, есть байты. Ваш смартфон может отослать один байт, два байта, четыре - любое соответствие кода символа нарисованной на экране букве "А". МК примет эти байты и далее, руководствуясь прошивкой, должен как-то на них отреагировать - мигнуть, пискнуть, щелкнуть и т.п. 

Я так не пробовал. Пробовал так: синхронно менял комбинации букв в команде на английском в скетче Ардуино и приложения. Идентификация работала, при русской комбинации уже нет. Монитор порта не открывал потому что на 0 и 1 выводах блютуз модуль висел. На худой вариант, думал, проговаривать по букве, а посылать число 0-32 на Ардуино, а по ним рисовать соответсвующую букву. 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

leks, для начала, как правильно заметили - надо разобраться с кодировкой. Почему? Всё просто, следите за руками: буквы - это абстракция НАД набором байт. И однажды одна кучка людей пошла пить пивас и решила, что в первом конкретном случае в одном байте содержится информация об адресе буквы в таблице символов. Таким образом, передавая 5 байт - мы передаём 5 адресов в таблице символов конкретной КОДИРОВКИ.

Потом - вторая кучка гиков решила, что для представления символа - одного байта явно маловато, развелось, понимаешь, этих всяких - с умляутами там, тильдами и прочей хернёй, не говоря уже о наскальных иероглифах. И решили, что в новой КОДИРОВКЕ будет так: один адрес в таблице символов будет передаваться двумя байтами. Таким образом, передавая 6 байт - мы передаём 3 символа, грубо говоря.

Потом очередь дошла до совсем чеканутых, и они придумали UTF-8...

Мысль донёс? Для начала надо бы знать - в какой кодировке передаются ваши строки.

sadman41
Offline
Зарегистрирован: 19.10.2016

leks пишет:

Монитор порта не открывал потому что на 0 и 1 выводах блютуз модуль висел. На худой вариант, думал, проговаривать по букве, а посылать число 0-32 на Ардуино, а по ним рисовать соответсвующую букву. 

Можете попробовать блюпуп повесить на SoftwareSerial или на Mega2560 с двумя сериалами, выводить байты на LCD-экран, наконец.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

leks пишет:

Значит я чего то не понимаю в этих кодировках,

Это заметно по Вашим сообщениям.

Цитата:

забиваю в поисковик ASCII, смотрю таблицы, наша А - 192,

А читать то, что выдает поисковик, не пробовали? 

Хотя бы, как называются те таблицы, которые содержат "нашу А"?

И еще: раз уж Вы сами употребили слово "таблица" во множественном числе, то, вероятно, могли обратить внимание, что в разных табицах "нашей А" соответствуют различные числа.

Цитата:

в мониторе порта отсылаю А, получаю её как 192.

На основе этого эксперимента можно сделать предположение, в какой именно кодировке работает монитор порта. Но отсюда совершенно не следует, что и другие программы работают в этой же кодировке. Arduino IDE, например, использует другую.

Так что у ВАс на выбор два варианта:

1. Ограничиться исключительно латинницей (той самой ASCII).

2. Тщательно разобраться с кодировками, чтобы решить этот вопрос для себя раз и навсегда.

 

Лично я советую остановиться на первом варианте (хотя для общей эрудиции не плох и второй - но он тоже не исключет первый). Например, я, хотя и написал библиотеку с поддержкой кириллицы "из коробки", http://arduino.ru/forum/proekty/asoled-kompaktnaya-biblioteka-dlya-oled-... сделал это исключительно из спртивного интереса и сам ни разу ее кииллическими возможностями не воспользовался.

leks
Offline
Зарегистрирован: 22.10.2017

Нашёл уточнение -ASCII Win-1251 для нашей А. На стороне смартфона в инвенторе в строке кодировка, наверное можно и такую вариацию забить, но на стороне Ардуино врядли. Проще попробовать по другому. 

 

b707
Offline
Зарегистрирован: 26.05.2017

leks пишет:

Проще попробовать по другому. 

 

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

leks
Offline
Зарегистрирован: 22.10.2017

b707 пишет:

leks пишет:

Проще попробовать по другому. 

 

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

Так, а что передавать в Ардуино получив слово на смартфоне?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

leks пишет:

Нашёл уточнение -ASCII Win-1251 для нашей А.

ASCII и Win-1251 - это разные кодировки: первая 7-битная, а вторая - 8-битная. Но первая половина таблицы Win-1251 полностью совпадает с таблицей ASCII.

leks пишет:

b707 пишет:

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

Так, а что передавать в Ардуино получив слово на смартфоне?

Передавайте то, что Вам нужно. В завивимости от Ваших потребностей.

Самое простое - передавать число. Однобайтовое. Вряд ли Вы на Ардуино предусмотрете реакцию на более чем 256 команд, поэтому вполне логично на смартфоне найти соответствующее команде число и именно его передавать на Ардуину.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

А как Ваша программа на смартфоне будет выглядеть в идеале? Наверное нарисованные кнопочки для команд и нарисованные лампочки для индикации?

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

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

b707 пишет:

leks пишет:

Теперь хочу переделать приложение на отсылку русских слов, с преобразованием на стороне Ардуино букв в массив кодов ASCII - где наша А это 192. Или это гораздо сложнее? 

А зачем? - если это просто комбинации букв, зачем их по русски посылать?

Обратите внимание. что команды в программах никто не переводит. Даже в русской винде команды копирования и удаления  - copy и del., а не КОП и СТЕР :)


Ну это вы погорячились, вам видимо АЛЬФА ДОС не знакома, там командный интерпретатор понимал и русские команды )))

leks
Offline
Зарегистрирован: 22.10.2017

mykaida пишет:

А как Ваша программа на смартфоне будет выглядеть в идеале? Наверное нарисованные кнопочки для команд и нарисованные лампочки для индикации?

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

Выглядит просто: одна кнопка, нажимаешь, говоришь слово, получаешь в ответ голосовой коментарий, следом идёт выполнение команды по произнесённому слову-коду. Команд с десяток. То есть одно слово - одна команда. А хотелось так: произнесённое слово, отправляется на Ардуино, там разбирается на отдельные буквы-команды. Вася говорим, а пишет манипулятор В,А,С,Я (4 команды).

Но видимо рановато захотелось. 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ua6em пишет:

Ну это вы погорячились, вам видимо АЛЬФА ДОС не знакома, там командный интерпретатор понимал и русские команды )))

А АЛЬФА ДОС обменивалась информацией со смартфонами? Ж8( )

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

Кроме того, сильно подозреваю, что в случае АЛЬФА ДОС использовалась 7-битная КОИ, т.е. проблем собственно при передаче даже здесь возникать не должно в принципе. Единственное возможное неудобство то, что в ASCII эта кириллица будет выглядеть латинницей. Но это только внешний вид - сами коды символов остаются неизменными.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

leks пишет:

Выглядит просто: одна кнопка, нажимаешь, говоришь слово, получаешь в ответ голосовой коментарий, следом идёт выполнение команды по произнесённому слову-коду. Команд с десяток. То есть одно слово - одна команда. А хотелось так: произнесённое слово, отправляется на Ардуино, там разбирается на отдельные буквы-команды. Вася говорим, а пишет манипулятор В,А,С,Я (4 команды).

Но видимо рановато захотелось. 

Это нелогично.

При распределении работы между двумя системами бОльшую часть работы должна брать на себя более мощная система. А это совсем не Ардуино.

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

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

надо еще чтоб ардуина умела взат посылать "ИНЖАЛИД ДЕЖИЦЕ"

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

andriano пишет:

ua6em пишет:

Ну это вы погорячились, вам видимо АЛЬФА ДОС не знакома, там командный интерпретатор понимал и русские команды )))

А АЛЬФА ДОС обменивалась информацией со смартфонами? Ж8( )

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

Кроме того, сильно подозреваю, что в случае АЛЬФА ДОС использовалась 7-битная КОИ, т.е. проблем собственно при передаче даже здесь возникать не должно в принципе. Единственное возможное неудобство то, что в ASCII эта кириллица будет выглядеть латинницей. Но это только внешний вид - сами коды символов остаются неизменными.


 

Командный интерпретатор не дизассемлировал, нужды не было, а кодировки были во второй половине ASCII 128-255
А перекодировать вообще сложностей нет, одна команда процессора выполняемая за один такт, XLAT называется )))

 

leks
Offline
Зарегистрирован: 22.10.2017

Разобрался, всё работает - слова продиктованные по русски пишет. Надо было на стороне смартфона в app inventor, в настройках блютуз прописать кодировку - CP1251 и что бы услышанное слово преобразовывало в текст заглавными буквами. Тогда А это 192 и т.д.  

leks
Offline
Зарегистрирован: 22.10.2017
 metka: if (Serial.available() > 0) {  //если есть доступные данные
        // считываем байт
   incomingByte = Serial.read();
   if (incomingByte==168){j=5;goto metka1;} //вставка для рисования буквы Ё как Е
   if (incomingByte==32){j=33;goto metka1;} //вставка для "рисования пробела"
   j=incomingByte-192;if (j<0||j>33){goto metka;}}else {goto metka;}
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
metka1:

Такая часть корявого кода , переменная j задаёт номер элемента в массиве для рисования конкретной буквы. Как из значений incomingByte вновь составить поступившее в Ардуино слово и сравнить с "эталоном", например - если slovo=="ВАСЯ", то...

b707
Offline
Зарегистрирован: 26.05.2017

leks пишет:
Как из значений incomingByte вновь составить поступившее в Ардуино слово и сравнить с "эталоном", например - если slovo=="ВАСЯ", то...

а вот тут "вас ждет вторая серия"...

Вы забиваете в коде slovo="ВАСЯ", сохраняете скетч, открываете его снова и... видите на месте "ВАСЯ" какое-нибудь "#$@@#"

И, конечно же, скетч не работает.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

b707 пишет:

leks пишет:
Как из значений incomingByte вновь составить поступившее в Ардуино слово и сравнить с "эталоном", например - если slovo=="ВАСЯ", то...

а вот тут "вас ждет вторая серия"...

Вы забиваете в коде slovo="ВАСЯ", сохраняете скетч, открываете его снова и... видите на месте "ВАСЯ" какое-нибудь "#$@@#"

И, конечно же, скетч не работает.

Если работать с UTF-8 - то можно забыть о таких головняках ;)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

разбирать ардуиной строки неправильное решение, передавайте команды, двухбайтный код думаю вполне устроит

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

ua6em пишет:

разбирать ардуиной строки неправильное решение

Не совсем согласен. У мну в проекте прекрасно работает система именно текстовых команд, типа:

SET=PIN|12|ON

GET=PIN|13

и т.п. Очень удобно, накладных расходов - мизер, т.к. в любом случае частота опроса контроллера командами - не килогерцы, не надо оно столько. Это я к тому, что многое - зависит от вводных: если у ТС команды идут десятки раз в секунду - и строковые команды вполне себе потянут, всё равно основную часть времени МК крутит пустой цикл ;)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

представил этот код )))
каждый делает как ему удобно, это точно

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
Любой пакет должен имеет заголовок и терминатор. И я пришел к воду что лучше что это будет '\n'
Вот к примеру сообщение SET=PIN|12|ON станет  таким "\nSET=PIN|12|ON\n"
В чем плюс Если идет нормальный ход то "\nSET=PIN|12|ON\n"+"\nGET=PIN|13\n"+"\nSET=PIN|12|ON\n" и все нрмально
Но если появится к примеру мусор то
"\nSET=PIN|12|ON\n"+мусор+"\nGET=PIN|13\n"+мусор+"\nSET=PIN|12|ON\n"
То есть по факту будет это
"SET=PIN|12|ON" //< это не потеряется
"мусор" //< это отсечется
"SET=PIN|12|ON"//< это не потеряется
"мусор"//< это отсечется
"SET=PIN|12|ON"//< это не потеряется

 

leks
Offline
Зарегистрирован: 22.10.2017

Ну у меня, насколько я понимаю, со смартфона идёт на Ардуину , например "ВАСЯ\n" в кодировке CP1251. На Ардуино получаю из этого 194,192... четыре числа. А как получить char и сравнить его с "ВАСЯ"? С UTF-8 вроде пробовал так: byte j;// переменная для выбранной буквы char tablC[]="ШТИРЛИЦ";, а потом вытягивал из массива числа через одно для переменной j=tablC[2*r+1]-144;где r номер текущей буквы с 0. Можно ли штирлица зашифровать в массив по буквам в виде пар чисел на каждую? Просто очень удобно в смартфон говорить слова, которые потом сравнивать "сразу с эталонами" в Ардуино.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

ua6em пишет:

представил этот код )))

Вполне тривиальный: парсер команд из потока, который разбирает всё на параметры, учитывая формат команд и всякий возвожный мусор (пух вон ниже свои пустые домыслы пытается туда прикрутить). Если интересно - код лежит тут: https://github.com/Porokhnya/GreenhouseProject/blob/master/Main/CommandParser.cpp

Это часть проекта контроллера теплицы, текстовые команды - главный пойнт: неважно, откуда она пришла - по MQTT, через ESP с вебморды, с монитора порта, по RS-485 - всё будет обработано и перенаправлено тому или иному программному модулю. Короче, концепция ЧПК - человеко-понятной команды: можно телнетом законнектится к контроллеру и слать туда команды.

А так да - ессно, каждый делает так, как ему удобно.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

qwone пишет:

Любой пакет должен имеет заголовок и терминатор. И я пришел к воду что лучше что это будет '\n'
Вот к примеру сообщение SET=PIN|12|ON станет  таким "\nSET=PIN|12|ON\n"
В чем плюс Если идет нормальный ход то "\nSET=PIN|12|ON\n"+"\nGET=PIN|13\n"+"\nSET=PIN|12|ON\n" и все нрмально
Но если появится к примеру мусор то
"\nSET=PIN|12|ON\n"+мусор+"\nGET=PIN|13\n"+мусор+"\nSET=PIN|12|ON\n"
То есть по факту будет это
"SET=PIN|12|ON" //< это не потеряется
"мусор" //< это отсечется
"SET=PIN|12|ON"//< это не потеряется
"мусор"//< это отсечется
"SET=PIN|12|ON"//< это не потеряется

Ты тут самый умный, да, пух? Хуле ты сюда влез - п@здуй в свою тему, и оттуда всех гоняй ссаными вениками. Всё у меня нормально и с заголовком, и терминатором - иди уже, графоманствуй в своих темах.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

leks пишет:

А как получить char и сравнить его с "ВАСЯ"? 

String inStr;

while(Serial.available())
{
  char ch = Serial.read();
  if(ch == '\n') break;
  inStr += ch;
}

if(inStr == F("ВАСЯ"))
{
 // bla bla
}

Только фишка в том, что Arduino IDE по умолчанию хранит файлы в кодировке UTF-8, так что и строка F("ВАСЯ") будет сохранена в UTF-8. Есть настройка substitute_unicode, емнип - можно отключить сохранение в UTF-8, и тогда файл будет сохраняться в кодировке ОС.

sadman41
Offline
Зарегистрирован: 19.10.2016

Можно наверняка Васю записать с помощью эскейпирования числовых кодов. Не сильно понятно будет, но и не побьется при сохранении исходника"

sadman41
Offline
Зарегистрирован: 19.10.2016

qwone пишет:

Любой пакет должен имеет заголовок и терминатор. И я пришел к воду что лучше что это будет '\n'

Префикс и постфикс должны быть различающимися, в противном случае любое сообщение равновероятно окажется мусором, а мусор - сообщением. STX и ETX еще во времена эпохи телетайпа придумали делать различными не просто для красоты.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:

Можно наверняка Васю записать с помощью эскейпирования числовых кодов. Не сильно понятно будет, но и не побьется при сохранении исходника"

Можно, конечно. Но жутко неудобно :) Мне проще напрямую с UTF-8 работать, когда нужна работа с кириллицей: в коде просто пишешь строку F("Настройки") (для какого-то из экранов дисплея) - и не паришься, и сразу видно. А когда подобных строк - сотни, то escape-последовательности уж точно помогут запутаться :)

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:

qwone пишет:

Любой пакет должен имеет заголовок и терминатор. И я пришел к воду что лучше что это будет '\n'

Префикс и постфикс должны быть различающимися, в противном случае любое сообщение равновероятно окажется мусором, а мусор - сообщением. STX и ETX еще во времена эпохи телетайпа придумали делать различными не просто для красоты.

В моём случае, учитывая специфику, STX принимает одно из значений "CTGET=" или "CTSET=", а ETX = два байта 0x0D 0x0A, проще говоря - возврат каретки и перевод строки (\r\n). Как показала практика - вполне достаточно для надёжной работы, во всяком случае - пару лет уже работает этот принцип и не кашляет. Сейчас, когда надо быстро наладить общение прошивки с софтом-конфигуратором на компе - только так и делаю, собственно - заказчики довольны, можно даже ручками простыми командами порулить контроллером.

Впрочем, никому не навязываю, да и упомянул только в том разрезе, что и текстовые команды - имеют право на жизнь, очень даже. Из последнего вспомнившегося сходной тематики: заказчик просил, чтобы он мог вбить в текстовый файл команды, по которым бы работал контроллер (микропрограмма, в общем). Те же яйца: заказчик не морщит лоб с байтами - а просто вбивает строки вида RUN_FORWARD,10 и т.п. - контроллер парсит строку с командой и выполняет.

sadman41
Offline
Зарегистрирован: 19.10.2016

Да я не против. Мне просто странно, как можно надеяться на четкое выделение пэйлоада пакета, используя одну и ту же последовательность для STX и ETX. Ни один нормальный сетевой протокол такого себе не позволяет и всем понятно почему.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:

Да я не против. Мне просто странно, как можно надеяться на четкое выделение пэйлоада пакета, используя одну и ту же последовательность для STX и ETX. Ни один нормальный сетевой протокол такого себе не позволяет и всем понятно почему.

Тут согласен полностью, без вариантов. Но это же пух - слышал звон, не знает, где он. Так что - забей ;)

З.Ы. Кстати, напомнил - вот из того же проекта хоббийного:

 RS485Packet packet;
    memset(&packet,0,sizeof(RS485Packet));
    
    packet.header1 = 0xAB;
    packet.header2 = 0xBA;
    packet.tail1 = 0xDE;
    packet.tail2 = 0xAD;

А там ещё и crc8 до кучи. Как видишь, я себе не позволяю "используя одну и ту же последовательность для STX и ETX" :)

leks
Offline
Зарегистрирован: 22.10.2017

DIYMan пишет:

leks пишет:

А как получить char и сравнить его с "ВАСЯ"? 

String inStr;

while(Serial.available())
{
  char ch = Serial.read();
  if(ch == '\n') break;
  inStr += ch;
}

if(inStr == F("ВАСЯ"))
{
 // bla bla
}

Только фишка в том, что Arduino IDE по умолчанию хранит файлы в кодировке UTF-8, так что и строка F("ВАСЯ") будет сохранена в UTF-8. Есть настройка substitute_unicode, емнип - можно отключить сохранение в UTF-8, и тогда файл будет сохраняться в кодировке ОС.

Тогда проще попробовать указать тип кодировки в приложении к смартфону как UTF-8, а не СР1251, но тогда как вырезать из "стрингов" второе число кода буквы - те же 144 для А?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

leks пишет:

Тогда проще попробовать указать тип кодировки в приложении к смартфону как UTF-8, а не СР1251, но тогда как вырезать из "стрингов" второе число кода буквы - те же 144 для А?

Из "стрингов" ничего вырезать не надо - класс String вполне себе правильно работает с любой кодировкой - он просто хранит последовательность байт, и ему похрен, в какой кодировке эта последовательность ;) В приведённом выше примере с "Васей" - если внутри экземпляра класса String содержится строка "ВАСЯ" в кодировке UTF-8 - то сравнение с F("ВАСЯ") (при условии, что скетч сохранён в кодировке UTF-8) - пройдёт как истинное.

Просто чуть-чуть поймите про кодировки ;)

Если же вы про то, как вырезать подстроку, учитывая кодировку - тут всё несколько сложнее хотя бы потому, что UTF-8 - кодировка с переменным количеством байт на символ. Но я не уверен, что вам надо с этим заморачиваться ;)

leks
Offline
Зарегистрирован: 22.10.2017

DIYMan пишет:

leks пишет:

Тогда проще попробовать указать тип кодировки в приложении к смартфону как UTF-8, а не СР1251, но тогда как вырезать из "стрингов" второе число кода буквы - те же 144 для А?

Из "стрингов" ничего вырезать не надо - класс String вполне себе правильно работает с любой кодировкой - он просто хранит последовательность байт, и ему похрен, в какой кодировке эта последовательность ;) В приведённом выше примере с "Васей" - если внутри экземпляра класса String содержится строка "ВАСЯ" в кодировке UTF-8 - то сравнение с F("ВАСЯ") (при условии, что скетч сохранён в кодировке UTF-8) - пройдёт как истинное.

Просто чуть-чуть поймите про кодировки ;)

Если же вы про то, как вырезать подстроку, учитывая кодировку - тут всё несколько сложнее хотя бы потому, что UTF-8 - кодировка с переменным количеством байт на символ. Но я не уверен, что вам надо с этим заморачиваться ;)

Ну да, если разбивать на несколько вариантов скетчей и приложений. Здесь мы рисуем изображения по слову-команде, здесь слово записываем произнесённое,- буквами, там рисуем цифры текущего времени.

Просто думал что А в этой кодировке это 208 на 144, и "144 для каждой буквы" можно как то извлечь из строки. То есть приходящее слово можно по разному анализировать. 

Shuring
Offline
Зарегистрирован: 16.08.2018

sadman41 пишет:
Мне просто странно, как можно надеяться на четкое выделение пэйлоада пакета, используя одну и ту же последовательность для STX и ETX. Ни один нормальный сетевой протокол такого себе не позволяет и всем понятно почему.

Я бы не был так категоричен. Например, протокол HDLC имеет флаг 0x7E в начале и конце кадра. Для контроля целостности есть дополнительные средства, так что выделение кадра проблемы не представляет.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

DIYMan пишет:
Тут согласен полностью, без вариантов. Но это же пух - слышал звон, не знает, где он. Так что - забей ;)
Ну да забей. Тут высокие материи разбирают. А простые решения они не по статусу великим умам.   Но если у Вас Serial и вы не сильно хотите заморачиваться с кодом то заголовок и хвост можно свести к одному коду. Проще говоря как поймали хвост, то посмотри что в буфере лежит. Если в буфере пурга или переполнение то это мусор. Зачем тогда второй хвост на нос цеплять. Так мало ли что до посылки в serial прилетело. Вот первый хвост и буфер приема и очистит. Разумеется тот буфер в который вы данные будете накапливать из приемного буфера Serial-a.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

leks пишет:

Ну да, если разбивать на несколько вариантов скетчей и приложений. Здесь мы рисуем изображения по слову-команде, здесь слово записываем произнесённое,- буквами, там рисуем цифры текущего времени.

Просто думал что А в этой кодировке это 208 на 144, и "144 для каждой буквы" можно как то извлечь из строки. То есть приходящее слово можно по разному анализировать. 

Стоп. Давай оппределимся в понятиях: допустим, ты хочешь, чтобы по приходу слова "ВАСЯ" выполнялось одно действие, а по приходу слова "ПЕТЯ" - другое. Соответственно, ты должен как-то понять, что в Serial упала именно команда, а не набор мусора. Для простоты, дабы сейчас не забивать голову, считаем, что признаком окончания команды - служит перевод строки \r\n. Тогда ты делаешь следующее:

String commandHolder;

void runCommand()
{
  if(commandHolder == F("ВАСЯ")) Serial.println(F("RUN COMMAND #1"));
  else if(commandHolder == F("ПЕТЯ")) Serial.println(F("RUN COMMAND #2"));

  commandHolder = "";
}

while(Serial.available())
{
 char ch = Serial.read();
 if(ch == '\r') continue;
 if(ch == '\n') runCommand();
 else commandHolder += ch;
}

При условии, что входящие по Serial байты содержат строки в кодировке UTF-8, и скетч сохранён в кодировке UTF-8 - всё будет работать.

Зачем разбивать в этом случае строку на подстроки - непонятно. Всё, что тебе нужно сделать - посылать команды, разделяя их символами новой строки.

Чтобы не забивать пока голову кодировками - замени ВАСЯ и ПЕТЯ на VASIA и PETIA - они в любой кодировке - по одному байту на символ: отсылаешь "VASIA\n" - выполняется первая команда, отсылаешь "PETIA\n" - выполняется вторая команда.

leks
Offline
Зарегистрирован: 22.10.2017

DIYMan пишет:

leks пишет:

Ну да, если разбивать на несколько вариантов скетчей и приложений. Здесь мы рисуем изображения по слову-команде, здесь слово записываем произнесённое,- буквами, там рисуем цифры текущего времени.

Просто думал что А в этой кодировке это 208 на 144, и "144 для каждой буквы" можно как то извлечь из строки. То есть приходящее слово можно по разному анализировать. 

Стоп. Давай оппределимся в понятиях: допустим, ты хочешь, чтобы по приходу слова "ВАСЯ" выполнялось одно действие, а по приходу слова "ПЕТЯ" - другое. Соответственно, ты должен как-то понять, что в Serial упала именно команда, а не набор мусора. Для простоты, дабы сейчас не забивать голову, считаем, что признаком окончания команды - служит перевод строки \r\n. Тогда ты делаешь следующее:

String commandHolder;

void runCommand()
{
  if(commandHolder == F("ВАСЯ")) Serial.println(F("RUN COMMAND #1"));
  else if(commandHolder == F("ПЕТЯ")) Serial.println(F("RUN COMMAND #2"));

  commandHolder = "";
}

while(Serial.available())
{
 char ch = Serial.read();
 if(ch == '\r') continue;
 if(ch == '\n') runCommand();
 else commandHolder += ch;
}

 

Зачем разбивать в этом случае строку на подстроки - непонятно. Всё, что тебе нужно сделать - посылать команды, разделяя их символами новой строки.

 

Дело в чём: надо, например по слову Петя его рисовать и это идентификация с "Петя", а слово Вася надо написать - и это должны быть номера элементов из "массива рисования букв" для В,А,С,Я.

sadman41
Offline
Зарегистрирован: 19.10.2016

Shuring пишет:

sadman41 пишет:
Мне просто странно, как можно надеяться на четкое выделение пэйлоада пакета, используя одну и ту же последовательность для STX и ETX. Ни один нормальный сетевой протокол такого себе не позволяет и всем понятно почему.

Я бы не был так категоричен. Например, протокол HDLC имеет флаг 0x7E в начале и конце кадра. Для контроля целостности есть дополнительные средства, так что выделение кадра проблемы не представляет.

Согласен, насчет "ни один" - погорячился.

Осталось понять, как алгоритм им.Квона будет определять мусор в буфере и отсекать его - по слову "мусор" или как-то иначе? CRC я там не наблюдаю пока что.

sadman41
Offline
Зарегистрирован: 19.10.2016

leks пишет:

Дело в чём: надо, например по слову Петя его рисовать и это идентификация с "Петя", а слово Вася надо написать - и это должны быть номера элементов из "массива рисования букв" для В,А,С,Я.

Я вот нить обсуждения потерял - зачем вам слово-то целиком анализировать, если вы его потом всё равно разбивать на символы собрались?