ESP-WROOM-02 отладка AT команд

Отлаживаем протокол AT комманд для ESP WROOM 02

Протокол AT команд - протокол управления модемом через подачу управляющих команд , начинающихся с символов AT.
Разделяются порции данных символами CR LF ('\n\r'). Так исторически сложилось с незапамятных времен.


Тренируемся на модуле, взятом из ккт Меркурий 185, просто потому, что он был по рукой.



фотка 1

Нас интересует задача : установить TCP соединение по протоколу HTTP, запросить данные GET запросом и принять данные со страницы сайта.

Схема подключения есть:

фотка 2

Управляется ESP WROOM 02 по каналу UART на скорости 115200.

Подал команду, ждем ответа. Парсим ответ. И так далее.

Проблема №1 : многообразие вариантов ответов на AT команды

Может использоваться эхо, т.е. твоя посланная команда будет сначала присылаться тебе полностью обратно от приемника (для контроля приема) , а может эхо и не использоваться.

Главная путаница в том , что на некоторые AT команды подтверждаются в ответом 'n\r\OK\n\r', 'n\r\ERROR\n\r', а некоторые нет .

К тому же некоторые команды (с основном оп TCP соединениям) возвращают сначала что-то типа 'n\r\OK\n\r', 'n\r\ERROR\n\r' , а потом позже 'n\r\CONNECT OK\n\r' , 'n\r\SEND OK\n\r'.

Надо по идеи учитывать (отрабатывать) все возможные варианты ответов.

А вот как это делать (т.е. парсить данные) , одновременно успевая принимать очередные данные из порта - вот это проблема №2.

Проблема №2 решается через прерывания и очереди FreeRTOS

Задержка получения данных по TCP соединению может доходить до 30-40сек (это нормально).

По прерыванию HAL_UART_RxCpltCallback очередные данные быстро помещаются в приемную очередь xQueueSendToBackFromISR.

Если не успевать принимать байты будет вылетать HAL_UART_ErrorCallback, что сигнализирует о не правильной работе UART (скорее очередной байт не был считан и его затер последующий).

То есть это очень важный момент. Быстро принял байт , поместил в очередь и вышел.

Очень помогает логический анализатор

Без него ребята процесс может стать практически невозможным.

фотка 3

Как показывает логический анализатор ответы приходят (к счастью) пачками :

Например сначала приходит эхо, в которое в конце сразу добавлено 'n\r\OK\n\r' или 'n\r\ERROR\n\r'

Потом через некоторое время (зависит от команды) может прийти еще ответ (данные или результат выполнения).

Все это будет помещаться в очередь через xQueueSendToBackFromISR(..).

Далее основной FreeRtos поток программы вынимает последовательно данные из очереди через xQueueReceive и уже "не спеша" начинает анализировать (парсить) ответ.

Тут есть важный момент как понять , что приняты все данные в ответе или надо еще ждать прихода байтов.

Тут надо индивидуально разбираться с каждой командой.

С простыми командами где максимум в ответе эхо и краткий результат типа (OK | ERROR) проблем нет.

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

Как на практике было установлено самые трудные команды , это когда ESP уже работает по WiFi с интернетом . Тут задержки бывают очень длительные.

ECHO RESULT DATA

Решено применить такую стратегию:
ECHO приходит быстро : ждем прихода из очереди первого символа допустим 1000 ms (firstMaxExpectedBlockTime=1000).
Задержку ожидания следующего байта делаем намного меньше , так как идет пачка (tinyExpectedBlockTime=5).

Таким образом если через 5ms не приходит очередной байт из очереди - значит пачка закончилась.
И можно перейти в режим ожидания следующей пачки с периодом конечно же опять побольше (firstMaxExpectedBlockTime=1000).

Главная особенность здесь , что после приема последнего байта пачки мы ждем всего 5мс, а потом можем даже успеть по-парсить принятые байты, до прихода следующей пачки.

А можем перевести поток в блокирующий режим опять на firstMaxExpectedBlockTime (1000) командой xQueueReceive и таким образом не нагружать систему.

Если вторая пачка успела начать приниматься через firstMaxExpectedBlockTime мс, то все хорошо (все идет по плану) и мы после приема первого байта пачки опять устанавливаем для следующего байта период tinyExpectedBlockTime(5мс) .
Принимаем вторую пачку.

И если у нас еще ожидается приход данных,через довольно неопределенное время , то устанавливаем ожидание DataMaxExpectedBlockTime (30000мс) и тупо ждем данных. Если данные пошли переключаемся на ожидание устанавливаем tinyExpectedBlockTime (5мс).

И таким образом после прихода последнего байта данных + 5мс мы завершаем прием.

Этот способ работает максимально быстро.

Но он не учитывает конечно , что пачек может быть и побольше.

Для нашей задачи эта стратегия работает.

К счастью в длинном ответе на GET запрос указывается количество байтов в ответе и в теле ответа. И это надо использовать для проверки.

Вот пример ответа

'\n\rSEND OK\n\r
\n\r+IPD,248:HTTP/1.1 200 OK\n\r
Server: nginx/1.10.2\n\r
Date: Sat, 04 Jan 2020 09:36:41 GMT\n\r
Content-Type: text/html\n\r
Transfer-Encoding: chunked\n\r
Connection: keep-alive\n\r
X-Powered-By: PHP/5.3.3\n\r
X-SERVER: linwebng04\n\r
X-SERVER: linwebng04\n\r
\n\r
e    // длина тела
\n\rxxyyzzssddffgg\n\r
0
\n\r\n\r
'


Примечание : Внимание : линия RTS задействована в канале UART с ESP.

фотка 4

Открытый проект как обычно прикладываю

Файлы для скачивания

* STM32F407VET6 UART2 UART3 FreeRtos AT commands Atollic [zip]
заработал TCP клиент через ESP WROOM 02