• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Разработка ‘библиотеки’ малого webсервера на esp8266.

AlexMelven

New member
надо к серверу создать аналог ESP TOUCH или типа того. Все-таки управление со смартфона через программу весьма нужная вещь. Чтобы все девайсы в кучу собирать в одной программе и ими управлять. Раз у китайцев это все криво и не работает, надо свое сделать, но рабочее. Тем более что в данном проекте китайские библиотеки более использоваться не будут из-за кривости.
 

pvvx

Активный участник сообщества
Сделал более менее нормальный Modbus RTU RS-485 и шлюз Modbus TCP, но не закончил с HTTP управлением всем этим делом. Будет отдельная прошивка без TCP-UART. Пока не доделал, принимаются заявки-хотелки для такой версии.
Драйвер RS-485 жрет более отложенных 500 запросов - имеет стек запросов и может создавать аналогичный стек ответов (связанных по ID от запросов)... Т.е. полностью мультизадачный и работающий по прерываниям и task-ам...
Используется RX - TX и комбинация их swap, плюс /OUT_ENABLE на любом свободном GPIO (или он отключен). RX и TX можно соединять в один провод для "однопроводного" интерфейса к другому чипу, если не используется драйвер шины RS-485.
Пакет http://www.modbustools.com/download.asp работает без ошибок на любой скорости.
 
Последнее редактирование:

Andy Korg

Moderator
Команда форума
...Пока не доделал, принимаются заявки-хотелки для такой версии....
Дык, этааа..., а можно вынести передачу не обработанных переменных в web_int_callbacks.c и web_int_vars.c ? Например в web_int_vars.c что-то типа такого:
Код:
void ICACHE_FLASH_ATTR web_int_vars(TCP_SERV_CONN *ts_conn, uint8 *pcmd, uint8 *pvar)
{
.....
    else parseHttpSetVar(NULL, 0, web_conn, pcmd, pvar);
#if DEBUGSOO > 5
    else os_printf(" - none! ");
#endif
}
и где нибудь прототип:
Код:
/*
* Write httpvar to variable
*/
uint8 ICACHE_FLASH_ATTR parseHttpSetVar(
pHttpVar *ParentVar, uint8 ParentLen, 
WEB_SRV_CONN *web_conn, uint8 *pcmd, uint8 *pvar);
Ручками конечно то же могу добавить, но как бы освященное автором оно лучше было бы.
 

A_D

Active member
pvvx, а удалось ли побороть странную работу RTS\CTS выводов, которую описал тут или Вы их вообще не используете и сделали вывод RTS на таймере ? (в свое время удавалось на freemodbus под наши миландровские АРМы такое с таймером - работало вполне сносно до 128000 скорости, выше не проверял)
 
Последнее редактирование:

pvvx

Активный участник сообщества
pvvx, а удалось ли побороть странную работу RTS\CTS выводов, которую описал тут или Вы их вообще не используете и сделали вывод RTS на таймере ? (в свое время удавалось на freemodbus под наши миландровские АРМы такое с таймером - работало вполне сносно до 128000 скорости, выше не проверял)
Как описывал так и сделал. Не 100% но 95% :)
Первая демка: https://yadi.sk/d/E_TYGKB_mq224
Исходники пока зажал. Надо причесать, если пойдет...
Основа из описанного тут http://esp8266.ru/forum/threads/modbus-rtu-rs-485.529/#post-11711
~rs485_timeout~ указывает максимально время передачи или приема. Желательно ставить немного менее, чем назначена пауза ответа у запрощающего на Modbus TCP. При неответе устроства на RS-485 через эту задержку будет обработан следующий пакет для передачи из очереди. Максимальная очередь определена размером памяти. Примерно 500 пакетов может находиться в ожидании на передачу - прием ответа на них. Такой пока драйвер - для мультизадачки. Закидываем пакетами, а он исполняет, по мере очереди и вызывает функцию приема после каждого приема ответа. Есть возможность и туда включить fifo оветных пакетов (уже реализовано в драйвере, но для Modbus TCP шлюза не используется - сразу отсылает). Запросный пакет имеет ID - в ответе тоже есть тот ID, после которого принят ответный пакет... Таймаут на передачу может возникнуть при постоянном шуме на линии...
Если ничего не отсылается в rs485, то прием пакетов и передача в Modbus TCP всё равно работает. Выходит типа сниффер.
Пакет http://www.modbustools.com slave через FT2232 дает паузу перед ответом не менее 50 ms - тормоз :(
ModbusTest1.gif
После вывода последнего бита, сигнал RX_ENABLE на драйвер шины протягивается минимум на 24 бита (передел 32 при паузе в 3.5 символа). Затем уже вычисляется остаток на таймере. При скорости более 19200 ставится дополнительная фиксированная задержка. Она тоже частично протягивается на RX_ENABLE, остаток вычисляется на таймере. Эта протяжка от того, что по другому очень криво выйдет на ESP8266 и она задает минимальную задержку между символами сообщений (конкретнее - дискретом по 8 бит, по тому что только так умеет считать паузу аппаратный UART у ESP8266). Мешать протоколу она не должна, т.к. после сообщения следующее должно выйти не ранее полной паузы. Всё описано в теме ModBus RTU (RS-485)
 
Последнее редактирование:

pvvx

Активный участник сообщества
pvvx, понял, Спасибо - постараюсь вечером потестировать.
Там ещё не всё учтено... Полную версию с правильной отработкой очередей сообщений ещё доделываю...
-------------
Сделал и слепил пока так:
(RS-485 = 256000 bps - больше софт на компе не может)
Временная ссылка на использованную в видео тестовую прошивку -> https://yadi.sk/d/u0roQ8IZmuvf7
Тему другую что-ли открывать? В RS-485 и далее с ним "свалка" не особо главная уже :)
Надо уже функции ПЛК и встроенный в Web редактор программ делать...
Ядро RS-485 пашет до 1 мегабита, но проверить нечем. На низкую скорость - 1200 baud гонял в том, что на видео. Под рукой пока всё тормозное, а доставать и раскладывать старые тестовые платы - лень...
 
Последнее редактирование:

PycLan

New member
Добрый день!
aloika, в какой момент (в Вашем примере UARTCommander3) можно передавать из UART в WEB параметры Enable,speed,sensivity, setting_time, current_time?
 

PycLan

New member
Возможно проблемы с включением питания - сбросом и инициализацией.
Это возможно от путаницы старта после deep-sleep, для ускорения инициализации WiFi. Надо глядеть....
Сперва все работало, но как только закоментил не нужное в user_config.h, начались такие же проблемы. Откатился на 054a...
 

aloika

Active member
в какой момент (в Вашем примере UARTCommander3) можно передавать из UART в WEB параметры Enable,speed,sensivity, setting_time, current_time?
Честно говоря, не совсем понял вопрос. Пример в части UART->WEB работает так:

1. Заводим таймер, который через каждые 0,1 сек запускает parse_rx_buf(void)
2. Эта функция вычитывает приемный буфер UART и распарсивает то, что туда пришло за последние 0,1 сек.
3. Если туда пришла определенная ранее строка (а в этой строке содержатся все значения параметров), то заполняются поля структуры:

Код:
pcsw->enable=comm[2];
pcsw->speed=comm[3];
pcsw->sensivity=comm[4];
pcsw->curr_time=(comm[6]<<8)+comm[5];
pcsw->setting_time=(comm[8<<8)+comm[7];
Если туда пришло что-то не то, какой-то мусор или некорректное что-то, то поля структуры не меняются.

4. Теперь мы можем в любой момент прочитать поля этой структуры с тем, чтобы, например, отобразить их в WEB. Для этого "родную" функцию web_int_callback дополняем своей функцией. В самом конце web_int_callback пишем:

Код:
else swbd_web_int_callback(web_conn, cstr); //tcp_put('?');
Теперь можно определить свою функцию swbd_web_int_callback(web_conn, cstr) и прописать там свои колбэки. Можно, конечно, было всё это в основную функцию web_int_callback затолкать, но мне показалось красивее отделить "родное" (pvvx'а) от самодельного.

5. Определяем:

Код:
void ICACHE_FLASH_ATTR swbd_web_int_callback(WEB_SRV_CONN *web_conn, uint8 *cstr)
{
     if(!os_memcmp((void*)cstr, "swbd_", 5)) {
                      cstr+=5;
                      if(!os_memcmp((void*)cstr, "enable", 6)) tcp_puts("%u", pcsw->enable);
                      else if(!os_memcmp((void*)cstr, "speed", 5)) tcp_puts("%u", pcsw->speed);
                      else if(!os_memcmp((void*)cstr, "sensivity", 9)) tcp_puts("%u", pcsw->sensivity);
                      else if(!os_memcmp((void*)cstr, "setting_time", 12)) tcp_puts("%u", pcsw->setting_time);
                      else if(!os_memcmp((void*)cstr, "curr_time", 9)) tcp_puts("%u", pcsw->curr_time);
                      else tcp_put('?');
                          }
}
6. Ну и все. Теперь в тексте веб-странички можно написать, например, ~swbd_speed~, и на месте этой записи на реальной страничке отобразится текущая скорость.

Прилагаю доработанный пример. Он на основе более новой версии "свалки" и там в корне есть файл качалка.txt, где написано, что нужно изменить в исходной "свалке", чтобы получить эту функциональность. Таким образом, если хотите, можете легко адаптировать самую новую версию "свалки". Учтите только, что функционал TCP<->UART при этом отключается, так как мне он не нужен.

Там же пример странички (my.htm) c примером нового функционала.

Конечно, было бы, наверное, красивее из приемного буфера данные вычитывать по прерываниям, а не по таймеру. Но у меня ума не хватило, как это корректно сделать, положительного результата так и не смог добиться. Но меня и так устраивает, работает стабильно (при моей скорости поступления данных в UART).
 

Вложения

PycLan

New member
Спасибо, смотрю.
Просто отправляю для примера A5B50000000000000000, на странице ничего не меняется.
 

aloika

Active member
Ну тогда раскомментируйте в parse_rx_buf одну из строчек

//os_printf("%02x ",ch);
// uart1_put_char(ch);

и посмотрите, что реально вы принимаете в UART. До парсинга еще. Может, там совсем и не то, что вы отправляете.

Только потом обратно закомментируйте. А то это дело будет тормозить WEB.
 

PycLan

New member
Да в UART1 летит, то что отправляю с URT0, но на страницу это не доходит.
Отображает всегда дефолтные параметры: Enable: 0, speed: 4, sensivity: 2, setting_time: 15, current_time: 15.
 

aloika

Active member
Хм. У меня-то работает как-то... правда сейчас проверить не могу, но работало. В серийном устройстве прошивка именно эта, web-часть другая только.

ну выведите в уарт1 значения этих величин, раскомментируйте там

// os_printf("enable is %04x, speed is %04x, sensivity is %04x, curr_time is %04x, setting_time is = %04x\n" , pcsw->enable, pcsw->speed, pcsw->sensivity, pcsw->curr_time, pcsw->setting_time );

что будет писать?

посмотрите, может там в веб-части ошибка? оно может и не опрашивает? может я что-то там изменил когда...

Если не получится у вас, приду домой, проверю (залью этот веб). Но это часа через 4 будет, не раньше.
 
Последнее редактирование:

PycLan

New member
ну выведите в уарт1 значения этих величин, раскомментируйте там

// os_printf("enable is %04x, speed is %04x, sensivity is %04x, curr_time is %04x, setting_time is = %04x\n" , pcsw->enable, pcsw->speed, pcsw->sensivity, pcsw->curr_time, pcsw->setting_time );

что будет писать?
Тишина...
посмотрите, может там в веб-части ошибка? оно может и не опрашивает? может я что-то там изменил когда...
Enable: 0, speed: 4, sensivity: 2, setting_time: 15, current_time: 15 - а эти значения из ESP или web?
 

PycLan

New member
Получается, что почему-то даже на A5 условие не выполняется, не выводится ни одно сообщение STROKA- .. только копия передачи по uart1_put_char(ch);
Код:
uart1_put_char(ch);


         if ((ch==0xA5)&&(curr==0)) {comm[curr]=ch; curr++;  os_printf("STROKA-1\n"); continue;}
         else if ((ch==0xB5)&&(curr==1)) {comm[curr]=ch; curr++;  os_printf("STROKA-2\n"); continue;}
         else if ((curr>=2)&&(curr<9)) {comm[curr]=ch; curr++;  os_printf("STROKA-3\n"); continue;}
         else if ((curr==9)&&(ch==(uint8)(comm[2]+comm[3]+comm[4]+comm[5]+comm[6]+comm[7]+comm[8])))
                   {
             os_printf("STROKA-4\n");
...
 

aloika

Active member
Вот, всё работает.

В терминале в строке отправки надо писать $A5$B5$01$01$01$01$01$01$01$07
Если, конечно, этим терминалом пользуетесь.

Безымянный.png Безымянный1.png
 
Сверху Снизу