Парсинг строки адреса Arduino в режиме веб-сервера
- Войдите на сайт для отправки комментариев
Чт, 11/04/2013 - 09:47
Имею arduino nano и enc28j60 модуль к нему. Мой проект - это очередная ethernet метеостанция, но не суть )
В процедуре Loop идет обработа запросов и выдача результатов:
void loop() { char* httpurl; if (httpurl = e.serviceRequest()) { if (strcmp(httpurl, "") == 0) { e.print("<A HREF='/'><H1>nano v3</H1></A>"); e.print("<br>"); e.print("<A HREF='?=temp'>Show Temperature</A>"); e.print("<br>"); e.print("<A HREF='?=ip'>IP Settings</A>"); e.print("<br>"); e.print("<A HREF='?=relay'>Relay Switch</A>"); } if (strcmp(httpurl, "?=ip") == 0) { e.print("<html>"); e.print("<head>"); e.print("</head>"); e.print("<body>"); e.print("<A HREF='/'><H1>nano v3</H1></A>"); e.print("<br> IP (loaded from ROM): <br>"); e.print("<form name = 'form1' action = 'setip' method = 'get'>"); e.print("ip: <input type = 'a' name = 'aaa' value = "); e.print(EEPROM.read(0)); e.print(">"); e.print(". <input type = 'b'; name = 'bbb' value = "); e.print(EEPROM.read(1)); e.print(">"); e.print(". <input type = 'c'; name = 'ccc' value = "); e.print(EEPROM.read(2)); e.print(">"); e.print(". <input type = 'd'; name = 'ddd' value = "); e.print(EEPROM.read(3)); e.print(">"); e.print("<br>"); e.print("<input type ='submit'; value = Apply >"); e.print("</form>"); e.print("</body>"); e.print("</html>"); } e.respond(); }
При запросе http://ip-адрес/?=ip выдается страничка с 4 полями и загруженными в нее значениями из eeprom. Если вписать свои значения нажать на кнопку Apply, то сформируется ссылка вида:
http://192.168.0.33/setip?aaa=192&bbb=168&ccc=0&ddd=34
Соответственно в httpurl передается значение:
setip?aaa=192&bbb=168&ccc=0&ddd=34
Задача вытянуть числа 192, 168, 0 и 34 в arduino для внутренней обработки - сохранения в eeprom. Есть библиотека TextFinder, но она не работает с моей библиотекой ethernet-модуля.
Также не совсем понимаю, как из char* httpurl преобразовать в String.
Логику работы парсинга себе представляю себе так:
1. поиск по маске, например, "aaa="
2. вычленение значения после выражения до символа "&" или окончания строки или можно что-то в стиле 3 символа после найденного значения+применение функции atoi
Если бы вы первые слова своей темы "Парсинг строки" вбили в поиск в верхенм правом углу, то второй же ссылкой вам выдало-бы тему где обсуждалось ровно то же самое. Причем буквально пару дней назад (а это значит что даже без поиска, просто посмотрев темы последние - можно было найти).
Разбор тестовой строки | Аппаратная платформа Arduino
Извините, подобную тему искал раньше даты создания темы от 4 апреля. Спасибо!
Единственный коммент - в той теме параметры в урле топикстартер разделяет запятыми и дветочиями. А у вас - амперсанды и знаки равно. "По стандартам" - ваш вариант более правильный/традиционный. Его легче понять просто посмотрев на урл любому веб-разработчику без доп. объяснений.
Так что там вы посмотрите только "принцип", но используйте свои разделители & и =.
>преобразовать в String.
Да просто передайте в конструктор
Но... лично я вообще предпочитаю не использовать класс String. Во первых "место", во вторых он "только в ардуине существует" и то используется редко в серьезном коде.
Так что лучше изначально привыкать работать с char* (обычные сишные строки) string
Все встроенные обычные функции сишные atoi, stkok и т.п. - работают именно с такими строками, а не String объектом.
Кручу-верчу функцию из найденой темы. При таком варианте возвращаются значения:
но возвращает только:
Ну во первых, не правильно "аналогию провели". Двоеточия из того кода - соотвествуют вашим знакам равно. То есть в for-ре у вас
strtok(NULL,
"="
)
Вот вам и будет парсинг имен параметров. А не захват "имя+значение" сразу. Но, у вас начнется потеря значений.
Вы же код из строк 41-42 выкинули, а именно он отвечает за парсинг значений. Вам он тоже нужен. Только там он ищется по запятой, а у вас амперсанд.
Вообщем из того кода в ваш переход делается чере замену ":"-->"=" и ","-->"&"
Верно. Не понимаете. Но в двух словах тут не расскажешь. загуглите какой-нибудь учебник по C/C++ и почитайте разделы "указатели/ссылки" и "строки". Возможно даже несколько учебников прийдется прочитать. Тема действительна сложная для понимания (но когда понял - все просто) не каждый автор наглядно может объяснить. А тема важна. Без нее что-то сложней "мигаем диодом" - трудно. А в работе со строками - вообще никак.
P.S. И наверное луче было продолжать дисскуссию в той ветке. Что-бы "не размазывать". Тем более что я планировал на выходных туда дописать альтернативу atoi. Да и топикстартер той ветки - тоже мог бы вам подсказать. Он то понял "как оно работает". Да еще говорил что "разобрался с указателями", может подскажет где почитал (я-то уже естественно не помню где про это нормально написано).
В первоначальном виде я в функцию наоборот запихал свои & и = . Теперь все работает.
Оставлю для истории правильный вариант:
Огромное спасибо.
А где в этом правильном варианте парсинг имен параметров? или они вам не нужны?
В моем случае это не особо принципиально, но по-хорошему проверка нужна (действительно ли, к примеру передается параметр 'aaa', а не 'cdf'). Только я опять затрудняюсь с решением данной задачи.
Ну, проверять - это уже потом. Вначале грамотно выпарсить нужно. И даже умея работать со строками - есть там с чем повозится.
Вообщем в любом случае "вначали читать книжку про указатели/ссылки и строки", в любом случае это пригодится (а без понимания - даже если дадут вам готовый код - будет все рушится при малейшей попытке что-то изменить).
Пока сделал такой костыль. Выдает структуру struct port_param_t {String name;int value;};