Цифровой температурный датчик на основе arduino — arduino+

Создаем беспроводной термометр на Arduino

Узнайте, как использовать RF модуль 433 МГц совместно с ATMega328P-PU. В данной статье мы соберем схему из датчика DHT11 и радиочастотного передатчика. А также соберем приемное устройство с радиоприемником 433 МГц и LCD дисплеем.

Что нам потребуется

Введение

В данной статье я покажу вам, как собрать устройство, которое измеряет температуру и относительную влажность воздуха и посылает измеренные значения с помощью стандартного радиочастотного модуля 433 МГц. Датчик температуры и влажности, используемый в устройстве, – это DHT11.

Существует множество способов передачи небольшого объема данных с помощью Arduino или контроллеров ATMega. Один из них использует уже готовую библиотеку, подобную RCSwitch, Radiohead или VirtualWire.

Кроме того, можно отправить необработанные данные с помощью встроенного в микроконтроллер модуля UART. Но использовать встроенный модуль UART не рекомендуется, так как приемник будет собирать и все помехи, и микроконтроллер будет работать не так, как предполагалось.

В данной статье для передачи и приема данных я использую библиотеку VirtualWire. Эта библиотека работает с Arduino IDE 1.6.2 и 1.6.5.

Модуль передатчика 433 МГц, когда не передает данные, всё равно излучает радиочастотные колебания и передает шум. Он также может создавать помехи другим радиочастотным устройствам. Чтобы не допустить этого, я включаю его, когда необходимо передать данные, и выключаю его, когда передача закончена.

Аппаратная часть

Нам необходимы две структурные схемы. Одна для передающего устройства, вторая для приемного.

Передатчик

Нам необходимы:

  • способ прошивки микроконтроллера → ISP;
  • датчик для измерения температуры и влажности → DHT11;
  • микроконтроллер для обработки данных → ATMega32p;
  • способ беспроводной передачи данных → радиочастотный модуль 433 МГц.

Приемник

Нам необходимы:

  • способ приема радиосигнала → радиочастотный модуль 433 МГц;
  • способ обработки принятых данных → Arduino Mega;
  • способ отображения температуры и влажности → 16×2 LCD.

Принципиальные схемы

Передатчик

Передающая часть беспроводного термометра на ATMega328p (для увеличения масштаба можно кликнуть по картинке правой кнопкой мыши и выбрать «Открыть ссылку/изображение в новой вкладке/новом окне»)

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

Приемник

Приемная часть беспроводного термометра на Arduino Mega (для увеличения масштаба можно кликнуть по картинке правой кнопкой мыши и выбрать «Открыть ссылку/изображение в новой вкладке/новом окне»)

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

Перечень элементов

Передатчик

Перечень элементов передающей части беспроводного термометра на ATMega328p (для увеличения масштаба можно кликнуть по картинке правой кнопкой мыши и выбрать «Открыть ссылку/изображение в новой вкладке/новом окне»)

Приемник

Перечень элементов приемной части беспроводного термометра на Arduino Mega (для увеличения масштаба можно кликнуть по картинке правой кнопкой мыши и выбрать «Открыть ссылку/изображение в новой вкладке/новом окне»)

Программа

Программа передатчика

Сперва рассмотрим программу передающей части:

// Подключаем необходимые библиотеки #include #include // Определение #define dhtPin 4 #define dhtType DHT11 #define txPowerPin 8 // Использование библиотеки DHT DHT dht(dhtPin, dhtType); // Переменные char msg0[3]; char msg1[3]; int tem = 0; int hum = 0; // Функция первоначальной настройки — выполняется только один раз при включении void setup() { pinMode(txPowerPin, OUTPUT); pinMode(txPowerPin, LOW); vw_setup(4800); // Скорость соединения VirtualWire vw_set_tx_pin(9); // Вывод передачи VirtualWire } // Функция цикла — выполняется всегда void loop() { digitalWrite(txPowerPin, HIGH); hum = dht.readHumidity(); // Переменная хранит влажность tem = dht.readTemperature(); // Переменная хранит температуру itoa(hum, msg1, 10); // Преобразование влажности в массив char itoa(tem, msg0, 10); // Преобразование температуры в массив char strcat(msg0, msg1); // Сложение/объединение двух массивов vw_send((uint8_t *)msg0, strlen(msg0)); // Передача сообщения vw_wait_tx(); // Ждем завершения передачи digitalWrite(txPowerPin, LOW); delay(5000); // Ждем 5 секунд и повторяем всё снова }

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

На приемной стороне данные будут разделены на отдельные символы. Делая это, я ограничиваю себя двумя цифрами градусов. Если датчик находится в среде с температурой менее 10°C, я буду получать на дисплее символы мусора.

Например, если температура составляет 20°C, а влажность – 45%, то будет передаваться сообщение 2045, и всё хорошо. Если температура равна 9°C, а влажность – 78%, то передастся сообщение 978x, где «x» – случайный символ.

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

Программа приемника

// Подключаем необходимые библиотеки #include #include // Определение подключение LCD #define RS 9 #define E 10 #define D4 5 #define D5 6 #define D6 7 #define D7 8 LiquidCrystal lcd(RS, E, D4, D5, D6, D7); // Отрисовка символа градусов byte degreesymbol[8] = { B01100, B10010, B10010, B01100, B00000, B00000, B00000, B00000 }; // Переменные int tem = 0; int i; // Функция первоначальной настройки — выполняется только один раз при включении void setup() { lcd.begin(16,2); // Инициализация LCD lcd.createChar(1, degreesymbol); // Создание символа градусов в месте 1 Serial.begin(9600); // Для отладки vw_setup(4800); // Скорость соединения VirtualWire vw_rx_start(); // Готовность для приема vw_set_rx_pin(2); // Вывод приема VirtualWiore lcd.clear(); // Очистить LCD } // Функция цикла — выполняется всегда void loop() { uint8_t buf[VW_MAX_MESSAGE_LEN]; // Переменная для хранения принятых данных uint8_t buflen = VW_MAX_MESSAGE_LEN; // Переменная для хранения длины принятых данных lcd.setCursor(0,0); lcd.print(«Temp: «); if (vw_get_message(buf, &buflen)) // Если данные приняты { for (i=0;i

Источник: https://radioprog.ru/post/128

Arduino: осваиваем цифровой термодатчик и 1-Wire — «Хакер»

Моргания лампочки и замыкание контактов — дело интересное и полезное для первых шагов. Но, как все мы помним со школы, чем нагляднее эксперимент, тем он интереснее.

Я продолжу развивать проект из предыдущих серий, и сегодня мы прикрутим термодатчик 1-Wire для того, чтобы контролировать температуру в твоем многострадальном холодильнике.

Того и гляди, скоро у тебя появится «умный» холодильник :).

В предыдущих сериях

Так как я продолжаю повествование с некоей точки, а не с самого начала, то пройдусь по тому, что уже имеется. В нашем арсенале Arduino mega2560 с поднятой ОСРВ scmRTOS.

Прошивка позволяет моргать светодиодом L на плате в разных последовательностях в зависимости от «аварийного» или «нормального» состояния, а также «плеваться» в консоль грязными ругательствами (ведь ты именно такие выбрал?) в качестве уведомления об изменении состояния.

«Нормальность» состояния определяется замкнутостью контактного датчика. Последовательность можно менять из консоли. Исходники проекта выложены на GitHub.

Вдохнем новизны

Идея прикрутить термодатчик зародилась у меня еще до того, как я начал делать этот проект. Последовательность действий (а именно так и нужно действовать — последовательно и не пытаться забегать вперед) оттягивала этот момент, и я особо не забивал себе голову деталями. Но вот время пришло.

Так в чем проблема? А вот в чем: можно было взять обычный резистивный термодатчик и использовать встроенный АЦП микропроцессора.

Но! Я взялся за этот проект с правилом: минимум паяльника и дополнительного нестандартного оборудования, все из коробки.

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

Остался второй вариант — цифровой термодатчик. Правда, с ним тоже беда. Цифровой термодатчик подключается по интерфейсу 1-Wire, а такого интерфейса на плате нет. Зато есть вариант минимальными усилиями сделать программную эмуляцию этого интерфейса.

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

Немного о самом 1-Wire

1-Wire — это так называемый однопроводный интерфейс. Примечателен он тем, что для обмена данными с устройствами по этому интерфейсу требуется всего один сигнальный провод и один провод «земли».

Что еще более примечательно, устройства спроектированы таким образом, что по этому же сигнальному проводу они и «кормятся» (то есть для питания устройства используется все тот же сигнальный провод), такой режим называется «паразитным питанием».

Для реализации такого способа питания в устройствах ставят достаточно емкий конденсатор.

Для того чтобы начать сессию обмена данными, необходимо сформировать сигнал «сброс». Для этого мастер передает в линию данных 0 на время не менее 480 мкс. После чего мастер отпускает линию данных и начинает слушать линию.

За счет резистора подтяжки линия данных установится в 1. Если на линии присутствует устройство (датчик), то он передаст мастеру подтверждение сброса, для этого он удерживает линию данных в 0 на время 60–240 мкс.

Считав состояние линии, мастер узнает о присутствии на шине устройств, готовых к обмену.

Старт обмена даннымиДругие статьи в выпуске:

  • Содержание выпуска
  • Подписка на «Хакер»

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

Таким образом, чтобы передать 1, необходимо установить в линии 0 и держать его 15 мкс, после чего отпустить линию, которая за счет подтягивающего резистора перейдет в уровень 1.

Чтобы передать 0, необходимо установить в линии 0 на 15 мкс, а затем держать 0 на линии еще 60–120 мкс.

Передача данных 1-Wire

Честный 1-Wire

Предложенный вариант реализации интерфейса 1-Wire обладает одним недостатком. Точнее, двумя.

  1. Он жрет ресурсы (как любая программная эмуляция).
  2. Он неустойчив к помехам.

С первым недостатком можно еще как-то мириться, хотя по мере роста проекта ресурсов остается все меньше. Со вторым недостатком в боевом софте надо бороться семплированием сигнала. Что такое семплирование? Допустим, бит 1 передается 6 мкс.

Для того чтобы точно быть уверенным, что это 1, а не какая-то наводка, необходимо несколько раз в течение этих 6 мкс измерить состояние входного сигнала. Чем больше измерений ты проведешь, тем точнее будет твой результат и уверенность в правильности принятия данных. Однако 6 мкс — это ооочень мало, тут возникает вопрос разумности и аппаратных возможностей.

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

Настроить-то можно, но толку от этого не будет, так как надо учитывать накладные расходы на «проваливание» в прерывание, сохранение регистров, выход из прерывания. Другой вариант — мотание в цикле, но опять вопрос во времени. Такт процессора на частоте 16 МГц длится 1/16 мкс, то есть у тебя есть всего 16 тактов.

За это ничтожное время тебе надо прокрутить счетчик (цикл же), снять состояние сигнала, перейти к следующей итерации. С учетом оптимизации и прочих накладных расходов на СИ сделать это практически нереально. Выход один — использовать аппаратную микросхему интерфейса 1-Wire, подключаемую, например, по SPI-интерфейсу.

Железо

Итак, выбор пал на термодатчик компании Maxim, модель DS18S20 (что под рукой оказалось). Если ты полез гуглить, сразу предупреждаю: подавляющее количество примеров применения термодатчиков с Arduino построено на базе DS18B20. Он немного отличается, но в рамках нашего проекта разницы никакой.

Работа термометра

Для работы с термометром по 1-Wire необходимо выполнить (по крайней мере для знакомства с ним) всего три действия:

  • запустить измерение;
  • подождать время, необходимое АЦП термометра, чтобы зафиксировать показание;
  • считать показание из памяти термометра.

Как и с обычными АЦП, чем выше точность, тем больше времени требуется для проведения измерения, тем дольше нужна задержка перед попыткой чтения показаний.

Термодатчик имеет два режима работы: постоянное питание или паразитное питание. Я буду использовать режим паразитного питания. В этом режиме термодатчик кушает через подтягивающий резистор (4,7 кОм) линии 1-Wire, когда линия «свободна» или передается высокий уровень. Как раз это вторая деталь, которую необходимо найти, резистор 4,7 кОм.

WARNING

Будь внимателен при подключении термодатчика, при ошибке подключения ты можешь его сжечь. Если сам не силен, попроси умеющего товарища спаять тебе проводки, ничего зазорного в этом нет :).

Читайте также:  Распиновка контроллера esp32 wroom-32 1.0 - arduino+

Схема подключения термодатчикаФото подключения термодатчика

Теперь, когда с подключением ты более или менее разобрался, приступим ко второй части нашего остросюжетного боевика. Нужно писать софт. Я, как и большинство программистов, создание ленивое, поэтому я вопросил у Всезнающего Гугла, что уже придумано до нас и надо ли изобретать велосипед.

Самое вразумительное, что я нашел, — это библиотека OneWire, рекомендуемая ардуиновцами. Также нам пригодится творчество еще одного товарища из ардуиновского сообщества — библиотека, реализующая протокол обмена данными с термодатчиком.

Можно просто взять, собрать все это в обычный скетч и прошить в железку, на чем и успокоиться. Но ты помнишь про холодильник? А значит, будем вкорячивать это добро в наш проект.

Ось зла

Начал я с простого — заставил хотя бы собираться библиотеки. Обе библиотеки используют ардуиновские функции, поэтому пришлось внести некоторые изменения. Для начала добавим файл OneWire_Port.h в проект (он будет портом библиотеки OneWire для проекта) и приинклюдим его в файл OneWire.h, а затем начнем причесывание. А именно:

  • OneWire построена таким образом, что ей при создании экземпляра объекта скармливается номер ноги, на которой у тебя будет линия 1-Wire. Это тащит за собой кусочек мрака из недр библиотек Ардуино, поэтому я пошел простым путем и зашил хардкодом в конструктор класса OneWire нужные мне ноги. Да, теряем универсальность, но я пока не вижу применения с двумя шинами 1-Wire (хотя… ну да не сейчас). Исходя из схемы платы, я выбрал ногу PA6, которая выходит на колодку DIGITAL пин 28. PORTA &= ~_BV(PA6); DDRA &= ~_BV(PA6); bitmask = _BV(PA6); baseReg = &PINA;
  • OneWire использует задержки в микросекундах для реализации протокола 1-Wire, подсунем библиотечную функцию _delay_us() в файл OneWire_Port.h #define delayMicroseconds(usec) _delay_us(usec)
  • OneWire любит отключать прерывания во время выполнения очень маленьких задержек (несколько микросекунд), и я ее понимаю. Но сразу же оглянемся и подумаем о том, что у нас все-таки будет ось. А значит, включение прерываний разумнее проредить немного, чтобы случайно не потерять контекст выполнения на неопределенное время. Библиотека использует ардуиновские функции работы с прерываниями, подсунем ей стандартные через файл OneWire_Port.h: #define noInterrupts() __builtin_avr_cli() #define interrupts() __builtin_avr_sei()
  • В драйвере термодатчика используется задержка, измеряемая в миллисекундах. Тут разумнее использовать вызов функции ОС, особенно учитывая размер этих задержек. Для замены sleep на вызов функции ОС пришлось немного погородить макросов в OneWire_Port.h, комментарии в коде. // Количество «тиков» операционной системы (переключений контекстов) в секунду #define __CLOCKS_PER_SEC 1000 //Период системного таймера операционной системы #define PERIOD_TIMER_MS ( 1000UL / __CLOCKS_PER_SEC ) // Макрос перевода миллисекунд в количество тиков операционной системы #define MSEC_TO_TICK( X ) ( X / PERIOD_TIMER_MS ) #define delay(msec) OS::sleep( MSEC_TO_TICK(msec))

Внедрение агента в банду

Теперь либы собираются, настал черед вкрутить их в код проекта. Как удостовериться, что оно заработало? Элементарно: создаем экземпляр класса OneWire, затем DallasTemperature с параметром шины, на которую подключены термодатчики, и начинаем все это активно использовать.

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

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

Отмечу отдельно алгоритм поиска устройств на линии, очень увлекательный процесс, описан подробно в документации к iButton в разделе Network Capabilities.

Первый запуск

Выносим в отдельный поток

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

Немного подумав, я решил, что лучше сделать целый класс — движок работы с термодатчиками, унаследовав его от класса process, чтобы все собрать в одну кучку: сделать имплементацию функции-потока, дать этой функции доступ к членам класса, выставить наружу основные функции работы с термодатчиками.

Однако тут я уткнулся в жадность. Мне хотелось оставить возможность опроса термодатчиков из консоли и иметь сигнализацию. Сразу же возникает необходимость разделять общие ресурсы, так как теперь два потока будут дергать один термодатчик (а точнее, шину 1-Wire). Лезь в класс OneWire и добавляй ему приватного мембера OS::TMutex _mutex;.

Здесь начинается интересное. Мьютекс мы завели, но пользоваться им внутри класса неразумно, так как библиотека работы с термодатчиком написана очень сильно интегрировано и на лету дергает функции байтовой, а не пакетной приема-передачи по 1-Wire. Для локализации массовых вызовов я создал два метода: open и close для шины 1-Wire.

void OneWire::open() { _mutex.lock(); } void OneWire::close() { _mutex.unlock(); }

Затем пришлось прошерстить всю библиотеку DallasTemperature и обернуть вызовы функций работы с шиной 1-Wire в оболочку _wire->open() -> _wire->close().

Реализация функции потока обработки показаний термодатчика совсем проста.

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

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

float val; AnalogState new_state; if (!TemperatureEngine::temperature_get(0, &val)) { if (state != lost && ++ lost_cntr > 10 ) { state = lost; TAlarmMessage msg; msg.state = state; msg.src = TAlarmMessage::AI_ALARM; AlarmMessageBox.push(msg); } continue; } lost_cntr = 0; if (val < low_value) new_state = low; else if (val > high_value) new_state = high; else new_state = normal; if (new_state != state) { TAlarmMessage msg; msg.state = new_state; msg.src = TAlarmMessage::AI_ALARM; AlarmMessageBox.push(msg); } state = new_state;

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

Тут-то я и наступил на грабли. Я забыл про функцию инициации процесса измерения DallasTemperature::requestTemperatures. В ней стоят задержки для того, чтобы подождать, пока термодатчик производит измерение. Но я поставил _wire->close() перед этими задержками.

В итоге я получил странную картину: при запросе из терминала начинали скакать показания термодатчика.

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

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

Остается лишь добавить в поток обработки аварийных сообщений кейсы нового источника аварий.

template<> OS_PROCESS void TAlarmTask::exec() { for(;;) { TAlarmMessage msg; // Тут мы уснем до получения аварийного сообщения AlarmMessageBox.pop(msg); // Получили сообщение, теперь обработаем его if (TAlarmMessage::DI_ALARM == msg.src) { // Обработка аварий цифрового датчика }else if(TAlarmMessage::AI_ALARM == msg.src) { // Здесь вставляем код обработки аварий аналогового (термо)датчика } } }

Испытания огнем

Конечно же, огонь применять никто не собирается, пожаров нам только не хватает. Но полевые испытания провести стоит. Так как датчик достаточно инертный, то я решил извлечь хоть какую-то пользу от выделяемого компьютером тепла и засунул термодатчик под поток воздуха от процессорного кулера. Ура, температура поползла вверх!

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

Проверка срабатывания аварии

Заключение

Вот мы и сделали еще один сложный шаг к защите содержимого твоего холодильника не только от врагов, но и от разморозки. Теперь в твоем арсенале есть термодатчик, а так как используется линия 1-Wire, то ты уже самостоятельно можешь навесить и два, и три, и более термодатчиков.

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

Пиши, пиши, пиши! Железный привет, RESET :).

DANGER

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

WARNING

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

WARNING

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

Источник: https://xakep.ru/2015/05/10/arduino-digital-temp-wire/

Аналоговые датчики температуры и Arduino

В предыдущей статье я уже упоминал о том, как устроена аналоговая микросхема-датчик температуры, а сейчас предлагаю перейти к практике.Обычно, мы получаем сенсор в корпусе TO-92 (не перепутайте с транзистором):

На фото — популярный датчик TMP36 от Analog Devices.

Как видите, выводов три, и если смотреть в положении «надписью к нам, ножками вниз», то получается (слева направо): питание (Vs), выход (Vout), земля (GND). Главная особенность таких датчиков — значение напряжения на выходе однозначно определяет температуру, независимо от напряжения питания (!).

Последнее может варьироваться от 2,7 до 5,5 Вольт.

Это очень удобно, и позволяет нам выполнить проверку датчика вне схемы, если под рукой есть элемент питания 3В, хотя бы даже и батарейка CR2032. В активном состоянии датчик потребляет не более 50 мкА, для проверки в течение двух-трех минут вполне хватает. Собираем схему:

Теперь, подключая мультиметр к выходу датчика (разумеется, в режиме измерения напряжения), мы будем наблюдать напряжение около 0,78 В, что соответствует 28 °С.

Чтобы убедиться в работоспособности датчика, его надо слегка нагреть, отлично подойдут:

  • пальцы рук (температура вашего тела — 36,6 °С)
  • дующий горячим возухом фен (можно довести и до 50 °C)
  • кошка (температура 38-39 °C)

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

Конечно, даже простого пальца будет достаточно, чтобы увидеть результат:Теперь подключим датчик к Arduino.

Пусть выход будет подключаться к analog0, а питание — к стабилизированному питанию +5В Arduinio:Для чтения придется использовать АЦП, а ему, как известно, требуется опорное напряжение, надо выбрать один из трех вариантов: питание, внешнее на AREF или внутреннее.

Напряжение на выходе датчика TMP36 меняется от 100 мВ до 2В, так что использовать внутренний источник опорного напряжения 1,1В не получится. Хотя, такое значение у источника МК ATmega168/328, а вот в ATmega8 это будет уже 2,56 В. Гораздо проще ориентироваться на стабилизированные +5 В, которые поступают от USB.Чтобы правильно перевести показания датчика в температуру, надо сначала понять, какое напряжение мы прочитали. АЦП возвращает число от 0 до 1023, при этом 0 = 0В, 1023 = 5В для нашего случая. Поэтому:

voltage = 5 В / 1024 * sensor

Заглянем в документацию на датчик: там оговаривается, что изменение на один градус цельсия соответствует изменению на 10 мВ, при этом 500 мВ будет соответствовать температуре 0°C. Получаем формулу:

tempC = (voltage — 0.5) * 100

() {
.(38400);}

() {

voltage = 5.0 / 1024.0 * (0);
.(voltage);
.();
tempC = ( voltage — 0.5 ) * 100;
.(tempC);
.();
(1000);}

Одно маленькое замечание к тексту скетча: значение опорного напряжения надо писать именно «5.0», чтобы компилятор случаем не решил разделить 5 на 1024 целочисленным делением и не получил пожизненный ноль в итоге.

Вернемся к вопросу о точности. Наш АЦП имеет шаг измерения 4,9 мВ, в то время как сам датчик имеет погрешность ±1°C, или ±10 мВ.

Таким образом, даже если мы понизим опорное напряжение, например, до 3,3 В и получив таким образом шаг преобразования 3,3 / 1024 = 3,2 мВ, это повышение точности не спасет нас от ошибки самого сенсора.

С другой стороны, напряжение питания +5 В тоже может запросто «гулять» ±5%, но в итоге это порождает ту же самую ошибку ±10 мВ. Таким образом, как ни крути, для данной схемы погрешность измерения будет не менее ±2°C. Из этого следует, кстати, забавный метрологический вывод: дробную часть можно отбрасывать 😉

Читайте также:  Транспорт становится эффективнее с использованием облачных технологий - arduino+

(в статье использованы материалы из статьи про измерение температуры by ladyada)

Источник: http://mk90.blogspot.com/2009/07/arduino.html

Код программы к уроку 7. arduino и датчик температуры

/* * Набор для экспериментов ArduinoKit * Код программы для опыта №7: sketch 07 * * Датчик температуры *

* Написано для сайта http://arduinokit.ru

* * * Помощь сообщества Arduino.

* Посетите сайт http://www.arduino.cc

* * * ДАТЧИК ТЕМПЕРАТУРЫ * * Использование «Монитора порта» (Serial Monitor), чтобы прочитать * показания датчика температуры. * * TMP35/TMP36/TMP37 являются простыми в использовании датчиками температуры, * которые меняют напряжение на своем выходе прямо пропорционально температуре * окружающей среды. Вы можете использовать их во всех видах задач * автоматизации, где необходимо использовать изменение параметров в * зависимости от изменения температуры. * * * Передача информации от Arduino компьютеру тема еще более интересная, чем * предыдущие опыты, — мы начнем использовать последовательный порт Arduino. * До сих пор мы ограничивались в использовании простых светодиодов для индикации * каких либо событий. Теперь мы убедимся, что Arduino можете не только * сигнализировать о чем либо, но и с легкостью общаться с компьютером, если это * необходимо, а также выводить все виды текста и данных на любой терминал.

*

* Подключение оборудования: * *  Будьте осторожны при установке датчика температуры, т.к. он очень *  похож на транзистор и есть шанс ошибиться! Вам нужен тот, на котором нет *  надписи 222, а есть треугольный логотип или надпись «TMP».

* *  Если повернуть датчик плоской стороной к себе, а выводами вниз, то *  назначение выводов будет таким (с лева на право): 5V, СИГНАЛ, и GND. * *  Подключите вывод датчика «5V» к  общей шине +5 вольт. *  Подключите вывод «Сигнал» к аналоговому порту 0 (Pin0).

*  Подключите вывод «GND» к земляной шине (GND). * *  Комментарий к программе переведен *  11 октября 2014

*  специально для http://arduinokit.ru

*

*/

// Мы будем использовать аналоговый порт 0 (Pin0) для снятия
// показаний с сигнального вывода датчика температуры.

const int temperaturePin = 0;

void setup()
{

// В этом скетче, мы будем используем последовательный порт Arduino, // чтобы передать текст обратно на компьютер. // Для того чтобы общение происходило корректно, необходимо соблюсти // общий протокол обмена данными, а также скорость передачи информации. // Для этого мы воспользуемся функцию Serial.begin(), она используется

// для инициализации порта и согласования скорости связи.

// Скорость передачи информации через последовательный порт измеряется в // битах в секунду, кстати бит может быть либо логической «единицей», // либо логическим «нулем». «baud rate» — скорость передачи. // Скорость 9600 является очень широко используемой при передачи данных, // хотя и очень медленной, при такой скорости передается примерно 10

// символов в секунду.

Serial.begin(9600);
}

void loop() { // До сих пор мы использовали для наших скетчей только целые числа («INT»), // «int» в переводе на русский — целые числа — 0, 1, 23 и т.д.. // В этй программе, мы будем использовать значения «float». // «Float» в переводе с английского – плавающий, у таких чисел помимо целой,

// есть еще дробная часть например, 1,42, 2523,43121 и т.д.

// Мы объявляем три переменных, все они будут «float», т.е. дробные, или как // еще говорят с плавающей точкой. Мы можем объявить несколько переменных

// одного типа за раз, на одной строчке, через запятую с пробелом:

float voltage, degreesC, degreesF;

// Сначала мы измерим напряжение на аналоговом входе. Обычно для этого мы // использовали функцию analogRead(), которая возвращает число от 0 до 1023. // Здесь же мы написали специальную функцию, о ней чуть дальше, под // названием getVoltage(), которая возвращает напряжение (от 0 до 5 вольт),

// присутствующего на аналоговом входе.

voltage = getVoltage(temperaturePin);

// Теперь мы преобразовываем напряжения в градусы Цельсия. // В этой формуле используются данные полученные с датчика температуры.

// Следующая формула работает для датчика TMP36:

degreesC = (voltage — 0.5) * 100.0;

// Если у вас датчик TMP35 формулу нужно немного изменить, // соответственно закомментируйте функцию выше и раскомментируйте // следующую, в ней ничего не надо вычитать, так как у TMP35

// выходное напряжение 0,25 милли вольт, а не 0,75 как у TMP36:

// degreesC = voltage * 100.0;

// Хотя нам это и не очень нужно, но давайте преобразуем градусы Цельсия (C) // в градусы Фаренгейта (F) (система используемая в США).

// Это классическая формула преобразования C в F:

degreesF = degreesC * (9.0/5.0) + 32.0;

// Теперь мы будем использовать последовательный порт для вывода
// данных на монитор!

// Чтобы открыть окно монитора порта, нужно загрузить код, а затем // нажать кнопку «увеличительное стекло» на правом краю панели

// инструментов Arduino IDE, откроется дополнительное окно монитора COM порта.

// (ПРИМЕЧАНИЕ: не забудьте, о чем мы говорили ранее, что скорость передачи // должна быть одинаковой для обеих сторон (передающей стороны и принимающей. // Убедитесь, что контроль скорости передачи в нижней части окна установлен

// в 9600. Если это не так, исправьте его на 9600.)

// Также обратите внимание, что каждый раз, когда вы загружаете // новый скетч в Arduino, окно монитора порта закрывается. Это // происходит потому что последовательный порт используется также // и для загрузки кода! Когда загрузка будет завершена, вы можете

// повторно открыть окно монитора COM порта.

// Для передачи данных от Arduino в COM порт, мы используем функцию // Serial.print(). Вы можете добавить свой текст напечатав его в кавычках. // С русскими символами монитор не дружит! Сразу за вашим текстом будет // впечатано значение переменной, см. ниже, оно без кавычек, их 3 —

// voltage, degreesC, degreesF:

Serial.print(«voltage: «); Serial.print(voltage); Serial.print(»  deg C: «); Serial.print(degreesC); Serial.print(»  deg F: «);

Serial.println(degreesF);

// Вывод информации будет иметь вид подобно следующему:
// «voltage: 0.73 deg C: 22.75 deg F: 72.96»

// Обратите внимание, что все переменные выше заявлены как // «Serial.print», а для последнего «Serial.println». // Все слова и значения переменных будут выведены на экран в одной строке, // а вот после последней переменной будет произведен «перевод каретки»

// на новую строку, за это как раз и отвечает «println».

delay(1000); // повторение через одну секунду (можете поменять!)
}

float getVoltage(int pin) { // Эта функция имеет один входной параметр, получаемый с аналогового // порта. Вы могли заметить, что эта функция не имеет ключевого «void», // хотя «void» должен использоваться при объявлении функций, но если // только функция не возвращает никакого значение, у нас как раз случай, // наоборот, потому что возвращается значение с плавающей точкой,

// которое является настоящим напряжением на этом выводе (от 0 до 5 В).

// Вы можете написать свои собственные функции, которые принимают
// что-то в параметрах, и после возвращают какие-либо значения:

// Чтобы что-то принять в параметрах, укажите их тип и имя в скобках, // после имени функции (смотри выше). Вы можете указать несколько

// параметров, разделенных запятыми.

// Чтобы возвратить значение, укажите тип перед именем функции, // помните пример «float», и используйте функцию return() для возврата

// значение (см ниже).

// Если у вас нет необходимости, что-то получить, просто используйте
// пустые скобки «()» после имени функции.

// Если у вас нет необходимости возвращать какое либо значение,
// просто укажите «void» перед именем функции.

// Далее идет оператор возврата return() для нашей функции. Мы
// делаем все вычисления которые должны сделать:

return (analogRead(pin) * 0.004882814);

// Это уравнение преобразует значение напряжения от 0,0 до 5,0 В., // полученное с помощью функции analogRead() с аналогового порта, // в значения от 0 до 1023.

}

// Как еще можно попробовать использовать этот код?

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

// Прочитать показания с потенциометра — получится термостат!
// Ну и так далее, все в ваших руках!

Источник: http://arduinokit.ru/arduino/lessons-arduino/arduino-temperature-sensor.html

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

У Arduino есть два типа температурных сенсоров — цифровые и аналоговые. Аналоговые имеют в своей основе терморезистор, или термистор — полупроводниковый резистор, у которого явно выражена зависимость сопротивления от температуры, и она представляет собой гладкую функцию. Соответственно, измеряя его сопротивление, можно измерять температуру среды.

Схема измерения температуры с термистором Мы помним, что на плате Arduino UNO есть шесть аналоговых входов, которые, по сути, являются каналами АЦП. В один из таких каналов мы и включим термистор.

Однако как померить его сопротивление, если АЦП умеет измерять только напряжение? Умные ребята придумали для этого использовать схему простого делителя:Здесь U0 — известное напряжение, R0 — известное сопротивление, RT — сопротивление, зависящее от температуры, Uизм — измеряемое напряжение.

Из рисунка очевидно, что для измеряемого напряжения справедливо соотношение:
Откуда сопротивление термистора выражается так:
Однако померить сопротивление мало, нам ведь нужно получить температуру!

Уравнение Стейнхарта-Харта

Типовая зависимость  сопротивления термистора от температуры выглядит так:Уважаемые господа Джон Стейнхарт и Стэнли Харт в 1968 году опубликовали свою работу, посвященную калибровочным кривым термисторов, в которой экспериментально вывели уравнение, связывающее сопротивление и температуру полупроводниковых термисторов.

Вот это уравнение:Здесь a, b и с — калибровочные константы, так называемые коэффициенты Стейнхарта-Харта. Это уравнение аппроксимирует кривую с хорошей точностью при подобранных коэффициентах для конкретного термистора. Коэффициенты Стейнхарта-Харта могут указываться в даташите производителем термистора.

 А могут вместо них указываться табличные значения температур и сопротивлений для конкретного устройства.

Я понятия не имею, какой термистор в моем сенсоре, кто его произвел, какая у него модель, какие характеристики. Поэтому коэффициенты я буду искать сам. Магазин, в котором я покупал сенсор, предлагает использовать какие-то коэффициенты, однако китайцы такие китайцы и им не стоит доверять.

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

Сенсор в студию

Мой аналоговый температурный сенсор выглядит так:Черная круглая блямба на переднем плане — и есть термистор. На нем написано «103», а это значит что при комнатной температуре он имеет сопротивление 10 КОм (103=10*10^3). Далее идет микросхемка, которая есть ни что иное, как операционный усилитель LM358P.

Есть еще 2 простых резистора, на которых тоже написано 103, один из которых никуда не подключен. Еще помните формулу для RT? Вот мы и нашли для нее R0, оно равно 10 КОм. А U0 равно 5 В, я вам так скажу.

Больше на плате ничего нет!

Сенсор очень просто подключается к Arduino Sensor Shield, который, в свою очередь, надевается на Arduino [в этом соль Arduino, кто еще не понял], прям как у меня вот так:

Ну собственно все — железо готово к лабораторной работе.

Калибровочная установка

Для калибровки понадобится печка, которая показывает свою температуру, и держит ее при этом (!). Нет проблем — пошел в ИНХ СО РАН, их там в каждой лабе по несколько штук. Выбирай по цвету, что называется. Приглянулась мне вот такая:Вообще это типа нагревательный столик (30.

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

Собираем установочку: Arduino в комп, сенсор в крышечку с водой, крышечку на печку, хвостик под лавочку, накрываем печку колпачком из кварца.

Ваши варианты проведения эксперимента прошу оставлять в комментариях. Сразу скажу, что без воды получается куда отстойнее, чем с водой.

Методика калибровки 

Пристально смотрим на уравнение Стейнхарта-Харта и видим в нем три неизвестных. Это означает, что нам достаточно провести три измерения и получить, таким образом, три уравнения. Выбираем три точки на температурной шкале. Мне нравятся, например, 30, 40 и 50 градусов Цельсия.

Нагреваем печку до одной из температур, ждем 10 минут, чтобы все термодинамические процессы произошли и энтропия вселенной увеличилась, замеряем сопротивление. Потом повторяем все для второй и третьей температур. Составляем три уравнения и решаем систему (линейных кстати) уравнений.

Нам лениво и мы заставим это делать Mathcad, который нам таки-выдаст коэффициенты Стейнхарта-Харта. Думаю, тут все понятно.

Читайте также:  Солнечная энергия: делаем зарядное устройство

Serial Communication

Есть у Arduino такая классная штука — serial communication. Это есть явление общения компа с Arduino во время выполнения программы. Происходит это через USB-порт, который эмулирует COM-порт. Это позволяет мониторить состояние платы в реальном времени и даже посылать на нее команды с компа.

Чтобы вызвать Serial monitor, выберите в меню Tools->Serial Monitor или нажмите хитрую комбинацию из трех клавиш ctrl+shift+M во время выполнения программы.

Чтобы заставить Arduino вывести что-то в последовательный поток, просто воспользуйтесь функцией Serial.println(число) или Serial.println(«текст»).

Последовательный обмен необходимо инициализировать в setup(){}, всунув туда команду Serial.begin(бодрейт). Бодрейт (baudrate) — количество информации, передаваемой в единицу времени (не путать с битрейтом).

Arduino предлагает на выбор: 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200 бод.

Вот что бывает, если не согласовать бодрейт в своей программе и в мониторе последовательного порта:

У вас это и должно произойти, когда вы впервые откроете монитор. Не пугайтесь.

Кодим

Напишем коротенький код, чтобы мониторить измеряемое значение напряжения и вычисляемое значение сопротивления:
void setup() {
  Serial.

begin(115200);           //стартуем последовательное соединение
}

void loop() {
  double rt;                      //измеряемая величина
  Serial.

println(«voltage:»);     //пишем в поток слово для красоты
  rt=(analogRead(0));             //читаем значение с сенсора
  Serial.println(rt);             //выводим значение с сенсора в поток
  rt = ((10240000/rt) — 10000);   //вычисляем сопротивление по формуле
  Serial.

println(«resistance:»);  //пишем в поток еще одно слово для красоты
  Serial.println(rt);             //выводим значение сопротивления в поток 
  delay(5000);                    //ничего не делаем 5 секунд
}
В результате все красиво:

Вычисляем коэффициенты Стейнхарца-Харца

По описанной выше методике выписываем на листочек три значения сопротивления при трех разных температурах. Подставляем их попарно в три уравнения Стейнхарца-Харца и решаем систему.

Вот фотка моего маткадовского файлика:Обратите внимание, что я вместо коэффициента «c» написал «се» [цэ], потому что маткад не дает использовать символ «с» кроме как в значении скорости света.

Нижний вектор-столбец и есть наши искомые коэффициенты.

Еще раз кодим

Теперь напишем скетч, который позволит Arduino измерять температуру.

#include    //подключаем свою библиотеку с блэкджэком и логарифмами

double Steinhart(int value) {
  double Temp;                  //в итоге эта переменная станет температурой
  Temp = log((10240000/value-10000));    //считаем логарифм
//считаем температуру из уравнения Стейнхарта-Харта
  Temp = 1/(0.001768+0.00005719*Temp+0.

000001354*Temp*Temp*Temp);
  Temp = Temp-273.15;//переводим температуру в градусы Цельсия         
  return Temp; //передаем температуру обратно в loop
}

void setup() {
  Serial.

begin(115200); //стартуем последовательное соединение
}

void loop() {
//передаем в функцию Steinhart измеренное значение и выводим температуру, которую она вернет
  Serial.

println(int(Steinhart(analogRead(0)))); 
  delay(2000); //ничего не делаем 2 секунды
}
Резюме

Температура меряется все равно корявенько, дает расхождение до трех градусов. Процесс калибровки — сложная штука в плане правильного нагрева термистора и поддержания определенной температуры. Улучшение методики калибровки — подключение дополнительных термопар, создание термостатированной камеры, возможно, сильно изменят результаты в лучшую сторону. Кстати, неплохая темя для курсовой физика-второкурсника. Если у вас есть знакомый физик-второкурсник, посоветуйте ему эту идею! 

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

Источник: http://greenoakst.blogspot.com/2012/03/arduino.html

Термометр на Arduino с температурным датчиком LM35

Сегодня мы рассмотрим проект на Arduino для студентов-инженеров. В этой статье расскажем вам,  как сделать термометр на Arduino. Преимуществом строительства термометра на Arduino является простота конструкции. Мы уже познакомились с Ардуино и ее особенностями. Программирование Arduino намного проще, чем вы думаете.

Данный проект — цифровой термометр (цифровой датчик температуры Arduino), построенный на основе прецизионного интегрального датчика  LM35.

Цифровые термометры широко используются во многих электронных устройствах, таких как кондиционеры, для информирования о температурном уровне и управления процессами системы охлаждения.

В данной схеме задействован датчик температуры LM35 для определения уровня температуры, который может измерять от -55 до 150°С. Измеренная температура отображается на ЖК-дисплее 16х2 с помощью Arduino.

Необходимые компоненты для проекта «Термометр на Arduino»

Цифровой термометр на Arduino использует легко доступные компоненты, которые каждый может приобрести в любом магазине электроники.

  • Arduino
  • Датчик температуры LM35
  • ЖК-дисплей 16х2
  • Потенциометр 1кОм

Работа термометра

Выходное напряжение датчика LM35 линейно пропорционально температуре (по Цельсию).

Выход LM35 имеет масштабный коэффициент 10 мВ/°C , что означает, что при каждом повышении температуры на 1°C произойдет соответствующее увеличение выходного напряжения на 10мВ, следовательно мы можем легко прочитать значение измеряемой температуры.

Arduino имеет аналоговый вывод (A0), способный считывать аналоговые сигналы от любого датчика. Как показано на принципиальной схеме, аналоговый вывод A0 Arduino подключается к выходу LM35.

Распиновка датчика температуры LM35

Arduino имеет 10-битный встроенный АЦП, поэтому он может считывать значение от 0 до 1023 , то есть для нулевого напряжения он считывает 0000, а для VCC (5 В) он считывает 1023.

Таким образом, мы масштабируем значения 0 — 1023 в новый диапазон 0 — 500, потому что LM35 выдает значения с шагом 10мВ на каждый градус, так что максимально возможный прирост составляет 500 (5В/0,01В).

Используя это сопоставление, мы можем принимать каждое приращение в значении АЦП как шаг повышения по шкале. Если значение АЦП равно 27, то значение измеряемо температуры составляет 27°C.

Скетч термометра

#include long A; int B; LiquidCrystal lcd(12, 11, 5, 4, 3, 2); void setup() { lcd.begin(16,2); lcd.print(«THERMO METER»); pinMode(A0,INPUT); } void loop() { A=analogRead(A0); B=map(A,0,1023,0,500); lcd.setCursor(0,0); lcd.print(«TEMPERARTURE: «); lcd.setCursor(0,1); lcd.print(B); lcd.

print(«‘C «); }

Теперь перейдем к логике программы. Сначала нам необходимо объявить  переменную long «A», чтобы сохранить значение, считанное с LM35, которое имеет диапазон от 0 до 1023.

Затем объявляем другую целочисленную переменную «B» для хранения отображаемого (преобразованного) значения.

Значение температуры считывается из вывода A0 и хранится в переменной «A». Затем переменная «A» преобразуется в диапазон от 0 до 500 и сохраняется в переменной «B». Значение «B» выводиться непосредственно на ЖК-экране 16х2.

www.circuitsgallery.com

Источник: http://fornk.ru/3389-termometr-na-arduino-s-temperaturnym-datchikom-lm35/

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

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

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

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

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

Но в итоге я все же смог получить нужную программу (ссылка на скачивание в конце статьи) и загрузить ее в микроконтроллер, ура:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#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(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)Arduinolibraries после чего перезапустить программу Arduino IDE.

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

Если вы будете применять детали схожие с моими, должно заработать и у вас.

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

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

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

Источник: https://tsarevstudio.ru/blog/hobby/humidity_and_temp_with_dht11_and_arduinouno.html

Ссылка на основную публикацию