Парсер параметров, приходящих в Stream

Тема в разделе "Arduino & Shields", создана пользователем DIYMan, 19 июл 2016.

  1. DIYMan

    DIYMan Guest

    Приветствую!

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

    Собственно, я тут с вопросом: понятное дело, что надо учиться и всё такое, для того, чтобы понимать, как оно устроено и как фунциклирует программирование вообще. Но! Вот подзадалбывает иногда, аж жуть. Можете сказать: задалбывает - не отвечай, и будете правы. Однако, есть и другой подход: написать и выложить сюда простейший парсер команд с минимальными настройками, который будет работать с Stream* и выдавать вовне нужные значения, например: пришло в порт "var1=12345\r\n", и парсер выдал, что есть команда с именем "var1" и параметром "1234". Т.е. чтобы в парсере настраивался разделитель команды и параметра, а также разделитель команд.

    Что скажете - стоит потратить часок времени и выложить сюда, по сути, велосипед? С надеждой, что его юзанье поможет новичкам не задавать в стопицотый раз вопрос "почему не работает?". Или - сделаем только хуже, убрав ещё один бастион, помогающий обучаться и понимать, как оно работает?
     
    9xA59kK нравится это.
  2. DIYMan

    DIYMan Guest

    В общем, вот вам всем, смотрите приложенный архив. Тестировал, посылая в Serial параметры со значениями:

    param1=1234\\r\n
    param1=value1&param2=value2&param3=value3\r\n
    param1=\r\n

    Разделитель имени и параметра - настраиваемый. Разделители команд между собой - настраиваемые. Времени на написание потратил - минут 10. Класс снимает все головняки с получением команд с любого Stream, кмк.

    Будут замечания - пишите, а я пока буду отсылать в эту тему всех, кто сталкивается с проблемой вычитки данных из Stream и разбором их на пары "ключ-значение".

    З.Ы. Код неоптимальный, кому надо - сам допилит (лично мне совсем не нравится постоянное дёрганье strlen по приходу команды, но это мелочи, по сути).

    З.З.Ы. Тестовый скетч - в комплекте.
     

    Вложения:

    9xA59kK, Securbond, Tomasina и 3 другим нравится это.
  3. ИгорьК

    ИгорьК Гуру

    Но не поможет...
     
  4. DIYMan

    DIYMan Guest

    Это точно :eek: Но я попытаюсь, хотя бы часть головняков снять по вдалбливанию одного и того же. И это, с одной стороны, даже хорошо - чем меньше будет людей, понимающих, как оно работает, тем больше у мну будет работы :D
     
    FlameWind нравится это.
  5. Tomasina

    Tomasina Сушитель лампочек Модератор

  6. AlexU

    AlexU Гуру

    Как показывает практика, не малое количество "программистов" вместо того, что бы попробовать поискать решение задачи, сразу идут на форум и задают вопрос. Поэтому Ваше предложение хорошее, но вскоре тема "уйдёт" далеко и просматривать её больше ни кто не будет, а подобные вопросы всё равно на форуме будут появляться.
    Как вариант -- заведите аккаунт на https://github.com/ (если ещё не завели), и выкладывайте свои наработки. А как только появиться очередной "программист", то сразу ему ссылку на проект, где он сможет получить полезную информацию.

    Несколько советов:
    1. лучше использовать связку файлов *.cpp + *.h, а не *.ino + *.h;
    2. в конструктор передаётся поток (Stream), а в функцию 'begin' параметры парсинга -- скорее следует сделать наоборот -- в конструктор передавать параметры парсинга, а в функцию 'begin' поток, т.к. параметры парсинга задаются один раз, а потоков, которые надо одинаково парсить, может быть несколько;
    3. с классом String (поле workBuffer) надо быть поаккуратней, этот класс динамически выделяет память под хранение строк, а с динамическим выделением память в AVR-ках нужно работать осторожно.
     
    AlexVS и ИгорьК нравится это.
  7. DIYMan

    DIYMan Guest

    В *.ino там просто тестовый пример, сам класс - весь в *.h реализован ;)
    Ну тут, что называется, на любителя ;), писал по-бырому, как уже упоминал.
    Ипстественно, но это уже не моя головная боль - не буду же я все-все-все проблемы решать ;) Кто повдумчивей - поймёт, что надо бы сделать guard на максимальную длину буфера, как минимум.

    З.Ы. Аккаунт на гитхабе есть (проект в подписи), но выкладывать туда сии поделия - надо подумать хорошо :D Впрочем, в вашем предложении есть здравое зерно.
     
  8. DIYMan

    DIYMan Guest

  9. ИгорьК

    ИгорьК Гуру

    Здесь с Вами не согласился бы.
    Юзвери делятся на тех, кто
    • "дайте мне библиотеку и как ее соединить";
    • интересно, как он это сделал;
    • это и без него известно.
    Первые думать не будут в силу привычки, вторые не подумают в силу неопытности. А опытным и так это понятно.
    Поэтому, если уж объясняете - лучше уж до конца (во имя маленькой, но очень благодарной второй группы :) )
     
    9xA59kK и DIYMan нравится это.
  10. DIYMan

    DIYMan Guest

    Дык вроде указал, что для совсем кошерности - надо просто вставить ещё проверку, чтобы длина буфера, в которую складываем символы, была ограничена каким-то разумным значением, и если она (длина) превышает это разумное значение - принудительно чистить буфер.

    Это нужно для предотвращения "спама", скажем так - когда в поток ооочень долго не приходит разделитель команд. Делов - одну проверку в update вставить, любой справится, я думаю.
     
  11. DIYMan

    DIYMan Guest

    Securbond и ИгорьК нравится это.
  12. Securbond

    Securbond Гуру

    А описание на ангЕльском это политика гитхаба? Или по привычке? Тут очень много тех кто с Русским то ещё не подружился))))
    А от себя, респект и уважуха за терпение и помощь.
     
    9xA59kK нравится это.
  13. DIYMan

    DIYMan Guest

    Да как-то решил, что на буржуйском интернациональней, что-ли :) Если что - всё равно вопросы будут задавать, отвечу, чего уж там ;)
     
  14. 9xA59kK

    9xA59kK Гик

    Да русский это всегда хорошо, особенно в комментариях .Ну на буржуйском многие по русски и пишут, чтобы свои не мучились, а вот буржуи пусть голову ломают.
    ps\ для меня русский это и есть интернациональный.