В данной статье мы рассмотрим подключение датчика температуры и влажности SHT31 к плате ESP32 с помощью ESP-IDF. Будет представлено краткое описание датчика, описание его подключения к плате ESP32, а также настройка проекта в VS Code с расширением ESP-IDF для сбора данных с датчика и их отображения на консоли.
Также на нашем сайте вы можете посмотреть другие проекты с использованием датчика SHT31:
- веб-сервер мониторинга температуры и влажности на ESP32 и датчике SHT31;
- подключение датчика температуры и влажности SHT3x к Arduino.
Сенсорный модуль SHT31
Модуль датчика SHT31 используется в электронных проектах для измерения температуры окружающей среды и относительной влажности. Модуль использует микросхему SHT31 от компании Sensirion для получения высокоточных данных с датчика и охватывает широкий диапазон измерений температуры и влажности. Кроме того, он отличается низкой стоимостью и компактностью, а для передачи данных на микроконтроллер используется протокол связи I2C. Этот протокол основан на синхронной многомастерной системе, где плата ESP32 выступает в роли ведущего устройства, а датчик SHT31 — в роли ведомого. Благодаря широкому диапазону рабочего напряжения от 2,15 до 5,5 В, он является отличным выбором для использования с микроконтроллерами.
На приведенной ниже схеме показан модуль датчика SHT31 с интерфейсом I2C, при этом микросхема датчика SHT31 выделена с одной стороны.
Распиновка модуля датчика SHT31
На приведенной ниже схеме показана распиновка модуля датчика SHT31.
Как видно на приведенной выше схеме, датчик SHt31 имеет шесть контактов. Два из них — это контакты питания, два — контакты связи по протоколу I2C, а два других — контакты выбора адреса I2C (AD) и вывода оповещения (AL).
| VIN | Это контакт питания, который подключается к источнику 3,3 В микроконтроллера ESP32. Вы можете подавать питание в диапазоне 2,4–5,5 В. |
| GND | Общий провод (земля) |
| SCL | Это контакт интерфейса I2C, который будет генерировать тактовый сигнал. |
| SDA | Это контакт интерфейса I2C, используемый для отправки и приема данных. |
| AD | Этот контакт является контактом выбора адреса I2C. Он позволяет пользователю изменять адрес I2C модуля датчика. По умолчанию, когда этот контакт находится в низком состоянии, адрес I2C равен 0x44. Когда состояние этого контакта высокое, адрес I2C изменяется на 0x45. |
| AL | Этот контакт является контактом оповещения. Он служит триггером для мониторинга показаний температуры и влажности. Когда эти показания выходят за пределы заданного пользователем диапазона, состояние этого вывода переходит в высокое. Он остается в высоком состоянии до тех пор, пока показания не вернутся в заданный диапазон. |
Как видим, распиновка модуля немного сложнее чем у других известных датчиков температуры и влажности, однако он обладает и более расширенной функциональностью по сравнению с данными датчиками.
Технические характеристики датчика
Рассмотрим некоторые ключевые характеристики сенсорного модуля SHT31.
- Напряжение питания 2,4–5,5 В
- Средний ток питания составляет 1,7 мкА.
- Максимальный ток питания 1500 мкА.
Измерения влажности
- Типичная точность измерения относительной влажности составляет 2 % от относительной влажности.
- Диапазон рабочей относительной влажности: 0–100 % RH
- Время отклика (τ63%) равно 8 с
Измерения температуры
- Типичная точность измерения температуры составляет 0,2°C.
- Диапазон рабочих температур: -40–125°C
- Время отклика (τ63%) составляет менее 2 секунд.
Контакты I2C ESP32
Мы будем использовать интерфейс I2C для получения показаний датчика SHT31 с помощью ESP32 и ESP-IDF. Теперь давайте обсудим контакты I2C ESP32. На приведенной ниже схеме показана распиновка ESP32, где контакты I2C по умолчанию выделены красным цветом. Это контакты I2C по умолчанию модуля ESP32 DEVKIT. Однако, если вы хотите использовать другие контакты GPIO в качестве контактов I2C, вам придется установить их в коде.
Для более подробной информации по этим вопросам можете прочитать статью про использование интерфейса I2C в ESP32 с помощью ESP-IDF.
Подключение датчика SHT31 к ESP32
Для подключения платы ESP32 к сенсорному модулю SHT31 нам понадобятся следующие компоненты:
- Плата ESP32.
- Модуль датчика SHT31.
- Соединительные провода.
- Макетная плата.
Подключение модуля датчика SHT31 к плате ESP32 довольно простое, так как оно включает в себя лишь соединение 4 контактов (GND, VCC, SDA и SCL) с ESP32. Необходимо соединить вывод VCC с контактом 3,3 В, заземление с общим заземлением, контакт SCL датчика с контактом SCL платы ESP32, а контакт SDA датчика с контактом SDA платы ESP32. Для подключения модуля датчика будут использоваться стандартные контакты I2C платы ESP32.
В ESP32 по умолчанию для вывода SDA используется GPIO21, а для SCL — GPIO22.
Соединения между устройствами указаны в таблице ниже:
| Модуль датчика SHT31 | ESP32 |
| GND | GND |
| VCC | 3.3V |
| SDA | GPIO21(I2C SDA) |
| SCL | GPIO22 (I2C SCL) |
Измерение показаний SHT31 с помощью ESP32 и ESP-IDF
Мы создадим проект в VS Code с расширением ESP-IDF. Код будет считывать значения температуры и влажности, используя библиотеку I2C-устройств и sht3x.h. Мы будем использовать библиотеку SHT3x, написанную UncleRus.
Создание примера проекта
Откройте VS Code и перейдите в меню View > Command Palette («Вид» > «Палитра команд»). Введите в строке поиска ESP-IDF: New Project и нажмите Enter.
Укажите название проекта и каталог, а также плату и целевое устройство ESP-IDF. Мы назвали наш проект «SHT31». Для платы ESP-IDF мы выбрали опцию custom board («пользовательская плата»). Для целевого устройства ESP-IDF мы выбрали модуль ESP32. Нажмите кнопку ‘Choose Template’ («Выбрать шаблон»), чтобы продолжить.
В разделе «Расширение» выберите опцию ESP-IDF:
На вкладке get-started («Начало работы») мы щелкнем по пункту «sample_project». Затем нажмем ‘Create project using template sample_project’) («Создать проект, используя шаблон sample_project»).
Вы получите уведомление о создании проекта. Чтобы открыть проект в новом окне, нажмите «Да».
Это откроет проект, который мы создали на вкладке «Проводник». Внутри папки проекта находится несколько папок. Это справедливо для каждого проекта, который вы будете создавать с помощью ESP-IDF Explorer.
Для начала добавим необходимые заголовочные файлы для библиотек, требуемых для этого проекта. Создайте новую папку с названием «components» и добавьте в неё следующие три подпапки:
- esp_idf_lib_helpers
- i2cdev
- sht3x
Добавьте папки sht3x, esp_idf_lib_helpers и i2cdev в папку ‘components’, скопировав их по указанной ниже ссылке :
Теперь перейдите в основную папку и создайте новый файл с именем ‘Kconfig.projbuild‘ в этой же папке. Скопируйте файл из этого места в созданный файл.
Настройки MenuConfig в ESP-IDF для работы с датчиком SHT31
Теперь перейдём к menuconfig. Откройте редактор конфигурации ESP-IDF SDK. Прокрутите вниз и откройте раздел Example configuration («Пример конфигурации»). Здесь мы можем установить параметры конфигурации в соответствии с нашими потребностями. Это включает в себя демонстрационный режим, I2C-адрес SHT3x, вывод GPIO SCL и вывод GPIO SDA. Здесь вы можете увидеть, что мы установили демонстрационный режим как «Высокий уровень», I2C-адрес SHT3x как 0x44 (по умолчанию), SCL GPIO как 22 и SDA GPIO как 21. Вы можете изменить эти параметры в соответствии со своими требованиями, а затем нажать кнопку «Сохранить», расположенную вверху.
В качестве альтернативы, мы также можем установить это значение конфигурации с помощью menuconfig. Откройте menuconfig, набрав в терминале команду idf.py menuconfig. Эта команда откроет конфигурацию Espressif IoT Development Framework. Перейдите к разделу Example configuration («Примеры конфигурации») и установите соответствующие параметры.
- Теперь перейдите к файлу main.c. В папке main находится исходный код, то есть файл main.c будет находиться здесь. Перейдите в папку main > main.c и откройте его. Скопируйте приведенный ниже код из этого файла и сохраните его.
Код для отображения показаний датчика SHT31
Это пример скетча для драйвера sht3x. Он позволяет пользователям выбирать различные демонстрационные сценарии и реализует задачи либо в периодическом, либо в однократном режиме. В однократном режиме пользователь может выбрать либо высокоуровневый, либо низкоуровневый демонстрационный сценарий из меню menuconfig.
Если выбран параметр CONFIG_EXAMPLE_SHT3X_DEMO_HL, то для получения данных с датчика в каждом цикле используется функция верхнего уровня sht3x_meaure(). Считывание показаний датчика происходит в однократном режиме каждые 5 секунд.
Однако, если выбран параметр CONFIG_EXAMPLE_SHT3X_DEMO_LL, то данные датчика измеряются по одному, каждые 5 секунд, в однократном режиме с высокой повторяемостью. Затем устройство ожидает выходного сигнала и извлекает данные.
Если выбран параметр CONFIG_SHT3X_DEMO_PERIODIC, то датчик SHT3x запускается в периодическом режиме, выполняя измерения каждую секунду. Пользовательская задача получает данные измерений датчика каждые 2 секунды.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
/** * Simple example with SHT3x sensor. * * It shows different user task implementations in *single shot mode* and * *periodic mode*. In *single shot* mode either low level or high level * functions are used. */ #include <stdio.h> #include <freertos/FreeRTOS.h> #include <freertos/task.h> #include <esp_system.h> #include <sht3x.h> #include <string.h> #include <esp_err.h> /* float is used in printf(). you need non-default configuration in * sdkconfig for ESP8266, which is enabled by default for this * example. see sdkconfig.defaults.esp8266 */ #ifndef APP_CPU_NUM #define APP_CPU_NUM PRO_CPU_NUM #endif static sht3x_t dev; #if defined(CONFIG_EXAMPLE_SHT3X_DEMO_HL) /* * User task that triggers a measurement every 5 seconds. Due to power * efficiency reasons it uses *single shot* mode. In this example it uses the * high level function *sht3x_measure* to perform one measurement in each cycle. */ void task(void *pvParameters) { float temperature; float humidity; TickType_t last_wakeup = xTaskGetTickCount(); while (1) { // perform one measurement and do something with the results ESP_ERROR_CHECK(sht3x_measure(&dev, &temperature, &humidity)); printf("SHT3x Sensor: %.2f °C, %.2f %%\n", temperature, humidity); // wait until 5 seconds are over vTaskDelayUntil(&last_wakeup, pdMS_TO_TICKS(5000)); } } #elif defined(CONFIG_EXAMPLE_SHT3X_DEMO_LL) /* * User task that triggers a measurement every 5 seconds. Due to power * efficiency reasons it uses *single shot* mode. In this example it starts the * measurement, waits for the results and fetches the results using separate * functions */ void task(void *pvParameters) { float temperature; float humidity; TickType_t last_wakeup = xTaskGetTickCount(); // get the measurement duration for high repeatability; uint8_t duration = sht3x_get_measurement_duration(SHT3X_HIGH); while (1) { // Trigger one measurement in single shot mode with high repeatability. ESP_ERROR_CHECK(sht3x_start_measurement(&dev, SHT3X_SINGLE_SHOT, SHT3X_HIGH)); // Wait until measurement is ready (constant time of at least 30 ms // or the duration returned from *sht3x_get_measurement_duration*). vTaskDelay(duration); // retrieve the values and do something with them ESP_ERROR_CHECK(sht3x_get_results(&dev, &temperature, &humidity)); printf("SHT3x Sensor: %.2f °C, %.2f %%\n", temperature, humidity); // wait until 5 seconds are over vTaskDelayUntil(&last_wakeup, pdMS_TO_TICKS(5000)); } } #else // CONFIG_SHT3X_DEMO_PERIODIC /* * User task that fetches latest measurement results of sensor every 2 * seconds. It starts the SHT3x in periodic mode with 1 measurements per * second (*SHT3X_PERIODIC_1MPS*). */ void task(void *pvParameters) { float temperature; float humidity; esp_err_t res; // Start periodic measurements with 1 measurement per second. ESP_ERROR_CHECK(sht3x_start_measurement(&dev, SHT3X_PERIODIC_1MPS, SHT3X_HIGH)); // Wait until first measurement is ready (constant time of at least 30 ms // or the duration returned from *sht3x_get_measurement_duration*). vTaskDelay(sht3x_get_measurement_duration(SHT3X_HIGH)); TickType_t last_wakeup = xTaskGetTickCount(); while (1) { // Get the values and do something with them. if ((res = sht3x_get_results(&dev, &temperature, &humidity)) == ESP_OK) printf("SHT3x Sensor: %.2f °C, %.2f %%\n", temperature, humidity); else printf("Could not get results: %d (%s)", res, esp_err_to_name(res)); // Wait until 2 seconds (cycle time) are over. vTaskDelayUntil(&last_wakeup, pdMS_TO_TICKS(2000)); } } #endif void app_main() { ESP_ERROR_CHECK(i2cdev_init()); memset(&dev, 0, sizeof(sht3x_t)); ESP_ERROR_CHECK(sht3x_init_desc(&dev, CONFIG_EXAMPLE_SHT3X_ADDR, 0, CONFIG_EXAMPLE_I2C_MASTER_SDA, CONFIG_EXAMPLE_I2C_MASTER_SCL)); ESP_ERROR_CHECK(sht3x_init(&dev)); xTaskCreatePinnedToCore(task, "sh301x_test", configMINIMAL_STACK_SIZE * 8, NULL, 5, NULL, APP_CPU_NUM); } |
Мы определим параметр CONFIG_SHT3X_DEMO_PERIODIC и объясним принцип работы этой части.
Как работает код?
Для начала мы подключим необходимые библиотеки для этого проекта. Это включает библиотеку SHT3x для доступа к API для настройки устройства sht3x и получения данных с датчиков.
|
1 2 3 4 5 6 7 |
#include <stdio.h> #include <freertos/FreeRTOS.h> #include <freertos/task.h> #include <esp_system.h> #include <sht3x.h> #include <string.h> #include <esp_err.h> |
Сначала мы создадим дескриптор устройства ‘dev’ для sht3x_t.
|
1 |
static sht3x_t dev; |
Для реализации задачи пользователя в периодическом режиме мы используем следующую функцию task().
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
void task(void *pvParameters) { float temperature; float humidity; esp_err_t res; ESP_ERROR_CHECK(sht3x_start_measurement(&dev, SHT3X_PERIODIC_1MPS, SHT3X_HIGH)); vTaskDelay(sht3x_get_measurement_duration(SHT3X_HIGH)); TickType_t last_wakeup = xTaskGetTickCount(); while (1) { // Get the values and do something with them. if ((res = sht3x_get_results(&dev, &temperature, &humidity)) == ESP_OK) printf("SHT3x Sensor: %.2f °C, %.2f %%\n", temperature, humidity); else printf("Could not get results: %d (%s)", res, esp_err_to_name(res)); // Wait until 2 seconds (cycle time) are over. vTaskDelayUntil(&last_wakeup, pdMS_TO_TICKS(2000)); } } |
Эта функция запускает периодические измерения данных с датчика с частотой одно измерение в секунду. Это делается путем вызова функции sht3x_start_measurement(). Эта функция принимает три параметра: указатель на структуру дескриптора объекта, режим измерения и повторяемость.
|
1 |
ESP_ERROR_CHECK(sht3x_start_measurement(&dev, SHT3X_PERIODIC_1MPS, SHT3X_HIGH)); |
После запуска измерения sht3x мы добавляем задержку, пока измерение не будет готово.
|
1 |
vTaskDelay(sht3x_get_measurement_duration(SHT3X_HIGH)); |
Внутри бесконечного цикла while мы получаем показания датчиков с помощью функции sht3x_get_results() для значений температуры и влажности. Эти данные выводятся на терминал ESP-IDF каждые 2 секунды.
|
1 2 3 4 5 6 7 8 9 10 11 |
while (1) { // Get the values and do something with them. if ((res = sht3x_get_results(&dev, &temperature, &humidity)) == ESP_OK) printf("SHT3x Sensor: %.2f °C, %.2f %%\n", temperature, humidity); else printf("Could not get results: %d (%s)", res, esp_err_to_name(res)); // Wait until 2 seconds (cycle time) are over. vTaskDelayUntil(&last_wakeup, pdMS_TO_TICKS(2000)); } |
Компиляция скетча
Для прошивки микросхемы введите следующую команду в последовательном терминале. Не забудьте заменить COM-порт на тот, через который подключена ваша плата.
|
1 |
idf.py -p COMX flash monitor |
После успешной прошивки кода вы сможете просмотреть показания температуры и влажности в консоли.
