Рейтинг@Mail.ru

Как подключить датчик температуры и влажности HTU21D

2 комментарии Arduino
Print Friendly, PDF & Email
Рассмотрим подключение цифрового датчика температуры и влажности HTU21D и научимся считывать с него показания. Причём как с использованием готовых библиотек, так и без них.

Для проекта нам понадобится:

1Описание и характеристики датчикавлажности и температуры HTU21D

Датчик HTU21D является цифровым датчиком для измерения температуры и влажности с подключением по интерфейсу I2C. Каждый датчик индивидуально калибруется и тестируется на заводе. Основные технические характеристики:

  • напряжение питания: 1,5…3,6 В;
  • ток потребления: ≤ 4 мА, в режиме ожидания – 0,08 мкА;
  • диапазон измерения влажности: 0…100%;
  • диапазон измерения температуры: -40…+125°C с точностью ±0,3°C;

Датчик измеряет температуру с разрешением 12…14 бит и влажность с разрешением 8…12 бит. Разрешение может быть изменено программно.

На самом деле HTU21D является представителем целого небольшого семейства датчиков температуры и влажности. Все они начинают свои названия с HTU2xx. В названии датчиков заложена следующая информация:

  • Число после "HTU2" показывает точность измерения влажности: "0" соответствует ±5%, "1" соответствует ±3%.
  • Буква после численного обозначения показывает тип датчика: D – цифровой (интерфейс I2C), P – аналоговый (PWM, ШИМ), S – сигма-дельта модуляция (SDM), преобразуемая в аналоговую.
  • Опциональное "F" в конце означает наличие специального фильтра, который защищает датчик от пыли и влаги.
Наименование семейства датчиков HTU2xx
Наименование семейства датчиков HTU2xx

Сенсор имеет миниатюрные размеры. Зачастую датчик можно приобрести в составе готового модуля, который подключается непосредственно к контроллеру (Arduino или другому). Одна из многочисленных разновидностей готового модуля с датчиком показана на фотографии.

Модуль с датчиком HTU21D
Модуль с датчиком HTU21D

На данном модуле минимум радиодеталей: собственно, сам датчик HTU21D, два подтягивающих линии SCL и SDA резистора номиналом по 4,7 кОм, а также фильтрующий конденсатор по питанию.

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

2Подключение датчика влажности и температуры HTU21D к Arduino

Датчик HTU21D управляется по интерфейсу I2C, и ему необходим 3-вольтовый сигнал управления (абсолютный максимум для ножек ввода-вывода, согласно техническому описанию, составляет 3,9 В). Arduino генерирует 5-вольтовый сигнал. Поэтому желательно подключать датчик с помощью преобразователя логического уровня по такой схеме:

Схема подключения датчика HTU21D к Arduino через преобразователь логического уровня
Схема подключения датчика HTU21D к Arduino через преобразователь логического уровня

На данной схеме показаны резисторы 4.7 кОм, которые подтягивают линии SCL и SDA к питанию 3,3 В. Если вы замкнули перемычку в модуле, то эти резисторы не нужны.

Для того чтобы использовать датчик, скачаем библиотеку HTU21D (она также приложена в конце статьи). Установим библиотеку как обычно. Загрузим пример SparkFun_HTU21D_Demo (File Examples SparkFun HTU21D humidity and temperature sensor breakout). В мониторе порта побегут измеренные значения температуры и влажности. Вживую это может выглядеть так:

Подключение датчика HTU21D к Arduino через преобразователь логического уровня
Подключение датчика HTU21D к Arduino через преобразователь логического уровня

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

3Чтение показаний датчика HTU21D без библиотек

Взаимодействие с датчиком осуществляется по интерфейсу I2C. Чтобы посылать команды датчику и читать ответы необходимо знать набор команд:

Команды датчика HTU21D
КомандаКод командыПримечание
Начать измерение температуры0xE3Удержание мастера
Начать измерение влажности0xE5Удержание мастера
Начать измерение температуры0xF3Без удержания мастера
Начать измерение влажности0xF5Без удержания мастера
Записать в пользовательский регистр0xE6
Прочитать пользовательский регистр0xE7
Сброс0xFE

Датчик поддерживает два режима измерений – с удержанием мастера и без удержания мастера (ведущего устройства). При получении команды с удержанием мастера датчик блокирует линию частоты SCK и все дальнейшие команды не будут выполняться, пока датчик не закончит измерения. В режиме без удержания датчик будет принимать следующие команды даже после начала измерений.

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

Структура пользовательского регистра датчика HTU21D
Структура пользовательского регистра датчика HTU21D

Сброс вызывает выключение датчика и повторное включение с настройками по умолчанию. Сброс занимает около 15 мс.

Для изучения датчика используем отладочную плату с микросхемой FT2232H. Она так же 3-вольтовая, как и датчик, и преобразователь уровня здесь не нужен. Подключим GND датчика к GND отладочной платы, 3.3V датчика к одной из ножек общего назначения GPIO отладочной платы (например, ADBUS7, как на фото), линию SCL интерфейса I2C датчика к выводу ADBUS0 платы, а линию SDA датчика – параллельно к выводам ADBUS1 и ADBUS2.

Подключение датчика HTU21D к FT2232H
Подключение датчика HTU21D к FT2232H

Подключим отладочную плату к USB порту компьютера. Далее воспользуемся программой SPI via FTDI для управления датчиком. Запустим её и выберем интерфейс I2C: меню «Устройство» Интерфейс I2C. Теперь нажмём Ctrl+C или «Подключить» в меню «Устройство». После подключения красный индикатор на вкладке устройства должен стать зелёным.

Выбор интерфейса I2C в настройках программы
Выбор интерфейса I2C в настройках программы

При подключении к FT2232 на портах GPIO обычно логическая единица. Соответственно, датчик HTU21D сразу включится. Для проверки можно нажать на кнопку «Сканировать». Программа проведёт поиск устройств на шине I2C и добавит адреса найденных устройств в выпадающий список. I2C адрес датчика HTU21D – 0x40. Теперь выберем из выпадающего списка наш адрес 0x40 (или 64 в десятичном представлении), и мы готовы посылать датчику команды и читать ответы.

Если датчик не включился, то идём в меню программы «Инструменты», выбираем «Чтение/запись GPIO», и подаём на вывод GPIO7 логическую единицу.

I2C адрес датчика HTU21D постоянный и несменяемый, поэтому нельзя на одну шину «повесить» одновременно несколько подобных датчиков. Однако можно включать питание датчиков таким образом, чтобы в один момент времени был активен только один датчик. Тогда можно иметь на одной шине I2C несколько датчиков HTU21D.

Сначала прочитаем пользовательский регистр датчика HTU21D чтобы узнать, в каком режиме он работает. Для этого ставим галочку в поле чтения в разделе «Команда» и вводим команду E7. Это значит, что перед чтением мы отправим датчику байт 0xE7, который, как мы помним, является командой чтения пользовательского регистра. Размер буфера указываем "1", т.к. необходимо прочитать один байт. Нажимаем на кнопку с таблицей для отображения принятых данных и нажимаем кнопку «Прочитать».

Чтение пользовательского регистра датчика HTU21D
Чтение пользовательского регистра датчика HTU21D

В приведённом примере датчик вернул число 0x02. В двоичном формате это 0000_0010. В соответствии с рисунком выше, где представлена структура пользовательского регистра, получается, что датчик настроен на разрешение при измерении влажности 12 бит, разрешение температуры 14 бит, получает питание более 2,25 В, встроенный нагреватель отключён, а также отключена перезагрузка регистра при включении. Что, кстати, соответствует значению по умолчанию для этого регистра. А вот так выглядит сигнал на шине I2C во время обмена данными с датчиком:

Временная диаграмма чтения пользовательского регистра датчика HTU21D по I2C
Временная диаграмма чтения пользовательского регистра датчика HTU21D по I2C

На линии SCL передаются по 9 тактовых импульсов для синхронизации данных: первые 8 – для синхронизации данных (передние фронты этих импульсов обозначены белыми стрелками), а во время 9-го импульса мастер проверяет наличие сигнала ACK от ведомого. Сигнал подтверждения ACK – это когда ведомый «прижимает» линию SDA к земле.

На верхнем рисунке мастер (в нашем случае микросхема FT2232H) отправляет на линию данных SDA шины I2C информацию, что сейчас будет передавать данные устройству с адресом 0x40, и получает подтверждение (ACK, от английского acknowledge) от ведомого (датчика HTU21D), что на шине имеется устройство с данным адресом. Если бы устройства с адресом 0x40 не было на шине, мастер бы не получил ответа, и дальнейший обмен не состоялся бы. Далее мастер отправляет на шину команду 0xE7 и получает подтверждение от ведомого, что он принял команду (ACK).

После этого (нижний рисунок) мастер отправляет на шину I2C сообщение, что сейчас будет читать из устройства с адресом 0x40, и получает от ведомого подтверждение (ACK). Данные 0x02 выставляет на шину уже ведомый. После этого ведомый не выставляет подтверждение (NAK, not acknowledge), что означает, что он закончил передачу.

Как видно, довольно большая работа происходит для чтения всего лишь одного байта данных. Такова плата за минимальное количество проводов в интерфейсе I2C.

Теперь самое интересное: давайте же прочитаем показания температуры и влажности.

Как уже упоминалось, датчик HTU21D может работать в двух режимах: с удержанием ведущего (hold master) и без удержания ведущего (no hold master). В режиме с удержанием ведущего датчик притягивает линию тактовых импульсов SCK к земле, и таким образом мастер оказывается в режиме ожидания. Пока датчик не закончит измерения, обмен приостанавливается. Однако в программе SPI via FTDI не реализовано такое поведение. Поэтому остаётся только использовать режим без удержания мастера.

В режиме без удержания мастера ведомый возвращает данные, как только они будут готовы, по запросу ведущего. Если запрос на чтение от ведущего пришёл, а данных у ведомого ещё нет, ведомый просто не выставляет ACK на шине. Это показано на рисунке ниже. Здесь голубым цветом отмечены участки, которые выставляет на шину ведомый, т.е. датчик HTU21D. Как видно, это 3 байта данных и несколько подтверждений ACK.

Последовательность обмена с датчиком HTU21D в режиме без удержания мастера (no hold master)
Последовательность обмена с датчиком HTU21D в режиме без удержания мастера (no hold master)

Чтобы прочитать данные температуры датчика HTU21D в программе необходимо в разделе записи указать команду F3 и нажать кнопку «Записать». После этого в разделе чтения указать число байтов для чтения. В данном случае это будет 3: два байта данных и один байт контрольной суммы. В приведённом примере датчик вернул 0x6C389D.

Настройки программы для чтения температуры с датчика HTU21D в режиме без удержания мастера (no hold master)
Настройки программы для чтения температуры с датчика HTU21D в режиме без удержания мастера (no hold master)

Вот как это преобразовать в значение температуры. В двоичном виде число 0x6C389D будет 01101100_00111000_10011101. Вместо значения битов статуса (см. предыдущий рисунок), какое бы значение там ни стояло, подставляем два бита "0". Далее объединяем младшую (LSB) часть со старшей (MSB) в одно число. Это будет значение STemp «в попугаях».

Данные (MSB)Данные (LSB)СтатусКонтрольная сумма
01101100001110000010011101
0x6C0x380x000x9D
0x6C38"STemp"0x9D

Если статус равен "00", значит в данных значение температуры; если статус "10", это данные влажности.

Далее подставляем STemp = 0x6C38 в формулу: T = STemp / 216 × 175.72 − 46.85 и получаем 24,68°C.

Контрольная же сумма считается по стандартному алгоритму 8-разрядных CRC. Мы уже разбирали этот алгоритм. Программу для расчёта контрольной суммы CRC можно скачать в конце этой статьи. Как видно из рисунка, если задать сообщение 0x6C38, то получим значение контрольной суммы как раз те самые 0x9D. Параметры для расчёта CRC приведены в техническом описании (datasheet) на датчик HTU21D.

Расчёт контрольной суммы показаний датчика HTU21D
Расчёт контрольной суммы показаний датчика HTU21D

Аналогично запрашивается значение влажности. Сначала отправляем команду датчику для начала измерения влажности: F5. А затем запрашиваем так же три байта.

Чтение показаний влажности датчика HTU21D
Чтение показаний влажности датчика HTU21D

В данном примере от датчика пришло число 0x6DAA32 или 01101101_10101010_00110010 в двоичном виде. Не забудем также, что вместо двух битов статуса записываются нули. Получаем:

Данные (MSB)Данные (LSB)СтатусКонтрольная сумма
01101101101010001000110010
0x6D0xA80x020x32
0x6DA8"SRH"0x32

Формула для пересчёта измеренного числа в проценты относительной влажности такая: RH = SRH / 216 × 125 − 6

Подставив 0x6DA8 в формулу получим значение влажности 47,54%.

4Чтение показаний датчика HTU21D без библиотек с помощью Arduino

Теперь, когда мы разобрались с протоколом обмена, давайте сделаем то же самое с помощью Arduino. Схему мы уже собирали. На этот раз давайте соберём схему без преобразователя уровня: если подключать датчик ненадолго, это не критично (нам же только провести один тест). В «боевой» схеме преобразователь уровня категорически рекомендуется. SCL и SDA шины I2C подтянем к питанию 3,3 В через резисторы номиналом 4,7…10 кОм.

Подключение датчика HTU2xx
Наименование семейства датчиков HTU2xx

А скетч будет такой:

Скетч чтения показаний температуры и влажности с HTU21D без библиотек (разворачивается)
#include <Wire.h>

const int htu21_addr = 0x40; // адрес датчика htu21d

void setup() {
  Serial.begin(9600);
  Wire.begin(); // инициализация i2c
}

void loop() {
  ReadTemperature();  
  ReadHumidity();
  delay(1000);
}

// Читает с датчика HTU21D температуру и выводит в COM-порт.
void ReadTemperature() {
  Wire.beginTransmission(htu21_addr); // начинаем общение с датчиком
  Wire.write(0xF3); // записываем команду на измерение температуры
  Wire.endTransmission(); // окончание передачи

  delay(100); // ждём готовности данных
  Wire.requestFrom(htu21_addr, 3); // запрашиваем 3 байта  

  int Stemp; // "сырые" данные температуры
  while (Wire.available()) { 
    int tmsb = Wire.read(); // читаем MSB температуры с датчика
    int tlsb = Wire.read() & 0xFC; // читаем LSB температуры с датчика и сбрасываем 2 младших бита
    int crc = Wire.read(); // читаем котрольную сумму    
    Stemp = tmsb * 256 + tlsb; // вычисляем значение Stemp
    // *256 это эквивалентно сдвигу на 8 бит влево: <<8 
    //Serial.println(Stemp, HEX);
  }
  double t = ConvertTemp(Stemp); // вычисляем температуру
  Serial.println("T = " + (String)t + "C"); // Выводим данные в COM-порт
}

// Преобразует температуру из "сырых" показаний датчика HTU21D в градусы Цельсия.
double ConvertTemp(int stemp){
  double t = stemp * 0.00268127 - 46.85; // 0.00268127 = 175.72/0x10000
  return t;
}

// Читает с датчика HTU21D относительную влажность и выводит в COM-порт.
void ReadHumidity() {
  Wire.beginTransmission(htu21_addr); // начинаем общение с датчиком
  Wire.write(0xF5); // записываем команду на измерение влажности
  Wire.endTransmission(); // окончание передачи

  delay(100); // ждём готовности данных
  Wire.requestFrom(htu21_addr, 3); // запрашиваем 3 байта  

  int Srh; // "сырые" данные влажности
  while (Wire.available()) { 
    int rmsb = Wire.read(); // читаем MSB влажность с датчика
    int rlsb = Wire.read() & 0xFC; // читаем LSB влажности с датчика и сбрасываем 2 младших бита
    int crc = Wire.read(); // читаем котрольную сумму
    Srh = rmsb * 256 + rlsb ; // вычисляем значение Srh
    //Serial.println(Srh, HEX);
  }
  double rh = ConvertRH(Srh); // вычисляем влажность
  Serial.println("RH = " + (String)rh + "%"); // Выводим данные в COM-порт
}

// Преобразует влажность из "сырых" показаний датчика HTU21D в проценты.
double ConvertRH(int srh) {
  double rh = srh * 0.0019073 - 6; // 0.0019073 = 125/0x10000
  return rh;
}

При запуске монитора последовательного порта увидим следующее:

Вывод показаний датчика HTU21D в монитор порта
Вывод показаний датчика HTU21D в монитор порта

Как видно, мы научились читать и расшифровывать показания датчика HTU21D с помощью Ардуино и без применения сторонних библиотек.

Работа с датчиком температуры и влажности HTU21D с помощью программы "SPI via FTDI"

Скачать вложения:

Последнее изменениеВоскресенье, 11 Февраль 2024 19:50 Прочитано 8832 раз

Поблагодарить автора:

Поделиться

Print Friendly, PDF & Email

2 комментарии

  • Олег
    Олег 18.01.2023 16:11 Комментировать

    "В «боевой» схеме преобразователь уровня категорически рекомендуется"...... зачем в схеме нужен преобразователь уровней, если вы можете использоватьподтягивающие резисторы внешние или на модуле к 3.3в, а интерфейс I2C mosfet-транзисторами внутри камня просто подтягивает их к GND, создавая таким образом логические уровни. Если не включать подтяжку внутри камня к питанию (что по умолчанию не происходит), то это избыточное усложнение схемы и посути бесполезное. Целесообразно наверное это делать только в случае подвешивания на шину еще других устройств и спитанием 5в, но это редкость чтобы они не работали с уровнями 3,3в, главное проследить чтоб негде в схеме больше небыло подтяжек к 5в, что и так обязательно всегда делать.

  • aave1
    aave1 18.01.2023 18:06 Комментировать

    Олег, спасибо за дополнение!

Оставить комментарий