управление через uart
- Войдите на сайт для отправки комментариев
Чт, 11/10/2018 - 10:08
здравствуйте.
помогите решить проблему.
как совершать какието действия по принятому одному байту (символу) через сериал я знаю.
а как это сделать по принятой серии байтов (строке)?
тоесть, ардуина должна например зажечь светодиод (условно) после того как получит конкретные 5 байт. (0x81 0x91 0хF1 0x94 0x84). приэтом в сериал могут прилитать строки разной длины.
А у вас какие имеются идеи на этот счет?
Наверное для начала нужно куда-то сложить эти байты, так? Потом есть, примеру, функция memcmp()... Понимаете ход мысли?
тоесть, ардуина должна например зажечь светодиод (условно) после того как получит конкретные 5 байт. (0x81 0x91 0хF1 0x94 0x84). приэтом в сериал могут прилитать строки разной длины.
А в чем проблема? Вы же один байт читать умеете? - ну вот и проверяйте, не равен ли он 0x81. Если совпал - дальше читаете 5 байт в буфер и сравниваете с нужными.
Это, конечно, еше не все - но дальше разберетесь
касательно моих видень.
первым делом подумал о String , вроде как все байты соберает в строку, вот и хотел сравнить полученную строку с нужной строкой. только не пойму как прописать условие целой строкой. вобщем разбираюсь со сравнением двух строк.
также проскакивала мысль поиграться с масивами, но лично для меня это самый сложный вариант, могу легко запутаться, поэтому отложил на потом. тем болеее масивы будут разной длины
а потом мне пришла идея сложить (сплюсовать) эти 5 байт, и эту сумму сравнивать с суммами полученных пакетов. думаю вероятность что попадется две одинаковые суммы с разными пакетами байт. этот вариант самый простой. что думаете, на сколько надежный метод?
0x81 + 0x91 + 0хF1 + 0x94 + 0x84 = ?
0x81 + 0хF1 + 0x94 + 0x91 + 0x84 = ?
Пакеты разные или одинаковые?
Если уж хотите чего-то простого - считайте CRC что ли... это хоть какую-то гарантию уникальности даст.
а потом мне пришла идея сложить (сплюсовать) эти 5 байт, и эту сумму сравнивать с суммами полученных пакетов. думаю вероятность что попадется две одинаковые суммы с разными пакетами байт. этот вариант самый простой. что думаете, на сколько надежный метод?
ненамного, но надежнее будет сумму сначала сдвинуть(лучше циклически), а потом сложить её с очередным байтом.
0x81 + 0x91 + 0хF1 + 0x94 + 0x84 = ?
0x81 + 0хF1 + 0x94 + 0x91 + 0x84 = ?
Пакеты разные или одинаковые?
это меня и смущает, хоть вероятность наверное маленькая, но она есть
почитайте http://robocraft.ru/blog/1090.html
вот пример где байты собираются в строку
как правильно записать условие if (strData == ......) {......}
if (strData == 0x81 + 0x91 + 0хF1 + 0x94 + 0x84) {.....} так правильно?
или
if (strData == 0x810x910хF10x940x84) {.....}
Никак не правильно. Сразу в массив делайте, как полагается.
Никак не правильно. Сразу в массив делайте, как полагается.
так строка String вроде это тот же масив.
а если hex перевести в символы и написать строкой? 81+91+F1+94+84 = Ѓ‘с”„
if (strData == "Ѓ‘с”„") {.....}
Чем это от массива будет отличаться? Накладных расходов только больше.
Господи....
Навскидку, за 3 минуты. Анализируйте, чего происходит, в коде всё прозрачно, и даже переменные по-человечьи названы.
Господи....
Навскидку, за 3 минуты. Анализируйте, чего происходит, в коде всё прозрачно, и даже переменные по-человечьи названы.
что-то ругается на эту строку uint8_t test[PACKET_SIZE] = {0x81, 0x91, 0хF1, 0x94, 0x84};
разобраться пока не получилось, поэтому сделал вариант с суммой
тоесть паралельно при приеме байт, сумирую их и сравниваю с суммой байт эталонной строкои.
не идеально, но пока работает. остановился пока на этом варианте, потомучто нужно решать дальнейшую задачу, которая возникает после получения нужного (стартового) пакета байт.
остановился пока на этом варианте, потомучто нужно решать дальнейшую задачу, которая возникает после получения нужного (стартового) пакета байт.
ну-ну....
"нужно спешить решать... " - а как решать -похер
вот ракеты и падают
обьясните мне, пожалуйста, почему когда я шлю в сериал одни байта, например 0х41 0х41 0х41 (теже ААА)
собираю их в строку String strData, а потом провожу сравнивание
if (strData == "ААА") {.....} то условие выполняется
а когда шлю нужные мне байты 0x81 + 0x91 + 0хF1 + 0x94 + 0x84 (из таблици символов это Ѓ‘с”„)
также собираю их в строку String strData, а потом провожу сравнивание
if (strData == "Ѓ‘с”„") {.....} то условие НЕ выполняется
у ардуино есть ограничение по символам? чем ААА отличается от Ѓ‘с”„, ониже с одной таблици.
как мне правиль перевести HEX в символы, чтоб ардуино правильно их понимала?
остановился пока на этом варианте, потомучто нужно решать дальнейшую задачу, которая возникает после получения нужного (стартового) пакета байт.
ну-ну....
"нужно спешить решать... " - а как решать -похер
вот ракеты и падают
не, я вернусь к этому моменту, просто последующая задача намного важнее и сложнее.
обьясните мне, пожалуйста, почему когда я шлю в сериал одни байта, например 0х41 0х41 0х41 (теже ААА)
собираю их в строку String strData, а потом провожу сравнивание
if (strData == "ААА") {.....} то условие выполняется
а когда шлю нужные мне байты 0x81 + 0x91 + 0хF1 + 0x94 + 0x84 (из таблици символов это Ѓ‘с”„)
также собираю их в строку String strData, а потом провожу сравнивание
if (strData == "Ѓ‘с”„") {.....} то условие НЕ выполняется
у ардуино есть ограничение по символам? чем ААА отличается от Ѓ‘с”„, ониже с одной таблици.
как мне правиль перевести HEX в символы, чтоб ардуино правильно их понимала?
потомучто IDE преобразовывает строку в UTF-8 и вот это "Ѓ‘с”„" в бинарном выражении, побайтово, нихрена не равно 0x81 + 0x91 + 0хF1 + 0x94 + 0x84
char *str = "Ѓ‘с”„" ;
while (unsigned char ch = *str++) {
Serial.print(ch, HEX);
Serial.print(' ');
}
Serial.println();
пропробовай, чо в сериал выдаст?
у мня выдаёть
D0 83 E2 80 98 D1 81 E2 80 9D E2 80 9E
Есть замечательная функция Serial.find() вот ей и пользуйтесь.
https://doc.arduino.ua/ru/prog/Serial/Find
в твоем случае, строку нада задавать как char *str = "\x81\x91\хF1\x94\x84";
Есть замечательная функция Serial.find() вот ей и пользуйтесь.
https://doc.arduino.ua/ru/prog/Serial/Find
этта какбы вапще не при делах.
в твоем случае, строку нада задавать как char *str = "\x81\x91\хF1\x94\x84";
спасибо, буду пробовать.
не понимаю, зачем тогда та таблица с символами, если половина символом не воспринимается IDE должным образом?
походу все что от нуля до 127 по DEC работает нормально, все остальное как-то по другому.
я когда сумировал каждый символ (0х81 0х91 0хF1 0х94 0х84) то сумма получалась с минусом, может есть таблица от нуля до -127?
но я попробую с вашим вариантом char *str = "\x81\x91\хF1\x94\x84"; такстрока выглядит понятней чем крякозябры Ѓ‘с”„
Иоптваюмать, ну ты прочитай чонить за UTF-8 наконец.
не понимаю, зачем тогда та таблица с символами, если половина символом не воспринимается IDE должным образом?
потому что IDE написана буржуями и для буржуев, хочеться работать с русским текстом - учите теорию
не идеально, но пока работает. остановился пока на этом варианте, потомучто нужно решать дальнейшую задачу, которая возникает после получения нужного (стартового) пакета байт.
не, я вернусь к этому моменту, просто последующая задача намного важнее и сложнее.
1. Если Вы и дальше будете решать в том же духе, то очень быстро столкнетесь с ситуацией, когда все перестанет работать, а Вы даже не будете знать, с какой стороны подступиться.
2. Прежде, чем приступать к решению сложной задачи, следует добиться идеальной работы тех простых вспомогательных задач, на решение которых опирается сложная.
3. Боюсь Вы еще не готовы к решению сложных задач, если даже простые вызывают у Вас принципиальные сложности.
PS. В целом присоединюсь к рекомендациям:
- тщательно разобраться в теме "кодировки кириллицы",
- особенно обратить внимаение на "utf-8".
посмотрел, что в UTF8 нет таких символов как х81 х91 и т.д.
но из конвертера UTF8 в hex Ѓ‘с”„ превращается вообще в \xd0\x83\xe2\x80\x98\xd1\x81\xe2\x80\x9d\xe2\x80\x9e
ладно буду пробовать ваш вариат прописания строки, вечером отпишусь
Начал бы делать массивом - давно уже всё понял. А со строками и кодировками маяться еще день будешь.
но из конвертера UTF8 в hex Ѓ‘с”„ превращается вообще в \xd0\x83\xe2\x80\x98\xd1\x81\xe2\x80\x9d\xe2\x80\x9e
http://i.voenmeh.ru/kafi5/Kam.loc/inform/UTF-8.htm
всё что тебе нужно, это байтовый массив и memcmp(), прочитай за них, а мы пацкажем.
не идеально, но пока работает. остановился пока на этом варианте, потомучто нужно решать дальнейшую задачу, которая возникает после получения нужного (стартового) пакета байт.
не, я вернусь к этому моменту, просто последующая задача намного важнее и сложнее.
1. Если Вы и дальше будете решать в том же духе, то очень быстро столкнетесь с ситуацией, когда все перестанет работать, а Вы даже не будете знать, с какой стороны подступиться.
2. Прежде, чем приступать к решению сложной задачи, следует добиться идеальной работы тех простых вспомогательных задач, на решение которых опирается сложная.
3. Боюсь Вы еще не готовы к решению сложных задач, если даже простые вызывают у Вас принципиальные сложности.
PS. В целом присоединюсь к рекомендациям:
- тщательно разобраться в теме "кодировки кириллицы",
- особенно обратить внимаение на "utf-8".
вопрос не в том в каком духе я пытаюсь решить задачу, а втом как правильно прописать строку из нужных мне символов.
я тоже считаю эту проблему банальной, но у меня пока не получается, точнее не получается именно с этими символами. но меня добрые люди тыкнули носом и я пытаюсь разобраться.
если вы знаете как это сделать правильно, подскажите, пожалуйста, мне будет проще разобраться.
пока читаю про "utf-8".
Начал бы делать массивом - давно уже всё понял. А со строками и кодировками маяться еще день будешь.
да я с масивов и думал начинать. просто боялся что напутаю, что-то и потом сложнее будет вычислить ошибку.
случайно наткнулся на пример, в котором байты можно собрать в строку, вроде тот же масив но оказалось со своими ньюансами. думал куда еще проще сравнить одну строку с другой. все работает, только эталонную строку не получилось прописать.
как хранить это конечно дело вкуса, я например храню все строки в скетче в однобайтовой Win1251, а в нужных местах уже ее перекодирую и/или сравниваю
случайно наткнулся на пример, в котором байты можно собрать в строку, вроде тот же масив но оказалось со своими ньюансами. думал куда еще проще сравнить одну строку с другой. все работает, только эталонную строку не получилось прописать.
С HEX-представлением правильно подсказали ж: "\x1\x2\x3" и т.д. Все равно данные бинарные, как я понял.
случайно наткнулся на пример, в котором байты можно собрать в строку, вроде тот же масив но оказалось со своими ньюансами. думал куда еще проще сравнить одну строку с другой. все работает, только эталонную строку не получилось прописать.
С HEX-представлением правильно подсказали ж: "\x1\x2\x3" и т.д. Все равно данные бинарные, как я понял.
я видел, у меня нет сейчас возможности проверить.
вопрос не в том в каком духе я пытаюсь решить задачу, а втом как правильно прописать строку из нужных мне символов.
Вопрос в том, что Вы сами не знаете, какие Вам нужны символы и в какой кодировке, а потому помочь Вам толком никто не может - все тыкаются и пытаются что-то подсказать в надежде - а вдруг подойдет.
вопрос не в том в каком духе я пытаюсь решить задачу, а втом как правильно прописать строку из нужных мне символов.
Вопрос в том, что Вы сами не знаете, какие Вам нужны символы и в какой кодировке, а потому помочь Вам толком никто не может - все тыкаются и пытаются что-то подсказать в надежде - а вдруг подойдет.
Ну почему же не знаю? Я вроде конкретно озвучил 5 байт в hex, вот их мне и нужно записать в строку String, с которой я буду сравнивать полученные строки. Предсказуемо, я открыл таблицу с кодировкой символов, нашол нужные мне hex и выписал соответствующие символы и вписал в строку. Но оказалось так можно сделать не совсеми символами, мне обьясни почему, и предложили вариант строки состоящий непосредственно из hex.
Это было краткое описание проблемы. Вот из чего вы сделали вывод, что я не понимаю что мне нужно?
потому что если б сразу начали с массивов - давно бы уже решили задачу.
Все еще боитесь "что-нибудь напутать"? - а с кодировками все просто оказалось, ничего не напутали?
Вы только подтверждаете то, ято я сформулировал выше.
Вы не владеете терминологией, в частности не понимаете разницы между байтом и символом, не понимаете, что строки не могут состоять из байтов, не понимаете, что hex - это способ перевода байтов в строки, не имеющий никакого отношения к самим байтам, и далее по списку...
Соответственно:
1. То, что Вы пытаетесь сформулировать, сформулировано некорректно и допускает несколько возможных взаимоисключающих способов исправления. Причем, какой из них соответствует Вашим желаниям, никто не знает.
2. Появляется обоснованное предположенгие, что то, что Вы пытаетесь сформулировать, на самом деле не отражает того, что Вы хотите сделать. Т.е. Вы избрали явно ошибочный способ реализации желаемого.
Поэтому лучше будет попытаться сформулировать исходную задачу, а не Ваше представление о том, как эта задача может быть решена.
На мой взгляд, если судить по самому первому сообщению, Вам вообще следует избавиться от попыток какой-либо работы со строками и символами, а приходящие байты разбирать конечным автоматом сразу по мере их поступления (не складывая в массив). Это наиболее прямой и универсальный способ. В противном случае Вам нужно будет вводить дополнительные ограничения, например, либо использовать команды строго фиксированной длины, либо вводить какие либо признаки окончания команды (либо байт-терминатор в конце, либо префикс, указывающий длину команды в начале).
А начать в этом случае лучше всего с полного описания системы используемых команд. Описание не обязано содержать полный списк команд (Вы его еще сами можете не знать), но обязано задавать четкую расширяемую структуру команд, включающие как те, что уже есть, так и те, которые будут введены подзднее.
На мой взгляд, если судить по самому первому сообщению, Вам вообще следует избавиться от попыток какой-либо работы со строками и символами, а приходящие байты разбирать конечным автоматом сразу по мере их поступления (не складывая в массив).
ну я человеку еще в сообщении #2 предложил искать во входящем потоке первый байт последовательности, а потом далее читать 4 байта и сравнивать с нужными. В конце концов. 4 байта - это совсем не так много, можно даже просто 4 IF использовать - и не городить эту фигню со строками, которая уводит ТС далеко в сторону от решения.
ну я человеку еще в сообщении #2 предложил искать во входящем потоке первый байт последовательности, а потом далее читать 4 байта и сравнивать с нужными. В конце концов. 4 байта - это совсем не так много, можно даже просто 4 IF использовать - и не городить эту фигню со строками, которая уводит ТС далеко в сторону от решения.
Ну да, мы не знаем, что ТС нужно, поэтому остается только гадать. В частности, гадать, имеют все команды одинаковую длину или нет. Можно, конечно, написать блок, который будет детектировать единственную команду и не будет допускать расширения набора команд. Формально - это будет решением сформулированной ТС задачи, но устроит ли его такое решение?
для: andriano и b707
с терминологию у меня проблемы, не спорю, извените, что зразу не придупредил (хотя некоторые меня поняли)
изначально стояла задача, при получении определенного пакета байт, выполнить определенное действие.
какие именно байты я знаю в формате hex, при необходимости их можно отобразить в другом формате, в том числе и в символах.
способов решение есть несколько, я пока разсматриваю вариант сравнивание двух "строк" (вариант имеющий право на жизнь)
проблема сейчас в прописании эталоннщй строки, состоящей из тех самых байт (пакета байт)
если вы знеете другие варнты, как прописать строку из нужных мне байт, подскажите, пожалуйста. (только кроме тех вариантов, что мне предложили выше)
Buzoff, чем быстрее вы поймете, что ваш вариант "сравнивание двух "строк" для этой задачи не подходит и "права на жизнь не имеет" - тем быстрее вы начнете, наконец, решать свою задачу.
Как прописать строку из нужных вам байт - вам уже посоветовало человек десять. МАССИВЫ.
Подскажите, обязательно для масивов указивать их размер [количество байт]?
Либо явно указывать размер, либо сразу, при иннициализаци, заполнять нужным количеством элементов. В любом случае, длину обычного массива Си после иннициализации менять нельзя.
И да, размер массива указывается в элементах, а не в байтах - ведь в массиве могут быть не только байты.
Общая задача такая:
Принять пакет байт от устройства#1 на сорости 19200бод через програмный uart, и передать этот пакет байт устроству#2 на скорости 10400бод через апаратный uart.
Должно получиться чтото типа конвертера скоростей.
Но для того чтобы пробудить устройство#2, нужно отправить два импульса (ноль 25мс и единицу 25мс) и сразу 5 (или другое количество) стартовых байт, после этого устройство#2 выходит на связь, после чего можно передавать пакеты байты между этими двумя устройствами, через ардуину, как через конвертер скоростей.
Но сериал не может передать такие длинные по 25мс импусы и передает только стартовый пакет байт.
Решение вижу следующее: как только получаю тот самый стартовый пакет байт, через любой пин через диод подтягиваю Rx устройства#2 на 25мс к нулю, потом к плюсу (тоесть отпускаю от минуса) , и только через 25мс шлю тот стартовый пакет байт. Устройство#2 просыпается, и оба устройства начинают общаться между собой на разных скоростях.
Основная задача сейчас, собирать пакеты байт в масивы и перед отправкой, сравнивать с эталлнным масивом (чтоб не пропустить стартовый паке)
А просто так запомнить режим/состояние выхода, потом сделать ему digitalWrite()+delay() и вернуть режим/состояние - не проще?
А просто так запомнить режим/состояние выхода, потом сделать ему digitalWrite()+delay() и вернуть режим/состояние - не проще?
Восновном, устройство#2 с первого раза не просыпается
Пока устройство#1 шлет два импульса и стартовый пакет байт, значит устройство#2 спит. Как только #2 проснется, оно ответит устройству#1 своим пакетом, и #1 перестанет слать импульсы пробуждения.
Так же, может произойти обрыв связи, и #1 снова начнет слать импульсы и стартовый пакет.
Поэтому постоянно нужно сравнивать пакеты, чтоб не пнопустить стартовый.
Или что вы имели ввиду под запомнить режимы?
Да это я так, в приступе overengeneering-a написал. Полагаю, что просто в TX digitalWrite сделать можно без диодов и вторых выходов.
Да это я так, в приступе overengeneering-a написал. Полагаю, что просто в TX digitalWrite сделать можно без диодов и вторых выходов.
Это тоже важный момент. Думал об этом, но не был уверен что зделаю это правильно, и решил через диод и другой пин
Подскажите, как это правильно сделать.
Тх вроде и так изначально настроен на выход.
Как именно эти режимы переключать?
Тоесть, я могу просто через digitalWrite подать ноль, делей 25мс, digitalWrite единица? Он сможет после единицы слать данные?
с терминологию у меня проблемы, не спорю, извените, что зразу не придупредил (хотя некоторые меня поняли)
Все совершенно логично: Вы написали неоднозначную фразу, которую можно понять несколькими способами. Вполне естественно, что часть читателей поняла ее так, как Вы хотели, а часть - по другому.
изначально стояла задача, при получении определенного пакета байт, выполнить определенное действие.
Ну так давайте именно эту задачу и решать.
какие именно байты я знаю в формате hex, при необходимости их можно отобразить в другом формате, в том числе и в символах.
Здесь, опять же, Ваше непонрмание, чем представление байтов отличается от их интерпретации.
В частности, далеко не все байты допускают интерпретацию в виде символов.
способов решение есть несколько, я пока разсматриваю вариант сравнивание двух "строк" (вариант имеющий право на жизнь)
Несколько - да. Имеет преаво нга жизнь - да. Но, тем не менее, это наихужший выбор.
Наихудший - потому, что самый сложный.
В частности, если Вы решите пойти по этому пути, Вам необходимо будет разбираться с кодировкой символов. А это сама по себе достаточно сложная тема. Практика показывает, что более половины новичков с этой темой справиться неспособны. Совсем.
Так что, если Вы пойдете по этому пути, вероятность успеха я предсказываю как менее 50%.
проблема сейчас в прописании эталоннщй строки, состоящей из тех самых байт (пакета байт)
Вот именно: при выбранном Вами подходе элементарная задача превращается в целую проблему.
если вы знеете другие варнты, как прописать строку из нужных мне байт, подскажите, пожалуйста. (только кроме тех вариантов, что мне предложили выше)
Могу только повторить свои рекомендации: забыть о символах и строках и работать с байтами.
А начать (опять же) советую с того, что определиться, какие вообще возможны команды. Хотя бы с тем, все ли команды имеют одинаковую длину или длина команд может быть различной. Без знания этой информации давать Вам конкретные советы совершенно невозможно.