Веб-сервер на ESP32 и датчике DS18B20 с помощью ESP-IDF


В этом уроке мы создадим веб-сервер на базе ESP32 с использованием ESP-IDF, который будет отображать показания датчика DS18B20. Датчик температуры DS18B20 широко используется в электронных проектах, поскольку для сбора данных используется один провод, что делает его программируемым по принципу «одного провода». Веб-сервер будет работать как метеостанция, отображая показания температуры на веб-странице, которые будут обновляться каждые 10 секунд. Для создания и сборки этого веб-сервера на базе ESP32 мы будем использовать VS Code с расширением ESP-IDF. Доступ к нему будет легко обеспечен на различных устройствах, таких как ноутбуки, мобильные телефоны и т. д., подключенных к той же сети Wi-Fi, что и плата ESP32.

Веб-сервер на ESP32 и датчике DS18B20 с помощью ESP-IDF Мы будем программировать нашу плату разработки ESP32 в VS Code с использованием расширения ESP-IDF.

Ранее на нашем сайте мы рассматривали проект аналогичного веб-сервера на основе датчика BME280.

Также вы можете прочитать статью про подключение датчика DS18B20 к ESP32 с помощью ESP-IDF.

Обзор веб-сервера на ESP32 и DS18B20

Наш ESP32 будет размещать веб-сервер, который будет предоставлять HTML/CSS-файлы веб-клиенту, то есть веб-браузеру. Мы создадим веб-сервер с помощью библиотеки HTTP-веб-сервера, доступной в esp-idf. Когда пользователь вводит IP-адрес в веб-браузере, на ESP32 отправляется HTTP GET-запрос. ESP32 отвечает на запрос, отправляя буфер, содержащий HTML и CSS-файлы для построения веб-страницы, отображающей данные датчика DS18B20.

Принцип работы веб-сервера на ESP32 и DS18B20

Пользователи могут получить доступ к веб-серверу через IP-адрес и любое веб-приложение, например, веб-браузер на ноутбуке или мобильном телефоне.

Интерфейс веб-сервера в веб-браузере на ноутбуке

Подключение DS18B20 к ESP32

Датчик температуры DS18B20 широко используется в электронных проектах, где для сбора данных используется один провод, поэтому он позиционируется как программируемый по одному проводу. Он использует один вывод GPIO микроконтроллера для вывода текущего показания температуры окружающей среды. Используя минимальное количество выводов, мы можем удобно получать доступ к нескольким показаниям температуры, подключая датчики DS18B20 к одному и тому же выводу GPIO.

Для подключения платы ESP32 к датчику DS18B20 нам понадобятся следующие компоненты:

  1. Плата ESP32.
  2. Датчик DS18B20.
  3. Подтягивающий резистор 4,7 кОм.
  4. Соединительные провода.
  5. Макетная плата.

Датчик DS18B20 может включаться в двух режимах: обычном и паразитном. В обычном режиме датчик питается от внешнего источника через вывод VCC и резистор 4,7 кОм. Однако в паразитном режиме датчик питается от линии данных, поэтому внешний источник питания не требуется. Мы будем питать наш датчик DS18B20 в обычном режиме.

В таблице ниже показано подключение трех контактов датчика DS18B20 к плате ESP32.

DS18B20 ESP32
VCC 3.3V / Vin
Data GPIO4
GND GND

Подключите вывод VCC датчика к выводу 3,3 В или Vin платы ESP32 и соедините заземление обоих устройств. Кроме того, подключите вывод данных датчика к соответствующему выводу GPIO платы ESP32, который можно настроить как выходной вывод. Обратите внимание, что выводы GPIO34-39 являются только входными и не могут использоваться для управления однопроводной шиной. Мы используем GPIO4 для подключения к выводу данных через подтягивающий резистор 4,7 кОм. Один конец резистора будет подключен к выходу данных, а другой — к источнику питания.

Обратите внимание, что если вы используете модуль DS18B20, то вам не нужно добавлять внешний подтягивающий резистор. Это связано с тем, что модуль уже оснащен датчиком и встроенным подтягивающим резистором.

Следуйте приведенной ниже принципиальной схеме, чтобы соединить два устройства.

Схема подключения датчика DS18B20 к плате ESP32

Проект веб-сервера на базе ESP32 и DS18B20 с помощью ESP-IDF

В этом разделе мы создадим веб-сервер на базе DS18B20 и ESP32 с использованием ESP-IDF. Плата ESP32 будет настроена в режиме станции, то есть она будет подключаться к сети Wi-Fi через маршрутизатор. После успешного подключения к точке доступа плате будет присвоен IP-адрес, который будет использоваться для доступа к веб-серверу.

Создание примера проекта

Откройте VS Code и перейдите в меню View > Command Palette («Вид» > «Палитра команд»). Введите в строке поиска ESP-IDF: New Project и нажмите Enter.

Укажите название проекта и каталог, а также плату и целевое устройство ESP-IDF. Для платы ESP-IDF мы выбрали опцию custom board ("пользовательская плата"). Для целевого устройства ESP-IDF мы выбрали модуль ESP32. Нажмите кнопку ‘Choose Template’ ("Выбрать шаблон"), чтобы продолжить.

В разделе «Расширение» выберите опцию ESP-IDF:

Выбор опции ESP-IDF в разделе Extension («Расширение»)

На вкладке get-started («Начало работы») мы щелкнем по пункту «sample_project». Затем нажмем ‘Create project using template sample_project’) («Создать проект, используя шаблон sample_project»).

Создание проекта с использованием шаблона sample_project

Вы получите уведомление о создании проекта. Чтобы открыть проект в новом окне, нажмите «Да».

Это откроет проект, который мы создали во вкладке «Проводник». Внутри папки проекта находится несколько папок. Это относится ко всем проектам, которые вы будете создавать с помощью ESP-IDF Explorer. Сначала добавим необходимые заголовочные файлы для библиотек, необходимых для этого проекта. Создайте новую папку с именем «components» и добавьте в нее следующие файлы:

  • ds18b20.h
  • ds18b20.c
  • MakeLists.txt

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

Теперь перейдите к файлу main.c. В папке main находится исходный код, то есть файл main.c будет находиться здесь. Перейдите в папку main > main.c и откройте его. Скопируйте приведенный ниже код из этого файла и сохраните его.

Код веб-сервера на ESP32 и DS18B20

Данный код можно также скачать по следующей ссылке.

Как работает код?

Для начала мы подключим необходимые библиотеки, включая ds18b20.h для работы с датчиками, библиотеки FreeRTOS для генерации задержек, создания задач и групп событий, esp_http_server.h для настройки веб-сервера HTTP, esp_wifi.h для включения Wi-Fi-соединения, esp_event.h для мониторинга событий Wi-Fi, esp_log.h в качестве библиотеки для логирования, библиотеку driver/gpio.h для управления цифровыми выходными контактами ESP32 и т.д.

Далее мы определили параметры для SSID и пароля Wi-Fi. Укажите свои собственные учетные данные сети, чтобы успешно подключить плату ESP32 к сети Wi-Fi.

Мы зададим максимальное значение количества повторных попыток для мониторинга Wi-Fi-соединения. Оно установлено равным 5.

Далее мы объявляем переменную 's_wifi-event_group' для хранения созданной группы событий FreeRTOS. Эта группа событий FreeRTOS используется для оповещения о подключении к Wi-Fi.

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

Переменная 'DS_PIN' содержит номер однопроводного GPIO, который будет использоваться для подключения к выводу данных датчика. Мы используем GPIO4.

Этот код использует информационное логирование. Функция логирования принимает два аргумента. Первый аргумент — это тег, а второй — отформатированная строка. Поэтому эта глобальная переменная будет полезна при вызове функций ESP_LOGI(). Здесь «esp32 webserver» — это тег, который будет использоваться при логировании.

HTML и CSS для создания веб-сервера

Затем у нас есть массив, содержащий HTML- и CSS-скрипты для HTML-страницы. Он включает в себя заголовок веб-сервера и две карточки для отображения показаний температуры вместе с иконками.

HTML-код задаётся в тегах <html></html>. Внутри тегов <style></style> задаётся стиль веб-страницы. Это включает в себя семейство шрифтов, размер шрифта, позиционирование текста, размер и цвет карточек и т. д.

Начнём с заголовка веб-страницы. Он размещается внутри тегов <title> </title>. В нашем случае мы установили заголовок веб-страницы как «ESP-IDF DS18B20 Web Server». Он будет отображаться в строке заголовка браузера.

Следующий метатег позволит отображать наш веб-сервер на разных устройствах.

Как мы уже упоминали, мы хотим добавить иконку температуры внутрь карточек. Поэтому следующий тег ссылки получит иконку из  FontAwesome.

Как вы могли заметить, весь текст набран шрифтом Arial и выровнен по центру веб-страницы. Цвет и размер шрифта верхней панели навигации также заданы. На нашей веб-странице есть две карточки для каждого показания датчика. Общее оформление карточек, а также цвет каждого отдельного показания, также заданы. Мы задаем размер и цвет заголовка карточки, а также общее оформление карточки, включая цвет фона, тень и т. д.

Внутри тегов <body> </body> будут размещены заголовок, абзацы и карточки.

Заголовок нашего веб-сервера — «ESP-IDF DS18B20 WEB SERVER», он размещен внутри тегов <h3></h3>.

Затем у нас есть две карточки, на которых отображаются показания температуры в градусах Цельсия и Фаренгейта соответственно. Все показания датчиков привязаны к классу «показание». Каждая карточка имеет свой значок, за которым следует заголовок и показание внизу, а также единица измерения.

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

Чтение данных из DS18B20

Внутри функции DS18B20_readings() инициализируется датчик DS18B20, после чего данные с датчика собираются и сохраняются в соответствующих переменных 'TempC' и 'TempF'.

Сначала мы инициализируем датчик DS18B20 с помощью функции ds18b20_init() и передаем в качестве параметра контакт GPIO с одним проводом.

Для начала получения показаний датчика DS18B20 мы запрашиваем температуру с помощью функции ds18b20_requestTemperatures().

Затем мы получим показания температуры в градусах Цельсия, используя функцию ds18b20_get_temp(). Эта функция возвращает показания температуры в виде числа с плавающей запятой. Аналогичным образом мы преобразуем показания температуры в градусах Цельсия в градусы Фаренгейта, умножив их на 9/5 и прибавив 32.

event_handler()

Затем у нас есть функция event_handler(), которая обрабатывает события Wi-Fi. Она выступает в качестве функции обратного вызова при возникновении события Wi-Fi или события IP.

Событие IP происходит, когда плата ESP32 подключается к нашей точке доступа, и маршрутизатор назначает ей IP-адрес. События IP могут быть одного из следующих типов. Но здесь мы используем только IP_EVENT_STA_GOT_IP.

Во-первых, когда происходят события Wi-Fi (WIFI_EVENT и WIFI_EVENT_STA_START), мы подключаем ESP32 к точке доступа. Для этого мы используем функцию  esp_wifi_connect().

Если плата ESP32 не может подключиться к точке доступа в течение установленного максимального количества попыток, она снова пытается подключиться к точке доступа и регистрирует сообщение «повторная попытка подключения к точке доступа». Однако, если ESP32 не может установить соединение с точкой доступа после истечения максимального количества попыток, она регистрирует сообщение «сбой подключения к точке доступа» и устанавливает бит WIFI_FAIL_BIT. Теперь, если плата ESP32 успешно подключается к точке доступа, это означает, что произошли оба события IP (IP_EVENT и IP_EVENT_STA_GOT_IP). В этом случае она выводит IP-адрес в качестве результата. Кроме того, она также устанавливает бит WIFI_CONNECTED_BIT.

connect_wifi()

Функция connect_wifi() будет вызываться внутри функции app_main() для инициализации Wi-Fi в режиме станции для ESP32.

Для начала создадим группу событий FreeRTOS для мониторинга соединения. Эта функция возвращает дескриптор группы событий.

ESP-IDF предоставляет полезный макрос ESP_ERROR_CHECK(), который используется для проверки наличия или отсутствия ошибки. Если функция, переданная в него, не возвращает ESP_OK, то мы проверяем наличие ошибки и записываем её в лог.

Здесь мы инициализируем lwIP с помощью функции esp_netif_init() и создаём задачу IwIP, также известную как задача TCP/IP. lwIP — это стек библиотек TCP/IP, предоставляемый ESP-IDF, который используется для выполнения различных протоколов, таких как TCP, UDP, DHCP и т. д.

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

Кроме того, следующая строка используется для инициализации Wi-Fi по умолчанию в режиме станции. Этот API используется для инициализации, а также регистрации обработчиков событий для интерфейса по умолчанию, которым в нашем случае является станция. Он создает экземпляр сетевого интерфейса, связывающий драйвер Wi-Fi и стек TCP/IP. Когда станция находится в процессе подключения к точке доступа, различные процессы автоматически обрабатываются с помощью этой функции.

Затем мы инициализируем ресурс выделения Wi-Fi для драйвера Wi-Fi. Он отвечает за запуск задачи Wi-Fi. Он принимает единственный параметр cfg, который является указателем на уже инициализированную структуру конфигурации Wi-Fi, установленную в значение WIFI_INIT_CONFIG_DEFAULT(), так что инициализация конфигурации происходит со значениями по умолчанию. Здесь wifi_init_config_t — это структура, обозначающая параметры конфигурации стека Wi-Fi, которые передаются в функцию esp_wifi_init().

Далее мы создаём два обработчика событий: один с именем 'instance_any_id' для всех событий Wi-Fi, а другой с именем 'instance_any_ip' — для событий, когда станция получает IP-адрес.

Далее, у нас есть два регистра для экземпляров обработчика событий, которые мы настроили. Таким образом, задача приложения может зарегистрироваться для обратного вызова, который будет прослушивать события для Wi-Fi и TCP/IP. Первое событие — «ESP_EVENT_ANY_ID», а второе — «IP_EVENT_STA_GOT_IP». Следовательно, она будет прослушивать все события Wi-Fi (ESP_EVENT_ANY_ID) и событие IP, когда станция получит свой IP-адрес (IP_EVENT_STA_GOT_IP). Таким образом, функция обратного вызова event_handler будет вызвана, если произойдет любое из этих двух событий.

Другие события Wi-Fi, которые мы можем использовать в нашем коде, включают:

В этой части мы задаём SSID и пароль сети, к которой хотим подключить наш ESP32, а также назначаем параметры безопасности.

Кроме того, мы устанавливаем режим Wi-Fi как «станция». Для этого мы используем функцию  esp_wifi_set_mode() и передаем в качестве параметра параметр WiFI_MODE_STA.

Затем мы назначаем SSID и пароль нашей сети. Таким образом, драйвер Wi-Fi настраивается с использованием учетных данных сети точки доступа и режима Wi-Fi. После этого мы запускаем Wi-Fi-соединение с заданными параметрами.

На этом этапе в журнале информации появляется сообщение «wifi_init_sta finished». Процесс инициализации Wi-Fi в режиме станции завершен.

Далее приложение переходит в заблокированное состояние, ожидая установки одного из битов в группе событий. Это происходит после инициализации и запуска Wi-Fi. Приложение остается в заблокированном состоянии до тех пор, пока не будет установлено соединение Wi-Fi (контролируется битом WIFI_CONNECTED_BIT) или пока соединение Wi-Fi не будет разорвано в течение максимального количества попыток (контролируется битом WIFI_FAIL_BIT).

Если функция event_handler() устанавливает значение WIFI_CONNECTED_BIT, указывающее на успешное подключение ESP32 к точке доступа, то в информационном журнале будет указано, что соединение установлено с SSID и паролем указанной точки доступа. Если же функция event_handler() устанавливает значение WIFI_FAIL_BIT, указывающее на невозможность подключения ESP32 к точке доступа даже после достижения максимального количества попыток, то в информационном журнале будет указано, что соединение с SSID и паролем указанной точки доступа не удалось.

Кроме того, мы удаляем группу событий 's_wifi_event_group' с помощью функции vEventGroupDelete(). Она была создана ранее с помощью вызова функции xEventGroupCreate().

API-интерфейсы esp_http_server.h для размещения веб-сервера на ESP32

Функция send_web_page() отвечает за отправку полного HTTP-ответа путем вызова функции httpd_resp_send(). API httpd_resp_send() принимает три параметра. Первый параметр — это запрос, на который должен быть дан ответ. Второй параметр — это буфер, из которого необходимо получить контекст. Третий параметр — это длина буфера. В функции send_web_page() HTTP-ответ состоит из показаний температуры в градусах Цельсия и Фаренгейта, полученных в функции DS18B20_readings().

Ниже представлена ​​структура обработчика uri-get. Выбранный метод — HTTP_GET, URL — «/», а обработчик для этого — get_req_handler, который возвращает ответ send_web_page().

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

Процесс начинается с определения конфигурации по умолчанию и присваивает пустое значение дескриптору HTTP-сервера. Оно устанавливается как NULL.

Функция httpd_start() запускает HTTP-сервер. Она принимает два параметра: конфигурацию для нового экземпляра сервера и дескриптор этого экземпляра. Если экземпляр был успешно создан, что означает, что функция вернула ESP_OK, то мы зарегистрируем обработчики URI. Функция принимает два параметра. Первый параметр — это дескриптор экземпляра HTTP-сервера, в данном случае 'server'. Второй параметр — это указатель на обработчик, который мы хотим зарегистрировать, — uri_get.

app_main()

Внутри функции app_main() сначала инициализируется NVS путем вызова  функции nvs_flash_init(). Затем проверяется, не содержит ли раздел NVS пустых страниц или содержит ли он данные в формате, отличном от текущей версии кода. Если выполняется хотя бы одно из этих условий, то с помощью функции nvs_flash_erase() происходит очистка флэш-памяти NVS  и повторная инициализация.

Затем мы выведем в терминале “ESP_WIFI_MODE_STA” и вызовем  функцию connect_wifi()  для подключения к Wi-Fi в режиме станции.

Если ESP32 успешно подключается к сети Wi-Fi, вызывается функция setup_server() для запуска HTTP-веб-сервера, и терминал выводит сообщение о том, что веб-сервер запущен. В противном случае терминал ESP-IDF выводит сообщение о сбое сети.

Компиляция скетча

Для прошивки микросхемы введите следующую команду в последовательном терминале. Не забудьте заменить COM-порт на тот, через который подключена ваша плата.

После успешной прошивки кода вы можете просмотреть все информационные журналы. Сначала инициализируется Wi-Fi станции. Затем мы можем просмотреть esp_netif_handlers, который включает IP-адрес, маску и адрес шлюза. Затем мы получаем запись «получен IP-адрес», за которой следует сам IP-адрес. Мы будем использовать этот IP-адрес для доступа к веб-серверу.

Тестирование работы проекта веб-сервера в окне терминала

Откройте новый веб-браузер и введите IP-адрес, полученный в терминале, затем нажмите Enter. Откроется веб-сервер ESP32 DS18B20, отображающий показания температуры, которые обновляются каждые несколько секунд.

Тестирование работы веб-сервера на ноутбуке

Тестирование работы веб-сервера на смартфоне

(Проголосуй первым!)
Загрузка...
4 просмотров

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

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