ESP8266 Урок 15. Wi-Fi. STA. UDP Client



Продолжаем развивать тему по приёму и передаче данных по беспроводной сети Wi-Fi.

И на данном уроке мы попытаемся написать простейший клиент UDP. Надеюсь, мы все помним, что это за протокол, если нет, то смотрим уроки по другим контроллерам, где всё это рассмотрено очень глубоко.

Передавать и принимать данные посредством протокола транспортного уровня UDP мы будем посредством Wi-Fi соединения в режиме станции.

Схема наша остаётся та же — отладочная плата, подключенная к USB компьютера

 

 

Проект мы за основу возьмём из прошлого урока с именем WIFI_STA и назовём его ESPCONN_UDP_CLIENT.

Для работы с протоколом UDP мы будем использовать библиотеку espconn, также предоставленную с закрытым исходным кодом.

Откроем наш проект в Eclipse и в файле main.c подключим заголовочный файл библиотеки

 

 

Теперь внесём некоторые изменение в создание соединения Wi-Fi для более стабильной его работы, а также для большего быстродействия.

Для начала в функции user_init() разъединим станцию с точкой доступа и отключим DHCP

 

 

Удалим вот эти строки

 

os_memset(&stationConf, 0, sizeof(struct station_config));

os_sprintf(stationConf.ssid, «%s», WIFI_CLIENTSSID);

os_sprintf(stationConf.password, «%s», WIFI_CLIENTPASSWORD);

wifi_station_set_config_current(&stationConf);

 

Заберём из FLASH-памяти настройки Wi-Fi-соединения и в случае удачного выполнения данной функции установим в ноль только SSID и пароль, после чего заменим их своими строками

 

 

При неудачном конфигурировании выведем соответствующее сообщение в терминальную программу

 

 

Удалим строку соединения с точкой доступа

 

wifi_station_connect();

 

И вызовем данную функцию выше, а затем вызовем функцию включения клиента DHCP

 

 

Включим протокол физического уровня типа 802.11n, если таковой уже не включен

 

 

Включим автоматическое соединение с точкой доступа в случае разрыва, если не включено

 

 

Удалим объявления следующих глобальных переменных

 

static uint8_t wifiStatus = STATION_IDLE;

static uint8_t connectStatus = 0;

 

Создадим перечисляемый тип с некоторыми состояниями соединения

 

 

Объявим переменную данного типа и сразу проинициализируем её

 

 

Объявим переменную типа структуры соединения и ещё одну типа структуры для хранения параметров соединения UDP

 

 

 

Для функции обработки событий таймера создадим прототип, так как доступность её имени потребуется в коде выше

 

 

В теле данной функции wifi_check_ip следующая переменная станет локальной

 

uint8_t wifiStatus = wifi_station_get_connect_status();

 

В данной условной конструкции удалим второе условие

 

if (wifiStatus == STATION_GOT_IP && ipConfig.ip.addr != 0)

 

Узнаем информацию о станции

 

 

Удалим инициализацию и запуск таймера

 

os_timer_setfn(&os_timer01, (os_timer_func_t *)wifi_check_ip, NULL);

os_timer_arm(&os_timer01, 2000, 0);

 

Весь код, расположенный ниже в теле условия, перенесём в тело другого условия, которое мы добавим, кое-что в нём изменив

 

 

В случае удачного соединения мы из функции выйдем совсем, в этом случае мы таймер позже запустим совсем в другом месте.

В ветке противного случая удалим данную строку

 

connectStatus = 0;

 

Вместо этого изменим статус соединения Wi-Fi

 

 

Разъединимся с хостом

 

 

Из тел следующих трёх условий условной конструкции удалим вызов функции соединения с точкой доступа, так как мы настроили автоматическое соединение при разрыве

 

wifi_station_connect();

 

А выше вывода сообщения в терминал в данных условиях присвоим переменной статуса значение ошибки соединения. После этого условия примут следующий вид

 

 

Противный случай данной условной конструкции также изменится, там будет другое сообщение и присвоение статуса

 

 

Инициализацию таймера и запуск здесь мы также удалим

 

os_timer_setfn(&os_timer01, (os_timer_func_t *)wifi_check_ip, NULL);

os_timer_arm(&os_timer01, 500, 0);

 

Таймер мы инициализируем и запустим, выйдя из тела противного случая условной конструкции верхнего уровня, иначе у нас светодиод мигать не будет. Время срабатывания таймера мы установим в 1 секунду

 

 

 

Выше функции wifi_check_ip добавим функцию установки соединения с сервером UDP

 

 

Вызовем данную функцию в функции wifi_check_ip вот здесь

 

 

В теле функции udp_connect объявим локальную переменную для хранения сетевого адреса

 

 

Объявим и проинициализируем символьный массив, который мы передадим затем серверу в случае успешного соединения с ним

 

 

Объявим подобный, но пустой, массив для хранения строкового значения адреса IP сервера

 

 

Деинициализируем таймер

 

 

Внесём некоторые настройки соединения: покажем адрес переменной структуры соединения UDP, тип соединения и его начальное состояние

 

 

В файле user_config.h добавим макросы для адреса и порта сервера, в качестве сервера у нас будет работать привычная нам программа netcat на ПК

 

 

Вернёмся в main.c в функцию udp_connect и скопируем адрес сервера в символьную строку, а затем с помощью специальной функции преобразуем его в число

 

 

Скопируем его в соответствующее поле переменной pConn

 

 

Также с помощью функции библиотеки espconn сгенерируем номер порта клиента и запишем его также в соответствующее поле

 

 

В следующее поле запишем номер порта сервера

 

 

Перед созданием соединения пошлём сообщение в терминальную программу

 

 

Попытаемся создать соединение UDP

 

 

Мы, конечно же, прекрасно знаем, что обмен данными посредством протокола UDP не предусматривает создание соединения, всё это виртуально, только для правильной организации работы клиента.

Выше добавим функции обратного вызова передачи и приёма пакетов

 

 

Зарегистрируем их в функции udp_connect

 

 

Проинициализируем и запустим таймер

 

 

Затем попробуем передать пакет серверу

 

 

Обратный вызов передачи пакета мы обрабатывать не будем, пусть обработчик будет пустотелым, а вот приём пакета обработать нужно.

Поэтому в функции udp_client_udp_recv_cb объявим переменную для отсчёта принятых байтов в пакете, а также выведем в терминал длину пакета в байтах и подготовим строку для вывода в терминальную программу принятых символов, так как на сервер и с сервера мы будем передавать символьные строки

 

 

Выведем принятые с сервера символы в терминальную программу

 

 

И отправим символьную строку серверу в ответ

 

 

Соберём код и прошьём контроллер.

В терминальной программе соединимся с виртуальным портом и увидим, что соединение Wi=Fi благополучно установлено

 

 

 

Только вот дальше у нас пока ничего не выводится, так как мы не запустили наш сервер. Поэтому в командной строке, находясь в каталоге с программой netcat, дадим следующую команду и, если всё нормально, то после перезагрузки отладочной платы сервер примет нашу строку

 

 

Попробуем что-нибудь передать обратно клиенту, введя в командной строке какую-нибудь строку

 

 

Клиент благополучно ответил.

Также мы видим информацию о принятом пакете клиента в терминальной программе

 

 

Давайте посмотрим, как проходят пакеты в программе анализа сетевого трафика Wireshark. Запустим его, в командной строке пока остановим слушание порта, нажав комбинацию клавиш Ctrl+C, запустим netcat заново, так как после перезагрузки клиента порт у него уже будет другой и в старом соединении сервера ничего не примется.

Перезагрузим клиент, примем строку, передадим строку клиента, на что он нам опять ответит своей строкой и уже после этого посмотрим анализ трафика между сервером и клиентом

 

 

Мы видим, что пакеты наши передаются в обе стороны безошибочно.

Итак, на данном уроке мы создали простенький, но уверенно работающий клиент UDP, с помощью которого нам благополучно удалось передать и принять пакеты UDP в обе стороны, используя при этом беспроводное соединение Wi-Fi с нашей платой.

Всем спасибо за внимание!

 

 

Предыдущий урок Программирование МК ESP8266 Следующий урок

Исходный код

 

 

Модуль ESP NodeMCU можно купить здесь: Модуль ESP NodeMCU

Различные модули ЕSP8266 можно приобрести здесь Модули ЕSP8266

Переходник USB to TTL можно приобрести здесь ftdi ft232rl

Многофункциональный переходник CJMCU FT232H USB к JTAG UART FIFO SPI I2C можно приобрести здесь ftdi ft232rl

Логический анализатор 16 каналов можно приобрести здесь

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

ESP8266 Wi-Fi. STA. UDP Client

4 комментария на “ESP8266 Урок 15. Wi-Fi. STA. UDP Client
  1. Олег:

    Добрый день. Есть вопрос о сотрудничестве, нужны ваши знания для наших проектов. Киньте мне на почту свой контактный телефон, наберу вам. Спасибо.

  2. Mikhail:

    Начинающие, не забывайте отключать фаерволл !!! )))
    Пол дня мучился пока сообразил.
    У меня антивирус своим фаерволлом перекрывал
    получение пакетов от модуля ESP01 в NetCat.
    А WireShark-у хоть бы что!!!

    Автору огромное спасибо за сий Труд!

  3. Антон:

    Маленький вопрос, откуда алгоритм действий данной программы?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*