Например TDA7294

РадиоКот >Статьи >

О работе с WiFi модулем WGM110 фирмы Silicon Lab

Автор: Сергей Безруков (aka Ser60), sergeilb60@mail.ru
Опубликовано 27.10.2016.
Создано при помощи КотоРед.

В статье [1] я недавно рассказывал о Bluetooth Smart решениях этой фирмы, так что логично было-бы посмотреть на их WiFi модули. Казалось-бы какое отношение они имеют друг к другу? Однако, связь между ними более тесная, чем может показаться поначалу. Дело в том, что оба они могут управляться программами и API на языке BGScript. Освоив одни модули, гораздо легче перейти или дополнить проект другими, т.к. их API во многом сходные. Но начнём всё по порядку.

На настоящий момент линейка WiFi модулей фирмы представлена тремя моделями. Это WF111 и его старший брат WF121, разработанные фирмой Bluegiga ещё до слияния с Silicon Labs, и последняя недавняя разработка – герой повествования – WGM110. Первый модуль может работать только в режиме NCP (Network Co-Processor) и требует внешнего контроллера для реализации логики работы устройства. Второй имеет на борту 32-битный микроконтроллер PIC32MX695F512H фирмы Microchip в который помимо стека может быть загружена и программа пользователя. Наконец третий, о котором пойдёт речь подробнее ниже, имеет на борту ARM Cortex-M3 микроконтроллер семейства Wizard Gecko фирмы, который также может выполнять программу пользователя. Это позволяет в случае WF121 и WGM110 спроектировать многие системы на основе лишь одного модуля. Помимо этого все упомянутые модули могут работать и в режиме NCP. Подробности о Ките для модуля WGM110 см. в [9].

Другим сходством Bluetooth и WiFi модулей фирмы является возможность установки их плат на единую отладочную плату Кита с программатором. Ниже показан её вид с подсоединённой дочерней платой расширения, улыбающейся нам справа. Я задействовал лишь светодиод на последней в своём тестовом проекте.

Размеры модуля всего 14.4×21 мм, так что по высоте он аккурат соответствует популярной в прошлом царской монете достоинством в 7 рублей 50 копеек (с чем-же ещё у Вас ассоциируется число 21?). На этот раз фирмой соблюдены собственные рекомендации по ширине земляного полигона вокруг модуля. На оценочной плате модуля установлена чип-антенна, а также коннектор USB и на обратной стороне гнездо для Micro-SD карты.

Стек WiFi протоколов фирмы включает реализацию IPv4, TCP, UDP, DHCP (client/server), ARP, DNS, HTTP server и TLS/SSL client. Реализация 802.11 b/g/n стандартов гарантирует передачу данных на максимальной скорости 72.2 Mbps и поддерживает WPA/WPA2 (Personal/Enterprise) и WEP security. Максимальная выходная мощность модуля +16 dBm (40 mW) при чувствительности -98 dBm. Модуль может работать в режимах AP (Access Point до 5 клиентов) и STA (station) при соединении с внешней AP. Микроконтроллер на плате модуля имеет 1 Mb флеша, так что остаётся ещё достаточно места для многих приложений.

Изначально в модуль на оценочной плате загружена программа приложения HTTP сервера с AP. Единственная обслуживаемая сервером веб-страница показывает данные температуры и влажности воздуха, считываемых с сенсора Si7021 на отладочной плате. После переделок можно будет хранить страницы и на Micro-SD карте под платой. При соединении с локальной сетью, предоставляемой модулем, с компьютера или смартфона и открытия браузером, поддерживающим HTML5, веб-страницы по адресу 192.168.1.1, увидим шкалы термометра и гигрометра:

Исходный код этого приложения подробно разобран в документе [2]. Примеры программ, устанавливамых вместе с сопутствующим software, включают реализацию HTTP сервера, исходный код проекта которого рассмотрен в [3]. Здесь я опишу приложение не разобранное в примерах, предоставляемых фирмой, а именно реализацию HTTP клиента. Наше приложение будет измерять температуру и влажность воздуха с помощью сенсора Si7021 на плате и каждые 5 секунд отсылать эти данные по GET запросу через внешнюю AP на внешний сервер. Что будет делать с этими данными сервер - это другой вопрос и здесь подробно не расматривается. Можно, например, сохранять эти значения в файле, как это описано в моей статье [4]. В нашем случае сервер просто посылает короткое подтверждение клиенту о получении данных. В качестве сервера я использовал легковесный MiniWeb сервер [5] на моём Windows лаптопе, к которому через USB кабель подключена отладочная плата с WiFi модулем. Вот как выглядит лог работы сервера в окне консоли после его запуска:

Число [416] в скобках – это некий ID клиента, выбранный сервером. В моей домашней сети нашему устройству присвоен IP адрес 10.0.0.2. WiFi стек модуля получает этот адрес автоматически и прозрачно для пользователя по протоколу DHCP при запросе соединения с AP. Данные температуры и влажности передаются серверу на обслуживающий скрипт sensors.html в строке GET запроса, где параметр n – его порядковый номер. Этот скрипт следует поместить в папку htdocs установки MiniWeb сервера.

В целях контроля работы программы я произвожу в ней открытие виртуального COM порта на компьютере для вывода служебных сообщений в процессе работы нашего устройства. Согласно протоколу HTTP, посылке запроса серверу предшествует установка соединения с ним посылкой SYN-пакета. Это делается WiFi стеком модуля автоматически вызовом специальной API функции (подробнее ниже). Если соединение произошло успешно, то на экран выводится соответствующая верхняя строчка в каждой группе посылок, разделённых пустой строкой. Вот как выглядят эти группы, появляющиеся в окне COM консоли с периодом 5 секунд:

Три строчки, начиная с команды GET – это HTTP хедеры запроса серверу. Мой лаптоп, используемый как сервер, в домашней сети имеет IP адрес 10.0.0.14. Для упрощения кода я не использовал DNS для обращения к серверу по имени, т.к. соответствующие примеры содержатся в дистрибутиве установки software (подробнее ниже). Если у вас на компьютере установлена Firewall, не забудьте сконфигурировать её надлежащим образом. После отсылки запроса серверу программа принимает его ответ и показывает на экране длину данных принятого пакета. Закрытиe соединения индицируется строкой “Closed”.

Работу системы можно проследить с помощью системы Wireshark, работающей на том-же самом лаптопе. Я установил в ней фильтр, показанный на зелёном фоне ниже, чтобы опустить все не относящиеся к делу пакеты. Как видно из скриншота, работа нашего клиента с сервером происходит в полном соответствии с классикой (а что ещё следовало ожидать?). В строчках 17-19 производится обмен пакетами «рукопожатия» для установки соединения с сервером. Замечу, что MiniWeb сервер однопотоковый и дефолтно принимает все запросы клиентов через порт 8000, а порт клиента в данном случае 49175. После соединения наше устройство посылает GET запрос на сервер в строке 20, который отвечает кодом “200 OK” в строке 21 и возвращает хедеры ответа клиенту. Данные этого пакета показаны в нижней части окна и имеют длину 211 байт, как мы уже видели выше. После этого сервер в строке 22 посылает ответ, в нашем случае короткий HTML файл sensors.html, см. прилагаемый архив. Длина данных (payload) этого пакета, согласно Wireshark, равна 88 байт, что согласуется с выводимыми сообщениями клиента выше. Отмечу, что в окне сервера при этом показана отсылка 299 байт. Однако, это суммарная длина данных посланных сервером с момента установки соединения. Длина второго пакета, таким образом, равна 299 – 211 = 88 байт. В заключении в строках 22-24 производится обмен пакетами для закрытия соединения. Таким образом, WiFi стек фирмы работает «как часы».

Обратимся теперь к коду программы, реализующей описанный выше функционал. Все файлы проекта показаны на вкладках редактора Notepad++ ниже. Сборка проекта для компиляции производится с помощью файла project.xml. В нём установлено имя основного файла main.bgs, а также конфигурация аппаратной части WiFi модуля и демо-платы. В нашем случае нам понадобится UART блок для вывода сообщений на виртуальный COM порт, подача питания на сенсор Si7021, и канал 1 интерфейса I2C модуля на его группе выводов 2 (так он соединён с демо-платой). Детали для создания файла проекта описаны в документе [6]. Генерируемый файл для загрузки в модуль назван client.bin.

Все сетевые настройки я вынес в отдельный файл network.bgs. Он начинается с номера канала моей домашней WiFi AP. В нём вместо точек в строках 3 и 5 следует поставить имя Вашей сети и пароль для входа в неё с соответствующими длинами этих строк в строчках 4 и 6. Вторая часть файла содержит хедеры запроса, посылаемые серверу и его IPv4 адрес, который автоматически переведётся в 32-битное число. Я разбил запрос на несколько строк, поскольку часть его формируется динамически в процессе работы устройства. Служебное слово const гарантирует размещение этих данных в области флеша на модуле, а директива export необходима для обеспечения доступа к ним из других файлов проекта. Синтакс языка BGScript для нашего модуля описан в [7]. Отмечу, что он слегка отличается от такового для BLE модуля из предыдущей статьи [1].

Оставлю без комментариев файлы sta.bgs и si7021.bgs. Первый из них я заимствовал без изменений из примеров фирмы. Этот файл отвечает за соединение с WiFi AP и поддержание этого соединения во времени. Второй файл – это мой драйвер сенсора Si7021, который аналогичен таковому из [1]. Отличия в нём минимальны и связаны с отличиями I2C API функций для нашего модуля и модуля BLE. Измеренные сенсором температура и влажность переводятся в строки утилитой util_itoa() библиотеки BGAPI.

Таким образом, мы подошли к последнему файлу main.bgs проекта. Файл начинается с включения остальных .bgs файлов в проект директивами import, декларирования используемых переменных, и процедуры send_request() для компоновки и отсылки GET запроса серверу. Компоновка производится с помощью C-образных утилит memcpy() для объединения всех строк запроса в одну. Можно, однако, этого не делать и посылать несколько строк запроса одну за другой.

Остальные методы в файле main.bgs – это соответствующие обработчики прерываний WiFi стека. После подачи питания стек формирует событие system_boot. В ответ на него мы конфигурируем задействованные порты модуля на ввод/вывод и вызываем API sme_wifi_on() для инициализации WiFi части модуля. По её окончании модулем генерируется событие sme_wifi_is_on, в обработчике которого (в файле sta.bgs) производится установка соединения с внешней WiFi AP. Если соединение произошло успешно, статус WiFi модуля изменится и сгенерируется событие sme_interface_status. В обработчике его прерывания мы индицируем успех зажиганием светодиода LED1 на демо-плате и запускаем таймер с периодом 5 секунд для производства новых измерений параметров среды и отсылки их на сервер. API функции модуля вместе с генерируемыми событиями и прочей информацией для разработчиков описаны в документе [8], доступного, как и все остальные, с вебсайта фирмы.

Таким образом, каждые 5 секунд канал 0 таймера генерирует прерывание, в обработчике которого заложена вся логика функционирования нашего устройства в виде конечного автомата с четырьмя состояниями. Номер текущего состояния хранится в переменной state. После установки соединения с AP значение этой переменной равно 1. При этом мы производим новое измерение температуры и влажности в строке 74, переносим измеренные данные в поля GET запроса серверу (строки 75-76), выдаём сообщение на COM порт в строке 77, и посылаем запрос на TCP соединение с сервером в строке 78. Если всё прошло гладко, переходим в состояние 2, и в любом случае посылаем отчёт на консоль (строки 79-88). По установке соединения статус нашей WiFi конечной точки изменится и сгенерируется событие endpoint_status (см. ниже). Если в момент переполнения таймера мы находились в состоянии 2, это означает, что GET запрос был послан серверу ранее, но подтверждения не получено. При этом мы посылаем запрос ещё раз в строках 90-93. Если-же на момент переполнения таймера мы находимся в состоянии 0 (нет соединения с AP) то останавливаем таймер и запрашиваем новое соединение с AP (строки 94-99).

Наконец, последняя вставка кода. Первое событие endpoint_status в ней генерируется при изменении статуса любой конечной точки (UART, USB, WiFi). В нашем случае на это изменение следует отреагировать по установке TCP соединения с сервером и по разрыве соединения с ним. В первом случае мы посылаем на сервер наш GET запрос (строки 105-108) и включаем светодиод LED0 на демо-плате. Во втором – закрываем WiFi конечную точку и гасим светодиоды (строки 109-118), переходим в состояние 1, и формируем новый номер n запроса (по модулю 10). Таким образом, сведтодиоды LED0 и LED3 (на плате расширения) кратковременно вспыхивают, соответственно, при каждой успешной посылке запроса на сервер и получении его ответа. Приём данных по WiFi сигнализируется стеком путём генерации события endpoint_data. В его обработчике мы переходим в состояние 3 приложения, и выводим в окно COM консоли число принятых байтов ответа сервера (строки 124-130). В данном приложении мы просто проверяем ответ на наличие кода “200” (всё ОК) в нём и игнорируем остальную его часть. Однако, вся она доступна через параметр data_from_server, передаваемый в обработчик WiFi стеком.

Ну вот, собственно, и всё. Как мы видели, в целом всё достаточно логично и просто. Для компиляции проекта и загрузки его в модуль следует установить систему Wizarg Gecko SDK (WSDK) с вебсайта фирмы, содержащую в папке examples примеры работы с модулем, упомянутые выше. Работа с ней полностью аналогична работе с соответствующей системой для BLE модуля, как описано в [1]. После установки подключаем Кит к компьютеру и запускаем программу BG-Tool системы. Затем компилируем проект нажатием на кнопку Build и в случае успеха заргужаем его в модуль нажатием на кнопку Upload. После загрузки firmware модуля сразу начинает работать. Подробности работы с WSDK см. в [10].

Отмечу, что не всё было гладко в процессе разработки этого приложения. Главной проблемой было зависание WiFi стека после примерно 5 часов работы, так что даже не генерировались прерывания таймера. Из контрольных выдач на консоли следовало, что последний запрос был отправлен серверу, достиг его, но отосланного им ответа модуль не получил. Чего только я не перепробовал, пока наконец не обратился в группу тех-поддержки на фирму. Как оказалось, это известный им баг в последней на настоящий момент версии v1.0.0 системы. До выпуска очередного апдейта WSDK у них имеется временное решение, сводящееся к замене файла wifi.juo в папке fw установки системы на одноимённый файл в прилагаемом к статье архиве. После этой замены и перекомпиляции с последующей загрузкой проекта в модуль всё заработало устойчиво.

Литература

  1. О работе с BLE модулем BGM111 фирмы Silicon Labs
  2. Silicon Labs AN967: Wizard Gecko WSTK Demo Walkthrough
  3. Silicon Labs AN1023: HTTP Server Example
  4. Сетевой логгер и сервер на базе модуля WIZ820io
  5. MiniWeb – the open source mini HTTP daemon
  6. Silicon Labs UG161: WGM110 Wi-Fi® Module Configuration Guide
  7. Silicon Labs UG170: Wizard Gecko BGScript™ User's Guide
  8. WGM110 API Reference Manual
  9. Silicon Labs UG172: Wizard Gecko Wi-Fi Module Wireless Starter Kit
  10. Silicon Labs UG160: Wizard Gecko BGTool™ User's Guide

Файлы:
Firmware


Все вопросы в Форум.


Как вам эта статья?

Заработало ли это устройство у вас?

9 6 3