Датчики температуры и влажности DHT11 и DHT22

DHT11 - вид спередиDHT11/DHT22 — довольно известные датчики для определения относительной влажности и температуры, состоят из емкостного датчика влажности и термистора. Также, датчик содержит в себе АЦП для преобразования аналоговых значений влажности и температуры.

Эти цифровые датчики основаны на протоколе, который для связи использует один провод/шину с открытым коллектором, поэтому обязательна подтяжка резистором 5-10кОм к плюсу питания. Основное различие между DHT11 и DHT22 заключается в том, что DHT22 имеет более высокое разрешение и более точен по сравнению с DHT11. Помимо этого, распиновка и программирование одинаковы для обоих.

В этой статье рассмотрены основы процесса протокола связи датчиков DHTxx. Кроме того, обратите внимание, что протокол, используемый DHTxx, не является то же, что и 1-проводная (1-Wire/OneWire) шина Dallas Semiconductor.

Распиновка DHT22 и DHT11

Распиновка DHT22 и DHT11 (pinout)

Выводы Описание
1 Vcc 3-5В питание
2 Data out Вывод данных
3 NC Не используется
4 GND Общий

Технические характеристики — DHT11 vs DHT22

DHT11 - вид сзади

Параметры DHT11 DHT22
Питание мин.
макс. 5.5В 5.5В
Потребляемый ток мин. 0.1мА 0.05мА
макс. 2.5мА 2.5мА
Измерение влажности мин. 20% 0%
макс. 80-95% 100%
точность 5% 2-5%
Измерение температуры мин. 0°C -40°C
макс. +50°C +80°C
точность ±2°C ±0.5°C
Частота измерений 1Гц 0.5Гц
Расстояние между соседними 0.1″ 0.1″
Разрешение 8 бит 16 бит

Подключение датчиков DHT11/DHT22 к Arduino

При подключении к микроконтроллеру, вы можете между выводами Vcc и Data разместить подтягивающий (pull-up) резистор номиналом 4.7-10 кОм. Плата Arduino имеет встроенные pull-up, однако они очень слабенькие — порядка 20-150 кОм в зависимости от использованного микроконтроллера.
Подключение датчиков DHT11/DHT22 к Arduino UNO

Считывание данных с датчиков DHT11/DHT22

Микроконтроллер выступает в роли ведущего устройства шины и, следовательно, отвечает за инициирование связи (т. е. чтение). Датчик влажности и температуры DHT11 всегда остаётся в качестве подчиненного устройства и отвечает данными, когда MCU просит его. Протокол, используемый для связи, прост и может быть обобщен следующим образом:
DHT11/DHT22 - Процесс коммуникации (protocol)

Процесс коммуникации

  1. Микроконтроллер подаёт стартовый сигнал — прижимает шину к земле на 18-20 мс;
  2. После этого контроллер отпускает линию и следить за уровнем на ней, примерно 20-40 мкс;
  3. Датчик, обнаружив сигнал и подождав пока уровень снова станет высоким, сам прижимает шину к земле на 80 мкс, за это время делаются измерения и преобразование результатов;
  4. Затем DHT11 отпускает линию на 80 мкс, что указывает на то, что он готов отправить данные;
  5. Затем он отправляет 40 бит данных. Перед отправкой каждого бита датчик прижимает шину к земле на 50 мкс, за которым следует 26-28 мкс для «0» или 70 мкс для «1»;
  6. По завершении связи линия вытягивается подтягивающим резистором и переходит в состояние ожидания.

DHT11/DHT22 - Процесс коммуникации (protocol)

Формат данных DHT11/DHT22

Когда датчик влажности и температуры отправляет данные, он сначала отправляет MSb (Most Significant Bit) — старший значащий бит. Данные от датчика передаются в виде посылки, состоящих из 40 бит данных — это 5 байт из которых первых два влажность, следующие 2 температура и байт четности. Байт четности равен сумме предыдущих байт. 1 и 2 байт содержат соответственно целую и дробную часть информации о влажности, 3 и 4 байт содержат целую и дробную часть информации о температуре. Для датчика DHT11 2-й и 4-й байты всегда ноль. Значение этих байтов заключается в следующем:

  • 1-й байт: относительная влажность — целая часть в %;
  • 2-й байт: десятая часть относительной влажности в % (ноль для DHT11);
  • 3-й байт: целая часть температуры в °C;
  • 4-й байт: десятая часть температуры в °C (ноль для DHT11);
  • 5-й байт: контрольная сумма (последние 8 бит {1-й байт + 2-й байт + 3-й байт + 4-й байт})

Библиотеки и пример программы на Arduino

Для работы с датчиками я использую библиотеки от Adafruit, а именно: Adafruit Unified Sensor Library и DHT Sensor Library.

Пример программы — DHT_Unified_Sensor.ino

// DHT Temperature & Humidity Sensor
// Unified Sensor Library Example
// Written by Tony DiCola for Adafruit Industries
// Released under an MIT license.

// Depends on the following Arduino libraries:
// - Adafruit Unified Sensor Library: https://github.com/adafruit/Adafruit_Sensor
// - DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library

#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>

#define DHTPIN            2         // Pin which is connected to the DHT sensor.

// Uncomment the type of sensor in use:
#define DHTTYPE           DHT11     // DHT 11 
//#define DHTTYPE           DHT22     // DHT 22 (AM2302)
//#define DHTTYPE           DHT21     // DHT 21 (AM2301)

// See guide for details on sensor wiring and usage:
//   https://learn.adafruit.com/dht/overview

DHT_Unified dht(DHTPIN, DHTTYPE);

uint32_t delayMS;

void setup() {
  Serial.begin(9600); 
  // Initialize device.
  dht.begin();
  Serial.println("DHTxx Unified Sensor Example");
  // Print temperature sensor details.
  sensor_t sensor;
  dht.temperature().getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.println("Temperature");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" *C");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" *C");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" *C");  
  Serial.println("------------------------------------");
  // Print humidity sensor details.
  dht.humidity().getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.println("Humidity");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println("%");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println("%");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println("%");  
  Serial.println("------------------------------------");
  // Set delay between sensor readings based on sensor details.
  delayMS = sensor.min_delay / 1000;
}

void loop() {
  // Delay between measurements.
  delay(delayMS);
  // Get temperature event and print its value.
  sensors_event_t event;  
  dht.temperature().getEvent(&event);
  if (isnan(event.temperature)) {
    Serial.println("Error reading temperature!");
  } else {
    Serial.print("Temperature: ");
    Serial.print(event.temperature);
    Serial.println(" *C");
  }
  // Get humidity event and print its value.
  dht.humidity().getEvent(&event);
  if (isnan(event.relative_humidity)) {
    Serial.println("Error reading humidity!");
  } else {
    Serial.print("Humidity: ");
    Serial.print(event.relative_humidity);
    Serial.println("%");
  }
}

Результат

Пример программы DHT11 на Arduino

Материалы и Datasheet

DHT11 Datasheet
DHT22/AM2302 Datasheet
Basics of Interfacing DHTxx Humidity and Temperature Sensor with MCU
Работа с датчиком влажности DHTxx в Bascom-AVR
Arduino Uno: Датчик температуры и влажности DHTxx

Купить DHT11 и DHT22 на Aliexpress

Похожие записи

Комментарии 4

  • Как сделать чтобы показывал минусовую температуру?

    • А какую библиотеку используйте? С библиотекой от adafruit https://github.com/adafruit/DHT-sensor-library проблем быть не должно.
      Если у вас стандартная библиотека ардуино, можете изменить .cpp файл примерно так, как пишут тут:
      Было так:

      if (bits[2] & 0x80) // negative temperature
      {
      	bits[2] = bits[2] & 0x7F;
      	sign = -1;
      }
      temperature = sign * word(bits[2], bits[3]) * 0.1;
      

      Стало так:

      if (bits[2] & 0x80) // negative temperature
      {
      	bits[2] = bits[2] & 0x7F;
      	sign = -1;
      	temperature =  word(bits[2], bits[3]) * -0.1;
      } else {
      	temperature = sign * word(bits[2], bits[3]) * 0.1;
      }
      

      Но можно сделать примерно так:

      if (bits[2] & 0x80) // negative temperature
      {
      	bits[2] = bits[2] & 0x7F;
      	temperature =  word(bits[2], bits[3]) * -0.1;
      } else {
      	temperature = word(bits[2], bits[3]) * 0.1;
      }
      
  • Есть ТЕХНИЧЕСКИЙ вопрос. Хочу использовать DHT11/DHT22 как датчик
    температуры, но при НЕПОСРЕДСТВЕННОМ контакте с объектом.

    На фото привожу «скальпированный» DHT11: сверху в прозрачном окошке
    нечто сложное (мелкоскопа под рукой нет), снизу чёрный чип на печатной
    плате. Вопрос — какая часть должна иметь тепловой контакт с объектом?
    Подозреваю, что верхняя (где под окошком скорее всего термистор в виде
    зигзагообразного напыления)… тогда надо монтировать этой стороной
    на объект — так я понимаю (чип будет сверху)..?

  • пытаюсь подключить DHT11 к orange pi 3 lts, не подскажете где код можно взять для считывания данных?

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

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