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

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

Sanya_kv

New member
В программе терминала. Она имеет десятки ошибок.
Не факт. Возможно проблема и в LwIP стеке. Находил описание проблемы на форуме electronix.ru. Суть проблемы в следующем, при передаче пакетов по WiFi или сложной топологии по Ethernet, пакеты могут приходить в разном порядке. Насколько я понял у LwIP по приёму есть проблемы, если пакеты приходят не в том порядке, котором были переданы. К сожалению самому эту проблему пока проверить не удалось.
 

pvvx

Активный участник сообщества
Не факт. Возможно проблема и в LwIP стеке. Находил описание проблемы на форуме electronix.ru. Суть проблемы в следующем, при передаче пакетов по WiFi или сложной топологии по Ethernet, пакеты могут приходить в разном порядке. Насколько я понял у LwIP по приёму есть проблемы, если пакеты приходят не в том порядке, котором были переданы. К сожалению самому эту проблему пока проверить не удалось.
Нашел - опять не работает ets_timer_arm_new(&uart0_rx_buf_timer, 400, 0, 0); надо подобрать другое число :)
Но если использовать RTS - всё будет Ok.
Так всё хорошо: ets_timer_arm_new(&uart0_rx_buf_timer, 0, 0, 0); :)
Но иногда оно не запускает таймер и передача отключается навсегда в данном соединении. Походит на очередной привет от Espressif...
А требуется задержка до 128 chasr * 10 bits / 3000000 Baud = 0.000427 seс , чтобы поддерживать до 3Mbaud. Меньше можно, но лишний раз грузит CPU разборками с буфером.... Лучше всего - реакция в 200us на накопление символов в fifo rx UART перед сливом в TCP и чтобы не раздражало ожидание + нехилый джиттер ets_timer.
При ets_timer_arm_new(&uart0_rx_buf_timer, 0, 0, 0):
test.gif
Прием-передача текстового файла. Но в данной программе не работает дуплекс и тоже куча ошибок (обрывки по буферам COM). Зато пауз в межсивольную прием/передачу на COM не вставляет...
При частом использовании ets_timer_arm_new(&uart0_rx_buf_timer, 0, 0, 0) возникают пропуски - он не всегда отрабатывает. С числом 400us и другими подобранными - всегда. :)
Необходима смена алгоритма передачи принятых байт, чтобы в нем не участвовало ничего от Espressif. Для этого надо переписывать систему обращения к LwIP, используемую Web сервером (а лень плодить разные драйвера).
И тама правильно написано:
Цитата(akorud @ Aug 29 2014, 17:23)
LwIP - да, но надо понимать внутренности, конфигурацию и как все работает. Применяем в рабочих промышленных проектах, устройства подключаются к публичному Интернету. Уровень поддержки socket() настолько доработан, что libmicrohttpd пошла с пол-пинка. TFTP сервер и клиент из OpenBSD портировались за день.
ИМХО, из бесплатных лучше нет.
uIP - нет. В смысле пробовали и запретили к использованию.
Платформы - от M3 до ARM11.

Sanya_kv - Как вы хотите работать без сигнала RTS, если соединение, к примеру, идет через GSM? Там задержки более 5 сек подтверждения TCP пакетов :)
 
Последнее редактирование:

Algis

New member
Не факт. Возможно проблема и в LwIP стеке...
В этом случае нет, быстрая проверка показала, что 10кб данных от wifi на uart прходят без проблем, а от uart на wifi уже нет.
Данные теряется в sent_uart_rx_buf() недойдя до буфера стека,
здесь:

conn->ptrtx[conn->cntro++] = READ_PERI_REG(UART_FIFO(UART0));

проходят только остатки строки
 

pvvx

Активный участник сообщества
В этом случае нет, быстрая проверка показала, что 10кб данных от wifi на uart прходят без проблем, а от uart на wifi уже нет.
Данные теряется в sent_uart_rx_buf() недойдя до буфера стека,
здесь:

conn->ptrtx[conn->cntro++] = READ_PERI_REG(UART_FIFO(UART0));

проходят только остатки строки
Проверка показала, что ets_timer_arm_new(&uart0_rx_buf_timer, 100, 0, 0) = ets_timer_arm_new(&uart0_rx_buf_timer, 100, 0, 1), т.е. всегда в миллисекундах.
Кто написал эту глупость в osapi.h ?
Код:
#ifdef USE_US_TIMER
#define os_timer_arm_us(a, b, c) ets_timer_arm_new(a, b, c, 0)
#endif
#define os_timer_arm(a, b, c) ets_timer_arm_new(a, b, c, 1)
100ms.gif
Вот у вас символы и выпадают, т.к. не смотрите RTS, что их приема нет. А считывание завязано на таймер, который не работает как описано и дает вместо 100us 100ms, за которые буфер fifo UART rx уже заполнен.
Сменил исходники.
 
Последнее редактирование:

Algis

New member
Вот у вас символы и выпадают, т.к. не смотрите RTS, что их приема нет. А считывание завязано на таймер, который не работает как описано и дает вместо 100us 100ms, за которые буфер fifo UART rx уже заполнен.
Сменил исходники.
Работает отличнно! попробовал 100кб в обоих направлениях много раз, без потерь.
 

pvvx

Активный участник сообщества
Работает отличнно! попробовал 100кб в обоих направлениях много раз, без потерь.
Допилил RTS/СTS, как и писал ранее. С TCP2COM вроде всё, если ошибок не всплывет. Но скорость ограничена примерно 1Mbaud (не проверял, но будет просто выставляться RTS, когда таймер будет отрабатывать слишком долго и при плохой связи аналогично). В системе SDK нет таймеров на us, а использовать на это аппаратный не желательно, т.к. нужен для других целей. После выставления RTS в fifo rx свободно 15 символов... Общие буфера приема и передачи на 2 максимальных пакета TCP (2*MSS = 3120 байт). Приемный может быть больше (такова специфика, чтобы не потерять данные принимаемые по TCP и увеличивается до размера стека, т.к. в начале соединения он ограничен значением по умолчанию - что-то порядка чуть более 5кило для ESP8266 и когфига LwIP от Espressif-цев). При забитом буфере приема, соединение просто так не закрыть клиенту TCP пока UART (tx) не передаст большую часть данных из буфера (тоже такова специфика TCP и LwIP при малом размере стека и при низких скоростях UART, и если все-таки как-то :) 'абырвалг' соединение с полным буфером (методами brig), то новое соединение не открыть, пока не вылезут символы через UART и не отработает увеличение окна приема TCP...).
RTS/CTS работают при включенном 'flow control'. Тормозят ввод/вывод. При неактивном соединении RTS указывает, что ввода нет.
Предел отжирания памяти в heap TCP2COM до 9000 байт при всех забитых буферах:
TCP2COM_max_heap.gif
 
Последнее редактирование:

Algis

New member
Допилил RTS/СTS, как и писал ранее. С TCP2COM вроде всё, если ошибок не всплывет.
Супер!

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

Имея такой мост, легко сделать программу упраления какого нибудь устройства одним HTML/Javascript поместив все необходимое в WEBFiles

TCP2COM не подходят дла таких целей, потому что из Javascript пока нет возможности создавать "чистое" TCP соединение, XMLHttpRequest и WebSockets в браузерах имеет много ограничений из-за соображений безопасности.
 
Последнее редактирование:

A_D

Active member
Ну, хоть и ветка про SDK - приведу результаты маленького эксперемента тут, так сказать с чем больше всего связан с того и начинаю - с железа :)
как я писал выше, хотя никого не затронуло - про разводку и емкости в питании мне не понравилось. Так же была фраза в каком то из топиков (кажется Ваша, pvvx ) - что мол схемы дети рисуют, что по модулям оч близко к правде.
Итак, что я сделал:
взял сборку резисторов 8,2к (что было под рукой) и подтянул вывод 13 (MTDO) к земле, а выводы 32 (RST), 7 (CHEN), 15 (GPIO0) к питанию. Так же на вывод 7 (CHEN) подключен конденсатор 10nF на землю.
Снизу платы на дорожке питания и земляном полигоне снята маска и напаяна цепочка конденсаторов такого номинала: 0,1uF + 10nF + 2,2nF

Попробовал на обоих модулях это сделать. Результат:
-Значение Power на рабочем ранее модуле теперь как вкопанное почему то - 4,43 . Работает так же хорошо, как и было. Напряжение на выводе VDD_RTC - 1,1245v
-Ранее сильно гревшийся модуль теперь перестал резко грется при попытке подключения к нему и теперь вполне стабильно работает (хотя всеравно чуть теплее чем первый) и значение Power так же осталось 4,45. Подключение к этому модулю теперь стабильное и быстрое. Напряжение на выводе VDD_RTC - 1,1275v

Такие результаты.
 

Вложения

Последнее редактирование:
  • Like
Реакции: MSW

shadows

New member
Проверка показала, что ets_timer_arm_new(&uart0_rx_buf_timer, 100, 0, 0) = ets_timer_arm_new(&uart0_rx_buf_timer, 100, 0, 1), т.е. всегда в миллисекундах.
Кто написал эту глупость в osapi.h ?
Код:
#ifdef USE_US_TIMER
#define os_timer_arm_us(a, b, c) ets_timer_arm_new(a, b, c, 0)
#endif
#define os_timer_arm(a, b, c) ets_timer_arm_new(a, b, c, 1)
В IOT SDK есть кусок
Код:
3.2.9. system_timer_reinit
Function: Reinitiate the timer when you need to use microsecond timer
Not es: 1. Define USE_US_TIMER;
2. Put system_timer_reinit at the beginning and user_init in the first 
  sentence.
Function definition:
void system_timer_reinit (void)
вот кусок дизасма Libmain.a, (не совсем ясно че лежит в dword_7E8 ) но похоже перконфигурируется делитель таимера. после этого возможно все заработает.
Код:
.irom0.text:000007E5                 .byte 0, 0, 0
.irom0.text:000007E8 dword_7E8       .int 0                  ; DATA XREF: system_timer_reinitr
.irom0.text:000007EC dword_7EC       .int 0x60000600         ; DATA XREF: system_timer_reinit+Br
.irom0.text:000007F0
.irom0.text:000007F0 ; =============== S U B R O U T I N E =======================================
.irom0.text:000007F0
.irom0.text:000007F0
.irom0.text:000007F0 system_timer_reinit:
.irom0.text:000007F0                 l32r            a5, dword_7E8
.irom0.text:000007F3                 movi.n          a4, 0
.irom0.text:000007F5                 s8i             a4, a5, 1
.irom0.text:000007F8                 movi            a2, 0x84
.irom0.text:000007FB                 l32r            a3, dword_7EC
.irom0.text:000007FE                 memw
.irom0.text:00000801                 s32i.n          a2, a3, 0x28
.irom0.text:00000803                 ret.n
.irom0.text:00000803 ; End of function system_timer_reinit
 

pvvx

Активный участник сообщества
В IOT SDK есть кусок
Код:
3.2.9. system_timer_reinit
Function: Reinitiate the timer when you need to use microsecond timer
Not es: 1. Define USE_US_TIMER;
2. Put system_timer_reinit at the beginning and user_init in the first
  sentence.
Function definition:
void system_timer_reinit (void)
Страшновато переинициализировать таймер - вдруг повлияет на уже работающие процедуры в SDK. Они все пользуются timer_insert() из Bios ROM.
Код:
40240bf0 <system_timer_reinit>:
40240bf0:    fe8251           l32r    a5, 402405f8 <xPortGetFreeHeapSize+0x50>  [0x3ffe8000] =  0x01010101
40240bf3:    040c         movi.n    a4, 0
40240bf5:    014542           s8i    a4, a5, 1
// 3ffe8000: 01 01 01 01 00 00 cd ab 01 00 00 00 ec 05 00 00
40240bf8:    84a022           movi    a2, 132
40240bfb:    fd9031           l32r    a3, 4024023c <_irom0_text_start+0x23c>  0x60000600
40240bfe:    0020c0           memw
40240c01:    a329         s32i.n    a2, a3, 40   [0x60000628] до этого = 0x00000088, пишет 0x84
40240c03:    f00d         ret.n
Она меняет "предшкалер" у таймера с DIVDED_BY_256 на DIVDED_BY_16 и меняет какой-то флаг в памяти. До 3ffe8000: 01 01 01 01 , после 3ffe8000: 01 00 01 01
До этого таймер работает с шагом в 0.0000032 сек (3.2us), а после в 200ns.
-------
Вставил в исходники, включил расчет задержек в TCP2COM ... счас заменю свалку...
 
Последнее редактирование:

pvvx

Активный участник сообщества
Ну, хоть и ветка про SDK - приведу результаты маленького эксперемента тут, так сказать с чем больше всего связан с того и начинаю - с железа :)
как я писал выше, хотя никого не затронуло - про разводку и емкости в питании мне не понравилось. Так же была фраза в каком то из топиков (кажется Ваша, pvvx ) - что мол схемы дети рисуют, что по модулям оч близко к правде.
Это очень хорошо, что дети рисуют - пусть развиваются, но верить таким рисункам не стоит :)

Итак, что я сделал:
взял сборку резисторов 8,2к (что было под рукой) и подтянул вывод 13 (MTDO) к земле, а выводы 32 (RST), 7 (CHEN), 15 (GPIO0) к питанию. Так же на вывод 7 (CHEN) подключен конденсатор 10nF на землю.
Снизу платы на дорожке питания и земляном полигоне снята маска и напаяна цепочка конденсаторов такого номинала: 0,1uF + 10nF + 2,2nF

Попробовал на обоих модулях это сделать. Результат:
-Значение Power на рабочем ранее модуле теперь как вкопанное почему то - 4,43 . Работает так же хорошо, как и было. Напряжение на выводе VDD_RTC - 1,1245v
-Ранее сильно гревшийся модуль теперь перестал резко грется при попытке подключения к нему и теперь вполне стабильно работает (хотя все равно чуть теплее чем первый) и значение Power так же осталось 4,45. Подключение к этому модулю теперь стабильное и быстрое. Напряжение на выводе VDD_RTC - 1,1275v
Такие результаты.
Поменяйте значение делителя для пересчета значений adc vdd в напряжение.
Надо найти, где сидит встроенный корректор. Возможно он прошит и в ROM или "OTP" блоках чипа и вообще не устанавливалось. Партии чипов разные и разное показание.
 

pvvx

Активный участник сообщества
была бы полезная еще одна простая фунциональность связанная с UART, чтобы подав строку на специальную GET или POST переменную она передавалась в UART, а ответ возвращался как содержание страницы, таким способом получится мост HTTP - UART.
Всё в ваших руках. Впишите в исходники :)
Оно и счас без моста работает. Пример приведен в sample.htm. Там прямо в регистры UART пишет :)
Вы можете находу сменить и уровни защелок RTS на другое ко-во символов в fifo и т.д. Они устанавливаются только при инициализации...
Отдача страниц из UART - это как-то криво в связи со скоростью UART и неопределенностью, где конец и сколько куда. Для этого требуется спецфический формат передачи и т.д. Т.е. всё становиться заточенным на определенный проект, а тут просто свалка часто встречающихся вариантов...
Делать Telnet аля HTTP таким образом тоже не красиво.
Для отдачи логов надо резервировать статический буфер в памяти, который отображать на странице, путем добавления строк из него, что пока не охота, т.к. связано с многозадачностью - соединений может быть много и все они должны работать с этим буфером совместно (к примеру UART то однозадачный...).
 
Последнее редактирование:

Algis

New member
Всё в ваших руках. Впишите в исходники...
Сделаю, но ваши знания SDK и опыт в прогаммировании на С лучше моих, и то что вы делаете доступно всем в исходниках "из коробки".

Отдача страниц из UART - это как-то криво в связи со скоростью UART и неопределенностью, где конец и сколько куда. Для этого требуется спецфический формат передачи и т.д. Т.е. всё становиться заточенным на определенный проект, а тут просто свалка часто встречающихся вариантов...
Это получилось бы заточенным для JSON формата, родного для javascript приложений и для всего веба, которые имели бы доступ к UART через AJAX запрос.
Такая функциональность, для людеи знающих javascript лучше чем С, дала бы возможность меньше вмешиваясь в прошивку сделать приложение управления самодельных устройств.
 
Последнее редактирование:

pvvx

Активный участник сообщества
Сделаю, но ваши знания SDK и опыт в прогаммировании на С лучше моих, и то что вы делаете доступно всем в исходниках "из коробки".
У меня нет опыта программирования на С. Я пишу на всех языках программирования, которые необходимы и лучше подходят для реализации проектов. По этой причине многое в них не знаю - только поверхностно. По СИ у меня не было ни одной книжки... Я считаю, что у вас возможностей больше - вся информация ныне есть в инет.
Это получилось бы заточенным для JSON формата, родного для javascript приложений и для всего веба, которые имели бы доступ к UART через AJAX запрос.
Такая функциональность, для людеи знающих javascript лучше чем С, дала бы возможность меньше вмешиваясь в прошивку сделать приложение управления самодельных устройств.
JSON формат не актуален - он не поддерживает POST, т.е. устарел и не является 'родным' для javascript.
https://ru.wikipedia.org/wiki/Cross-origin_resource_sharing
До недавнего времени основным способом преодоления ограничений, наложенных в same-origin-policy относительно XSS запросов, было использование JSONP. Сам JSONP имеет неустранимое ограничение — позволяет только получение данных GET методом, то есть отправка данных через POST метод остается недоступной.
https://ru.wikipedia.org/wiki/JSONP
JSONP или «JSON with padding» (JSON с набивкой) это дополнение к базовому формату JSON. Он предоставляет способ запросить данные с сервера, находящегося в другом домене — операцию, запрещённую в типичных веб-браузерах из-за политики ограничения домена.
https://ru.wikipedia.org/wiki/JSON
Заметим, что данный пример применения XMLHttpRequest не является универсальным для всех браузеров (для браузеров, основанных на Internet Explorer, Opera, Safari и Mozilla, в коде должны быть те или иные отличия). Возможности применения XMLHttpRequest ограничены из-за правила ограничения домена (same origin policy): URL ответ на запрос должен находиться в том же DNS домене, что и сервер, на котором находится страница, запрашивающая ответ. В качестве альтернативы применяется подход JSONP, включающий в себя использование закодированного вызова функции, передающегося между клиентом и сервером, чтобы клиент мог загружать закодированные в JSON данные со сторонних доменов, и уведомлять о завершении вызывающую сторону, хотя это приводит к некоторым рискам для безопасности и дополнительным требованиям к серверу.
:) :) :)

Короче - JSON не поддерживается в современных браузерах и вымирает как мамонты.
XML спасет строка в web-сервере: tcp_puts("Access-Control-Allow-Origin: *\r\n");
Всё читается и передается куда угодно и очень легко отлаживать web страницы на компе, посылающие запросы к данным c Web на устройстве (хоть GET, хоть POST :) ).
Но самое главное ограничение у JSON - общая длина заголовка HTTP запроса. Она у всех ограничена, а POST с multipart/form-data ничем не ограничен. Ой - нет.- ограничен размером числа за Content-Length в заголовке HTTP в аски символах... в либах atoi() :)
atoi() не возьмет 100 значное число.... :(
----
Новая версия переехала на SDK 0.9.5 + Unofficial Development Kit for Espressif ESP8266 v1.0.8 (c) by CHERTS.
Изменены маке файлы.
 
Последнее редактирование:

Algis

New member
У меня нет опыта программирования на С. Я пишу на всех языках программирования, которые необходимы и лучше подходят для реализации проектов. По этой причине многое в них не знаю - только поверхностно. По СИ у меня не было ни одной книжки... Я считаю, что у вас возможностей больше - вся информация ныне есть в инет.
У меня то же самое, не было ни одной книги по програмированию, и не учился специально. Hо как-то лет 15 назад заинтересовался и постепенно втянулся полностью...
JSON формат не актуален - он не поддерживает POST, т.е. устарел и не является 'родным' для javascript.
JSON (JavaScript Object Notation) - формат описания обьектов в JavaScript, из-за своей компактности (особенно в сравнении с xml, при той же самой фунциональности) очень удобен для описания структурированных данных, и широко используется в вебе... ну неважно...

Вот, добавил передачу данных на UART и обратно через HTTP, и попробовал сделать дистанционное управление для контроллера отопительной системы,
команды посылаются в виде эскейп последовательностей типа: \x1B\n0?5\x1B\r а возвращается в виде массивов данных в JSON
Очень все хорошо получается, уже никак нельзя ваш проект называть "свалкой файлов" :) спасибо.
 

Вложения

pvvx

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

Lstt

Member
У меня то же самое, не было ни одной книги по програмированию, и не учился специально. Hо как-то лет 15 назад заинтересовался и постепенно втянулся полностью...

JSON (JavaScript Object Notation) - формат описания обьектов в JavaScript, из-за своей компактности (особенно в сравнении с xml, при той же самой фунциональности) очень удобен для описания структурированных данных, и широко используется в вебе... ну неважно...

Вот, добавил передачу данных на UART и обратно через HTTP, и попробовал сделать дистанционное управление для контроллера отопительной системы,
команды посылаются в виде эскейп последовательностей типа: \x1B\n0?5\x1B\r а возвращается в виде массивов данных в JSON
Очень все хорошо получается, уже никак нельзя ваш проект называть "свалкой файлов" :) спасибо.
А можно более подробнее, очень интересно, сам хочу использовать модули (которые ещё в пути) для банального управления силовыми нагрузки (возможно диммирование)... Ещё бы как-нибудь это к Андроиду привязать...
 

Algis

New member
А можно более подробнее, очень интересно, сам хочу использовать модули (которые ещё в пути) для банального управления силовыми нагрузки (возможно диммирование)... Ещё бы как-нибудь это к Андроиду привязать...
Для вкл/выкл, достаточно в Web директории сделать htm с формой в которой столько checkbox'ов сколько виводов модуля вы хотите виделить для этого,
названия им дать например gpio1, gpio2, gpio3 а в web_int_vars.c добавить условие
Код:
else if(!os_memcmp((void*)cstr, "gpio", 4)) {
....
}
со своим обработчиком этого типа переменных, управляющим соответстующие выводы модуля.
Ели выводов не хватает, поставить сдвиговщй регистр, дальше уже обычьные или твердотельные реле.
С диммированием сложнее, придется через оптрон ловить пересечение нуля в сети и от этого осчитывать момент включения вывода,
 
Последнее редактирование:
  • Like
Реакции: Lstt

Lstt

Member
Спасибо за ответ! Здесь нашел работоспособную схему для Arduino, как раз с детектором нуля http://wiki.dxarts.washington.edu/groups/general/wiki/4dd69/AC_Dimmer_Circuit.html , как Вы считаете, её можно задействовать, я так понимаю, необходимо постоянно опрашивать вход, для определения этого момента, а для простого включения выключения, думаю тоже использовать обычную симисторную схему с драйвером для гальванической развязки, вот хочется только ещё диммирование прикрутить...
 
Сверху Снизу