Выводим температуру и влажность помещения на LCD I2C дисплей. Подключение датчика DHT11 к Arduino UNO

Я продолжаю свое увлечение электроникой. Буквально вчера пришла посылка с моим набором для изучения Arduino UNO — конечно же сразу захотелось что-нибудь собрать.

Немного поигравшись с мигающими светодиодами, я решил протестировать остальное содержимое набора. Выбор пал на ЖК-дисплей и датчик температуры и влажности DHT11.

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

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

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

Датчик DHT11 очень неточный, поэтому использовать его в качестве источника информации для каких-то серьезных систем я бы не советовал, но для учебных целей он очень даже подходит.

Ниже я подробно расскажу как повторить данную конструкцию (если кому-то захочется) и приведу текст скетча для Arduino IDE.

Начнем с дисплея:

LCD I2C дисплей

На картинке приведен вид спереди и сзади. Как можно увидеть, мой экземпляр снабжен интерфейсом I2C (маленькая платка на задней стороне). Данный интерфейс очень упрощает подключение дисплея к Arduino — нужно использовать всего 4 контакта:

GRD — минус питания («земля»)
VCC — питание +5V
SDA — линия данных
SLC — линия синхронизации

Без I2C подключение LCD дисплея осуществляется несколько сложнее.

Датчик DH11 так же имеет 4 контакта, при этом один из них вообще не используется. Мой дачик уже расположен на платке, на которой сразу установлен дополнительный резистор (который требуется для нормальной работы датчика) и выведено 3 ножки:

датчик влажности dht11

Левая подписана как S — с нее поступает сигнал, правая — «-», ну а средняя получается «+» на нее подается питание.

Итак, собираем схему:

схема подключения датчиков в Arduino Uno

NB!  Перед монтажом схемы и внесением в нее каких-либо изменений обязательно отключайте питание всех элементов, иначе можно их банально сжечь — потом будет жалко.

1) Подключаем датчик:

  • S на A0
  • + на +5V
  • —  на GND

2) Подключаем LCD дисплей:

  • SDA на A4
  • SLC на A5
  • VCC на +5V (на Arduino UNO такой pin всего один и там уже обосновался провод питания идущий от датчика, поэтому лучше соединить VCC дисплея с «+» датчика (например джампером) или использовать для одного из устройств внешнее питание)
  • GND на GND Arduino («земли» на UNO как раз две, так что тут никаких проблем)

Сборка на этом закончена, осталось прошить микроконтроллер.
Вот код скетча:

#include <Wire.h> // Добавляем необходимые библиотеки
#include <LiquidCrystal_I2C.h>
#include "DHT.h"
#define DHTPIN A0 // к какому пину будет подключен сигнальный выход датчика
//выбор используемого датчика
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
//инициализация датчика
DHT dht(DHTPIN, DHTTYPE);
byte degree[8] = // кодируем символ градуса
{
B00111,
B00101,
B00111,
B00000,
B00000,
B00000,
B00000,
};
LiquidCrystal_I2C lcd(0x27,16,2); // Задаем адрес и размерность дисплея
void setup()
{
lcd.init(); // Инициализация lcd
lcd.backlight(); // Включаем подсветку
lcd.createChar(1, degree); // Создаем символ под номером 1
Serial.begin(9600);
dht.begin();
}
void loop() {
// Добавляем паузы в несколько секунд между измерениями
delay(2000);
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
// Read temperature as Celsius
float t = dht.readTemperature();
// Read temperature as Fahrenheit
float f = dht.readTemperature(true);
// Выводим показания влажности и температуры
lcd.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
lcd.print("Hum = % "); // Выводим текст
lcd.setCursor(7, 0); // Устанавливаем курсор на 7 символ
lcd.print(h, 1); // Выводим на экран значение влажности
lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
lcd.print("Temp = \1C "); // Выводим текст, \1 - значок градуса
lcd.setCursor(7, 1); // Устанавливаем курсор на 7 символ
lcd.print(t,1); // Выводим значение температуры
}

В данном коде используются библиотеки DHT и LiquidCrystal_I2C, которые не входят в стандартный пакет Arduino IDE. В сети множество разных библиотек с такими же названиями. И несмотря на их схожесть, не со всеми версиями данный код работает. Чтобы вам не тратить свое время и нервы на поиск рабочего варианта, я прикладываю к данной статье архив, в котором содержатся данные библиотеки и сам скетч для Arduino IDE.  Библиотеки надо разархивировать и поместить в папку C:\Program Files (x86)\Arduino\libraries после чего перезапустить программу Arduino IDE.

Я думаю, что опытные разработчики найдут к чему придраться в данном коде (например, здесь нет обработчика ошибок), но на данном этапе, для меня главное, что он работает. Если вы будете применять детали схожие с моими, должно заработать и у вас. Конечно, рекомендую не просто скопировать, но и попытаться понять за что отвечает каждая строчка кода (комментарии в коде сильно в этом помогут).

Быстрые результаты в любом деле это не цель, а всего лишь мотивация, которая должна подталкивать вас копать глубже. Помните об этом! =)

P.S. Статья нашла своих читателей, что меня, как автора, очень радует. Если у Вас что-то не получается, обратите внимание на комментарии, там много полезной информации. Огромное спасибо всем читателям, поделившимся своим опытом!

Комментарии приветствуются! Уже 29 :)

  1. Павел:

    А у меня вот так пишет. Неверная библиотека найдена в C:\Program Files (x86)\Arduino\libraries\Humidity_and_temp: нет заголовочных файлов.

  2. Александр:

    Вопрос гдупый, но што за переходник используется для подключения к 5в?

  3. Кирилл:

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

  4. Виктор:

    Чем можно заменить UNO

  5. Влад:

    Почему пишет после температуры nan и также после влажности?

    • Влад:

      Проблему решил поменяв 2 провода местами и кодом для дисплея/датчика :

      #include

      #include

      #include «DHT.h»

      // назначение PIN и выбор типа датчика DHT

      #define DHTPIN 4 //

      // раскомментировать нужную строку

      #define DHTTYPE DHT11 // DHT 11

      //#define DHTTYPE DHT22 // DHT 22 (AM2302)

      //#define DHTTYPE DHT21 // DHT 21 (AM2301)

      DHT dht (DHTPIN, DHTTYPE); // инициализация сенсора DHT

      LiquidCrystal_I2C lcd (0×27,16,2); // инициализация дисплея

      byte symb_grad[8] = // кодирование символа градуса

      {

      B00111,

      B00101,

      B00111,

      B00000,

      B00000,

      B00000,

      B00000,

      };

      void setup ()

      {

      lcd.init (); // инициализация lcd

      lcd.createChar (1, symb_grad); // регистрируем собственный символ с кодом 1

      Serial.begin (9600); // запуск передачи данных

      dht.begin (); // запуск датчика DHT

      }

      void loop ()

      {

      // добавляем паузы в 2 секунды между измерениями

      delay (2000);

      float h = dht.readHumidity (); // считывание влажности

      float t = dht.readTemperature (); // считывание температуры

      // Выводим показания влажности и температуры

      lcd.clear (); // очистка экрана

      lcd.setCursor (0, 0); // установка курсора в начало 1 строки

      lcd.print ("Humidity: % "); // вывод текста

      lcd.setCursor (10, 0); // установка курсора на 10 позицию

      lcd.print (h, 1); // вывод на экран значения влажности

      lcd.setCursor (0, 1); // установка курсора в начало 2 строки

      lcd.print («Temperat: C»); // вывод текста

      lcd.setCursor (14, 1); // установка курсора на 14 позицию

      lcd.print («\1»); // вывод символа градуса

      lcd.setCursor (10, 1); // установка курсора на 10 позицию

      lcd.print (t,1); // вывод значения температуры

      }

      Могу скинуть схему)

  6. Valeriya:

    Этот скетч точно работает

    #include // Добавляем необходимые библиотеки

    #include

    #include «DHT.h»

    #define DHTPIN A0 // к какому пину будет подключен сигнальный выход датчика

    //выбор используемого датчика

    #define DHTTYPE DHT11 // DHT 11

    //#define DHTTYPE DHT22 // DHT 22 (AM2302)

    //#define DHTTYPE DHT21 // DHT 21 (AM2301)

    //инициализация датчика

    DHT dht (DHTPIN, DHTTYPE);

    byte degree[8] = // кодируем символ градуса

    {

    B00111,

    B00101,

    B00111,

    B00000,

    B00000,

    B00000,

    B00000,

    };

    LiquidCrystal_I2C lcd (0×27,16,2); // Задаем адрес и размерность дисплея

    void setup ()

    {

    lcd.init (); // Инициализация lcd

    lcd.backlight (); // Включаем подсветку

    lcd.createChar (1, degree); // Создаем символ под номером 1

    Serial.begin (9600);

    dht.begin ();

    }

    void loop () {

    Serial.print (analogRead (0));

    // Добавляем паузы в несколько секунд между измерениями

    delay (2000);

    // Reading temperature or humidity takes about 250 milliseconds!

    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)

    float h = dht.readHumidity ();

    // Read temperature as Celsius

    float t = dht.readTemperature ();

    // Read temperature as Fahrenheit

    float f = dht.readTemperature (true);

    // Выводим показания влажности и температуры

    lcd.setCursor (0, 0); // Устанавливаем курсор в начало 1 строки

    lcd.print ("Hum = % "); // Выводим текст

    lcd.setCursor (11, 0); // Устанавливаем курсор на 11 символ

    lcd.print (h, 6); // Выводим на экран значение влажности

    lcd.setCursor (0, 1); // Устанавливаем курсор в начало 2 строки

    lcd.print ("Temp = \1C "); // Выводим текст, \1 — значок градуса

    lcd.setCursor (11, 1); // Устанавливаем курсор на 11 символ

    lcd.print (t,6); // Выводим значение температуры

    }

  7. Вадим:

    код працює але не виводить значення

  8. Вадим:

    ось така помилка «exit status 1

    LiquidCrystal_I2C.h: No such file or directory»

  9. Максим:

    У меня такая же ошибка, выводит только 2.0 2.0 и первые буквы. Адрес дисплея свой вбил, все проверил, Датчик и пин свой выстовил, не пойму что не так. Уже 6 часов убил.

  10. Михаил:

    На дисплее изображено: H 3.6 и T 2.9. Прошу совета.

  11. Александр:

    LiquidCrystal_I2C lcd (0x3F,16,2); // Задаем адрес у некоторых нужно изменить адрес LCD

  12. Александр:

    Добрый день. Подскажите пож. все сделал как у Вас, работает, но выводит на экран не все. Вместо Hum и Temp выводит только H и T. А вместо влажности 35,9 и температуры 25,5 выводит 3,9 и 2,5 соответственно. Т.е. не все символы выводятся. В чем может быть проблема ?

    • Стас:

      Аналогичная проблема, решилось у вас как-то?

    • a:

      Аналогичная проблема, решилось у вас как-то?

      • filin:

        Если у кого выводятся только первые буквы в каждой строке то надо использовать другую библиотеку, сам потратил время, но нашел:

        #include // Для LCD экрана I2C

        #include // Для LCD экрана

        LiquidCrystal_PCF8574 lcd (0×27); // set the LCD address to 0×27 for a 16 chars and 2 line display

        если у кого решение по-изящнее прошу поделится

  13. Игорь:

    Спасибо всё заработало. в программе изменил датчик на 22.

  14. Anton Nikolaev:

    Статья отличная, подробная и понятная.

    Но экран был светел и пуст, несмотря на различные шаманства.

    Покрутил регулятор яркости сзади платы, и волшебным образом текст проявился.

    Добавлю, что при обратной крайности регулятора вместо текста видны белые квадраты как в комментарии Григория Щербакова.

    Надеюсь, это сбережёт кому-то время и нервы.

  15. Petr:

    Здравствуйте, у меня ошибка:

    exit status 1

    'DHT' does not name a type

  16. Сергей:

    Все работает, спасибо тебе дружище и процветания

  17. Дима:

    Разобрался! На моем ARDUINO MEGA 2560 надо подключать I2C не на А4 А5 как везде пишут, а на SDA 20 и SCL 21! Может кому поможет. Я 6 часов на это потерял!

  18. Дима:

    На ардуино мега не работает на дисплее просто черные квадратики в линию и все.

    Подскажите в чем дело?

    Все собрал по схеме.

    Код записал все нормально, но почему-то не работает.

  19. Dmitry:

    А ГДЕ ССЫЛКА НА БИБЛИОТЕКУ

    • Михаил Царев:

      Фраза в статье «архив, в котором содержатся данные библиотеки и сам скетч для Arduino IDE.» — это и есть ссылка, она выделена другим цветом — щелкните и начнется закачка архива.

  20. Maksim:

    Спасибо) для пробной версии очень даже хорошо!

  21. Алексей:

    Спасибо.

    • Владимир:

      Так как решить проблему с тем что ничего нет на этом экране???

      • Владимир:

        блин всё дело в контрастности лсд дисплея было не настроено)))