Курс Arduino с нуля · Индикаторы и экраны

Урок 27. Датчик DHT11: температура и влажность

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

Урок 27 из 31⏱ примерно 50 минутОбновлено: 30 июля 2026

Что понадобится

  • Плата Uno из набора
  • Кабель USB
  • Макетная плата
  • Датчик температуры и влажности DHT11
  • Резистор 10 кОм
  • 6 проводов «папа-папа»

Все детали есть в обучающем наборе, по которому идёт курс.

До сих пор наши датчики отдавали плате напряжение, а мы сами догадывались, что означают числа от 0 до 1023. Сегодня всё иначе: DHT11 измеряет сам и присылает готовые цифры — сколько градусов и сколько процентов влажности.

Заодно в этом уроке случится ещё одно первое: нам понадобится библиотека, которой нет в программе. Научимся её ставить — дальше это будет обычным делом.

Что это за деталь

решётка: сквозь неё датчик чувствует воздух12341вывод 1 — питание «плюс», 5 В2вывод 2 — линия данных, идёт на вывод 2 платы3вывод 3 — не используется, остаётся пустым4вывод 4 — «минус», земляДержите датчик решёткой к себе — тогда выводы считаются слева направо. Сам он размеромс ноготь: 15 × 12 мм, а расстояние между выводами — ровно как между отверстиями макетки.
DHT11: синяя коробочка с решёткой и четыре вывода. Работают только три из них — третий не подключается никуда.

Внутри корпуса спрятаны сразу два измерителя и маленькая микросхема. Один измеритель следит за температурой, второй — за влажностью воздуха, а микросхема превращает их показания в числа. Через решётку воздух попадает внутрь: закрывать её пальцем или клеить скотчем нельзя.

Что умеет датчик из набора:

  • температура от 0 до +50 °C, ошибка до 2 градусов;
  • влажность от 20 до 90 %, ошибка до 5 процентов;
  • показания — целыми градусами и процентами, без десятых;
  • отвечать успевает не чаще одного раза в 2 секунды.

Мороз и кипяток датчику не по силам: ниже нуля и выше пятидесяти он просто не работает. Для комнаты, теплицы или ящика с растениями этого хватает с запасом.

Чем он отличается от прежних датчиков

Фоторезистор, датчик Холла, потенциометр — все они были аналоговыми: деталь меняла напряжение, плата это напряжение измеряла командой analogRead и получала число 0…1023. Что значит «512», решали мы сами, и пороги приходилось подбирать опытом.

DHT11 — цифровой. Он сам делает измерение, сам переводит его в градусы и проценты и присылает плате готовый ответ. Никаких порогов подбирать не нужно: 23 — это двадцать три градуса, и всё.

Плата за это платит другим: с цифровым датчиком нужно договориться. Он не отвечает просто потому, что на него подали питание, — его нужно спросить, дождаться ответа и разобрать этот ответ. Всё это делает библиотека, но полезно знать, что там происходит.

Как датчик рассказывает о погоде

Плата UnoДатчик DHT11одна линия данных — один проводпо нему говорят по очереди: сначала плата, потом датчик10плата: измеряй!датчик отвечает: 40 бит подряд011010Длина верхней полочки и есть весь секрет: короткая — ноль, длинная — единица.Библиотека ловит эти полочки сама и складывает из них два числа: 23.0 °C и 45 %.
Разговор идёт по одному проводу и по очереди: плата прижимает линию к минусу — это вопрос; потом датчик отвечает сорока импульсами.

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

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

Весь разговор занимает около двадцати миллисекунд и целиком лежит на библиотеке. Нам останется одна команда «прочитать» и две готовые величины.

Зачем нужен резистор 10 кОм

Никто не тянет5 В10 кОм1платаDHT11Резистор подтянул линию к «плюсу»:на ней единица, тишина.Тянет плата5 В10 кОм0платаDHT11Плата прижала линию к минусу —это её вопрос датчику.Тянет датчик5 В10 кОм0платаDHT11Прижимает датчик — так онпередаёт нули и единицы.И плата, и датчик умеют только прижимать линию к минусу. Поднимать её обратно некому — этим и занят резистор.
Линию данных тянут вниз оба участника разговора. Поднимать её обратно к «плюсу» — работа резистора.

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

Вот для этого и нужен резистор 10 кОм между линией данных и «плюсом». Он слабо, но постоянно подтягивает линию вверх: как только оба отпустили — на линии единица. Такой резистор называют подтягивающим, и мы его уже видели в уроке про кнопки. Только там он был спрятан внутри платы, а здесь нужен настоящий.

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

Собираем схему

++abcdefghij1567820123451Датчик — решёткой к себе, четыре вывода в ряд a, столбики 5, 6, 7 и 8.2Питание платы: 5V на шину «+» нижней половины, GND — на шину «−».3Столбик 5 (вывод 1) идёт на «+», столбик 8 (вывод 4) — на «−». Столбик 7 остаётся пустым.4Резистор 10 кОм перекинут через канавку из столбика 6, а снизу от него провод уходит на «+».5Из столбика 6 провод идёт на вывод 2 платы — это и есть линия данных.Верхние шины закрыты корпусом датчика, поэтому всё питание берём с нижних.Провод соединён только там, где на нём светлая шляпка; шины он пересекает между отверстиями.
Датчик стоит в ряду a и закрывает корпусом верхние шины — поэтому питание берём с нижних.

Отключите USB и соберите по порядку.

  1. Вставьте датчик решёткой к себе в ряд a, четыре вывода в столбики 5, 6, 7 и 8. Корпус ляжет на верхние шины — так и должно быть.
  2. Питание макетки: 5V платы — на шину «+» нижней половины, GND — на шину «−».
  3. Вывод 1 (столбик 5) — проводом на «+». Вывод 4 (столбик 8) — на «−». Столбик 7 не трогаем вообще.
  4. Резистор 10 кОм: одна ножка в столбик 6 сверху от канавки, вторая — в тот же столбик 6, но снизу. От нижней ножки провод идёт на шину «+».
  5. И последний провод: из столбика 6 сверху — на вывод 2 платы. Это линия данных.
UnoD2GNDDHT11+DATA+5 ВR1 10 кОмВывод 3 датчика в схеме не участвует: он никуда не подключается.
То же самое языком схем: питание на датчик, линия данных на вывод 2 и резистор 10 кОм между линией и «плюсом».

Проверьте перед включением: решётка смотрит на вас; крайний левый вывод датчика идёт на «+», крайний правый — на «−» (перепутать их нельзя, от этого датчик может выйти из строя); третий вывод свободен; резистор соединяет столбик данных с «плюсом»; на макетке есть питание с платы.

Ставим библиотеку

Библиотеки Servo и LiquidCrystal из прошлых уроков были встроены в Trema IDE. С DHT11 так не выйдет — нужную библиотеку нужно поставить. Она называется iarduino_DHT, её сделал тот же магазин, что собрал ваш набор.

Проще всего дать программе разобраться самой: напишите первую строку скетча (она ниже) и нажмите «Проверить». Trema IDE увидит незнакомую строку и сама предложит установить библиотеку — окно так и называется, «Нужна библиотека». Соглашайтесь, установка занимает секунды.

Если окно не появилось, откройте слева раздел «Библиотеки», наберите в поиске iarduino_DHT и нажмите на карточке кнопку «Установить». Для установки нужен интернет — библиотека скачивается из каталога.

Библиотека ставится один раз и остаётся в программе навсегда: в следующих проектах с DHT11 её уже не придётся искать.

Шаг 1. Первые цифры

// Урок 27. Первые цифры: температура и влажность в мониторе порта.

#include <iarduino_DHT.h>

iarduino_DHT sensor(2);   // датчик подключён к выводу 2

void setup() {
  Serial.begin(9600);
  delay(1000);            // даём датчику проснуться после включения питания
}

void loop() {
  sensor.read();          // спрашиваем датчик: измерь и передай

  Serial.print("Температура: ");
  Serial.print(sensor.tem, 1);
  Serial.print(" C, влажность: ");
  Serial.print(sensor.hum, 0);
  Serial.println(" %");

  delay(2000);            // чаще раза в 2 секунды датчик спрашивать нельзя
}

Разберём новые строки.

  • #include <iarduino_DHT.h> — подключаем библиотеку, как раньше подключали Servo.
  • iarduino_DHT sensor(2); — создаём «свой датчик» и говорим, к какому выводу он подключён. Имя sensor мы выбрали сами, оно может быть любым.
  • sensor.read(); — спрашиваем датчик. После этой строки в sensor.tem лежит температура, а в sensor.hum — влажность.
  • Serial.print(sensor.tem, 1) — печатаем число с одним знаком после точки. Цифра 1 в конце и есть «сколько знаков показать».

Откройте монитор порта. Через пару секунд там появятся строки:

Температура: 23.0 C, влажность: 41 %
Температура: 23.0 C, влажность: 41 %
Температура: 23.0 C, влажность: 42 %

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

После точки всегда ноль — и это не ошибка. DHT11 измеряет целыми градусами, десятых он просто не знает. И ещё: температура почти всегда на градус-два выше, чем в комнате, — плата рядом греется, и датчик это чувствует.

Шаг 2. А если датчик не ответил?

Если в мониторе вместо чисел упрямые нули, значит датчик молчит: провод не в том столбике, забыт резистор или перепутаны выводы. Плохо то, что программа об этом даже не подозревает — она печатает что было.

Так вот: sensor.read() не только читает, но и возвращает ответ — получилось или нет. Проверим его.

// Урок 27. Сначала проверяем ответ датчика, потом печатаем.

#include <iarduino_DHT.h>

iarduino_DHT sensor(2);

void setup() {
  Serial.begin(9600);
  delay(1000);
}

void loop() {
  if (sensor.read() == DHT_OK) {
    Serial.print("Температура: ");
    Serial.print(sensor.tem, 1);
    Serial.print(" C, влажность: ");
    Serial.print(sensor.hum, 0);
    Serial.println(" %");
  } else {
    Serial.println("Датчик не ответил");
  }

  delay(2000);
}

DHT_OK — это готовое слово из библиотеки, означающее «всё хорошо». Теперь программа честно говорит, когда данных нет, а не выдаёт нули за показания. Проверьте: выньте провод данных из макетки — в мониторе побегут «Датчик не ответил».

Шаг 3. Четыре ответа и команда switch

«Не ответил» бывает по разным причинам, и библиотека их различает. Ответов всего четыре:

  • DHT_OK — данные пришли и сошлись;
  • DHT_ERROR_NO_REPLY — датчик вообще не отозвался;
  • DHT_ERROR_CHECKSUM — ответ пришёл, но искажённым;
  • DHT_ERROR_DATA — ответ не похож на показания DHT.

Писать четыре if подряд некрасиво. Для случая «одно значение, много вариантов» в программах есть отдельная команда — switch.

// Урок 27. Разбираем ответ датчика: switch на все четыре случая.

#include <iarduino_DHT.h>

iarduino_DHT sensor(2);

void setup() {
  Serial.begin(9600);
  delay(1000);
}

void loop() {
  switch (sensor.read()) {
    case DHT_OK:
      Serial.print("Температура: ");
      Serial.print(sensor.tem, 1);
      Serial.print(" C, влажность: ");
      Serial.print(sensor.hum, 0);
      Serial.println(" %");
      break;

    case DHT_ERROR_NO_REPLY:
      Serial.println("Датчик молчит — проверьте провода и питание");
      break;

    case DHT_ERROR_CHECKSUM:
      Serial.println("Ответ пришёл испорченным — помехи на линии");
      break;

    case DHT_ERROR_DATA:
      Serial.println("Ответ не похож на показания DHT");
      break;

    default:
      Serial.println("Что-то совсем непонятное");
      break;
  }

  delay(2000);
}

Читается она просто:

  • switch (что проверяем) — берём значение один раз;
  • case DHT_OK: — «если получилось вот это, делай следующее»;
  • break; — «на этом всё, из switch выходим». Забыть его — частая ошибка: программа поедет выполнять и следующий случай тоже;
  • default: — «на всё остальное». Полезен, даже если кажется лишним.

Теперь по монитору сразу видно, что не так. Оторвите провод данных — будет «датчик молчит». Возьмите провод подлиннее и потрясите — начнут попадаться «ответ пришёл испорченным».

Шаг 4. Смотрим на график

Помните вкладку «График» из урока про монитор порта? Вот теперь ей найдётся дело. Ей нужны просто числа, по одному в строке, — без подписей.

// Урок 27. Печатаем только число — для вкладки «График».

#include <iarduino_DHT.h>

iarduino_DHT sensor(2);

void setup() {
  Serial.begin(9600);
  delay(1000);
}

void loop() {
  if (sensor.read() == DHT_OK) {
    Serial.println(sensor.tem, 1);   // одно число в строке, без подписей
  }

  delay(2000);
}

Откройте вкладку «График» и подышите на датчик: кривая пойдёт вверх ступеньками, а потом медленно вернётся. Ступеньки крупные, потому что датчик даёт целые градусы и отвечает раз в две секунды. Хотите смотреть на влажность — напечатайте вместо sensor.tem строку sensor.hum.

Шаг 5. Опрос по часам, без delay

Пока в программе стоит delay(2000), плата две секунды не делает ничего. Настоящему устройству это не подходит: оно должно успевать следить за кнопкой, мигать, считать время. Возьмём приём из урока про дребезг — часы millis().

// Урок 27. Опрос по часам: между замерами плата не стоит на месте.

#include <iarduino_DHT.h>

iarduino_DHT sensor(2);

const int LED = 13;             // встроенный светодиод платы

unsigned long lastRead = 0;     // когда последний раз спрашивали датчик
unsigned long lastBlink = 0;    // когда последний раз переключали светодиод
bool ledOn = false;

void setup() {
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
  delay(1000);
}

void loop() {
  unsigned long now = millis();

  if (now - lastRead >= 2000) {
    lastRead = now;
    if (sensor.read() == DHT_OK) {
      Serial.print("Температура: ");
      Serial.print(sensor.tem, 1);
      Serial.print(" C, влажность: ");
      Serial.print(sensor.hum, 0);
      Serial.println(" %");
    } else {
      Serial.println("Датчик не ответил");
    }
  }

  if (now - lastBlink >= 250) {
    lastBlink = now;
    ledOn = !ledOn;
    digitalWrite(LED, ledOn);
  }
}

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

Спрашивать датчик чаще, чем раз в две секунды, бессмысленно: он не успевает сделать новое измерение и отвечает ошибкой. Число 2000 в программе — не прихоть, а требование датчика.

Шаг 6. Сигнал «стало жарко»

Сделаем из датчика простейший сторож: как только теплее 26 градусов — светодиод горит. Чтобы он не мигал на границе, поставим два разных порога — приём из урока про датчик света.

// Урок 27. Светодиод загорается, когда в комнате стало жарко.

#include <iarduino_DHT.h>

iarduino_DHT sensor(2);

const int LED = 13;             // встроенный светодиод платы

const float TEM_ON = 26.0;      // выше этого — зажигаем
const float TEM_OFF = 24.0;     // ниже этого — гасим

bool warm = false;              // сейчас жарко?

void setup() {
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
  delay(1000);
}

void loop() {
  if (sensor.read() == DHT_OK) {
    if (!warm && sensor.tem >= TEM_ON) {
      warm = true;
    }
    if (warm && sensor.tem <= TEM_OFF) {
      warm = false;
    }

    digitalWrite(LED, warm);

    Serial.print(sensor.tem, 1);
    if (warm) {
      Serial.println(" C — жарко");
    } else {
      Serial.println(" C — нормально");
    }
  }

  delay(2000);
}

Загорается на 26 градусах, гаснет только на 24. Между ними лампа не меняет решения, и дребезга на границе нет. Проверить легко: подержите датчик в ладони.

Здесь работает встроенный светодиод платы, поэтому паять и втыкать ничего не нужно. Хочется ярче — поставьте светодиод на вывод 10 через резистор 470 Ом, как в уроке 5, и замените в программе 13 на 10.

Не работает? Разбираемся

  • Ошибка сборки «iarduino_DHT.h: No such file or directory» — библиотека не установлена. Вернитесь к разделу «Ставим библиотеку».
  • Каждый раз «датчик молчит» — проверьте провод данных: он должен идти из столбика вывода 2 датчика на вывод 2 платы. Заодно проверьте резистор: без него молчание — обычное дело.
  • В мониторе нули — это старая программа из шага 1, она печатает показания, не спросив, получились ли они. Возьмите вариант с проверкой.
  • Показания появляются через раз — плохой контакт или слишком длинные провода. Пошевелите датчик в макетке: если ошибки идут волной, дело в контакте.
  • Влажность упёрлась в 90 или в 20 — это границы датчика. Подышали слишком усердно: дайте ему минуту-две, показания вернутся сами.
  • Температура выше, чем на настоящем термометре — так и будет. Датчик стоит рядом с греющейся платой, да и точность у него ±2 градуса.
  • Датчик заметно горячий на ощупь — немедленно выньте USB: скорее всего питание попало не на те выводы. Пересчитайте их, держа датчик решёткой к себе.

Задания для тренировки

  • РазминкаПечатайте только влажность и посмотрите на неё во вкладке «График». Подышите на датчик и дождитесь, пока кривая вернётся к обычным значениям — сколько это заняло?
  • ПосложнееДобавьте в монитор строку «сухо», когда влажность ниже 30 %, и «сыро», когда выше 60 %. В остальных случаях пусть будет «нормально».
  • Со звёздочкой ⭐Пусть программа помнит самую низкую и самую высокую температуру за всё время работы и печатает их рядом с текущей.
Разбор задания со звёздочкой

Хитрость одна: нельзя начинать с нулей. Если записать в «минимум» ноль, комнатные плюс двадцать три его никогда не побьют, и минимум навсегда останется нулём. Поэтому первый удачный замер задаёт сразу и минимум, и максимум — за этим следит отдельная переменная haveNumbers.

// Урок 27. Разбор задания: помним самое холодное и самое жаркое.

#include <iarduino_DHT.h>

iarduino_DHT sensor(2);

float lowest = 0;
float highest = 0;
bool haveNumbers = false;       // был ли уже хоть один удачный замер

void setup() {
  Serial.begin(9600);
  delay(1000);
}

void loop() {
  if (sensor.read() == DHT_OK) {
    if (!haveNumbers) {
      lowest = sensor.tem;      // первый замер задаёт и минимум, и максимум
      highest = sensor.tem;
      haveNumbers = true;
    }
    if (sensor.tem < lowest) {
      lowest = sensor.tem;
    }
    if (sensor.tem > highest) {
      highest = sensor.tem;
    }

    Serial.print("Сейчас ");
    Serial.print(sensor.tem, 1);
    Serial.print(" C, минимум ");
    Serial.print(lowest, 1);
    Serial.print(" C, максимум ");
    Serial.print(highest, 1);
    Serial.println(" C");
  }

  delay(2000);
}

Тот же приём годится для любых «рекордов»: самая яркая вспышка, самое долгое нажатие, самая быстрая реакция.

Что мы узнали

  • Датчики бывают аналоговые (отдают напряжение, значение угадываем сами) и цифровые (считают сами и присылают готовые числа).
  • Цифровому датчику нужен разговор по правилам, и его ведёт библиотека. Библиотеку можно поставить в Trema IDE из каталога — программа предложит это сама.
  • На линии данных нужен подтягивающий резистор: участники разговора умеют только прижимать линию к минусу.
  • Чтение может не получиться, и хорошая программа это проверяет. Разбирать несколько вариантов ответа удобно командой switch.
  • У любого датчика есть предел скорости: DHT11 отвечает раз в две секунды, и спрашивать его чаще бесполезно.

Теперь у нас есть экран, который умеет показывать текст, и датчик, который знает погоду в комнате. В следующем уроке соединим их вместе и соберём настоящую метеостанцию — с цифрами на экране и без компьютера.

Частые вопросы

Как подключить датчик DHT11 к Arduino?

Датчик ставят в макетную плату решёткой к себе. Первый вывод идёт на плюс, четвёртый — на минус, второй — на цифровой вывод платы, а третий не подключается. Между линией данных и плюсом обязательно ставят резистор 10 кОм.

Какая библиотека нужна для DHT11?

iarduino_DHT — её делает тот же магазин, что собрал набор. В Trema IDE она ставится из каталога библиотек: программа сама заметит незнакомую строку include и предложит установку.

Зачем датчику DHT11 резистор 10 кОм?

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

Почему DHT11 показывает целые градусы, без десятых?

Такая у него точность: разрешение 1 градус и 1 процент, а ошибка до 2 градусов и 5 процентов. Дробная часть в показаниях всегда нулевая, и это нормально.

Как часто можно опрашивать DHT11?

Не чаще одного раза в 2 секунды. Если спрашивать быстрее, датчик не успевает сделать новое измерение и возвращает ошибку вместо показаний.

← Все уроки курса