Термометр Arduino з температурним датчиком LM35. Цифровий термометр DS18B20 та ARDUINO UNO

Про цифрових термометрівна основі Arduinoбуло сказано чимало. Усі вони або підключалися до комп'ютера, або виводили температури одразу на дисплей.
Але мені потрібен був вуличний термометр, який автономно і відправляє дані на сайт. Отже, почнемо.

Що нам знадобиться:
  • Arduino Duemilanove (Freeduino 2009)
  • Ethernet Shield v2
  • цифровий датчик температури - DS18B20
  • вентилятор для корпусу (120 мм)
  • банку від водоемульсійки або клею ПВА (2 літри)
  • світлодіод
  • кручена пара
Завдання
Опитувати датчик температури по шині 1-Wire та кожні 3 секунди самостійно надсилати результати на Web-сервер, на якому вони зберігатимуться.
Алгоритм роботи пристрою:
  1. привласнюємо нашому Ethernet Shield`у MAC адресата ip-адреса
  2. ініціалізуємо з'єднання з сервером на 80 порт
  3. отримуємо дані з цифрового датчика температури, по 1-Wire шині
  4. формуємо GET запит
  5. надсилаємо GET запит
  6. розриваємо з'єднання
Вихідний код скетчу:
Коментарі по ходу коду мають внести ясність.
include
// Бібліотеки нижче немає у стандартному постачанні середовища розробки Arduino.
// Прийде її скопіювати.
include

// MAC-адреса нашого пристрою
byte mac = (0x00, 0x3A, 0xF1, 0x19, 0x69, 0xFC);
// ip-адреса пристрою
byte ip = (192, 168, 1, 156);
// ip-адреса віддаленого сервера
byte server = (79, 140, 28, 20); // Змініть на свій
char temp;
byte isdata=0;

Client client(server, 80); // 80-порт.
DallasTemperature tempSensor;

void setup()
{
Ethernet.begin(mac, ip); // Ініціалізуємо Ethernet Shield
tempSensor.begin(7); // Датчик температури на 7 пін
Serial.begin(9600); // Швидкість консольного порту 9600 (годиться для налагодження)
}

void loop()
{
delay(3000); // Затримка 3 сек.
// З'єднуємося
if (client.connect()) (
Serial.println("connecting..."); // Serial.println для налагодження. Краще його залишити, про всяк випадок, потім легше зрозуміти, у чому проблема.
// Обробник помилок датчика
switch (tempSensor.isValid())
{
case 1:
Serial.println("Invalid CRC"); // помилка контрольної суми
tempSensor.reset(); // скинути девайс
return;
case 2:
Serial.println("Invalid device"); // якийсь "лівий" датчик:)
tempSensor.reset(); // скинути девайс
return;
}

Serial.println("connected");
char buf;
float f=tempSensor.getTemperature(); // Отримуємо температуру

Serial.println(tempSensor.getTemperature());

// Нижче збочення з відділенням дробової частини та цілої. Чомусь Arduino не хоче працювати з float.
// Замість числа вставляє питання. Напевно, виною тому відсутність апаратної підтримки роботи з
// Числами з плаваючою комою в Arduino. Радий побачити красивіше рішення в коментарях.
int temp1 = (f - (int) f) * 100; // виділяємо дробову частину
// Складаємо GET запит. Змінна code потрібна для того, щоб ворожий термометр не надсилав будь-яких значень.
// перевіряється за Web-сервера.
sprintf(buf, "GET /class/backend/meteo.php?temp=%0d.%d&code=123456 HTTP/1.0", (int f), abs (temp1));

Serial.println(buf);
client.println(buf); // Надсилаємо GET запит
client.println("Host: opck.info"); // Вказуємо, який саме host цьому ip нас цікавить.
client.println();

) else (
Serial.println("connection failed");
}

while (client.available()) (
isdata=1;
char c = client.read(); // Читаємо, що нам відповів Web-сервер
Serial.print(c);

if (!client.connected()) (
isdata=0;
Serial.println();
Serial.println("disconnecting.");
client.stop(); // Завершуємо з'єднання
}
}


Складання пристрою:
  1. першу «ногу» датчика чіпляємо на «мінус» GND
  2. другу «ногу» (DQ) на 7-й пін
  3. третю на «плюс»
  4. другу та третю потрібно з'єднати резистором на ~ 4,7 К. Але я замінив резистор на світлодіод та отримав індикатор звернення до шини датчика (УВАГА! Без резистора чи світлодіода працювати нічого не буде. Не забудьте!)

За ідеєю, ось і все. Має працювати.
Працює, але бойові умови показали, що коли падає сонячне світлона датчик, той може нагріватися і показувати температуру набагато вище за реальну. Все правильно – він покаже температуру на сонці. А нам потрібна температура повітря.

Вперше для цього було зібрано корпус з-під банки від кави, обгорнутий у фольгу. Але це нічим не допомогло.

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

Робимо корпус для датчика
Відповідною за розміром виявилася банка від водоемульсійної фарби (такі ж бувають з-під клею ПВА, об'ємом 2-3 літри). У нижній частині банки робимо отвір під вентилятор. І прикріплюємо його до банку. У центрі банки розміщуємо майданчик під датчики, діаметром трохи меншим самої банки, щоб повітря могло циркулювати.
Декілька фото:

Як ви пам'ятаєте, резистор я замінив світлодіодом, тому робимо і для нього отвір, щоб завжди було видно роботу пристрою.

Кришка від банки нам не потрібна, замість неї потрібний навіс, такий, щоб і повітря пропускало, і щоб атмосферні опади не потрапляли всередину (датчик буде розташований на вулиці).

Корпус для Arduino я зробив із пластмасової коробки від mp3-плеєра Explay C360.

Backend, який приймає дані:
На стороні сервера працює скрипт, до якого звертається термометр. Скрипт перевіряє правильність секретного коду, щоб свідчення не можна було підмінити.
А потім додає новий записв таблицю MySql. Потім ці дані можна виводити як завгодно. При цьому щохвилини дані за минулу хвилину усереднюються і додаються до іншої таблиці.
Потрібно це для того, щоб:
1. простіше було робити вибірки в базі (не так, зручніше вказати конкретну хвилину і отримати результат)
2. вибірки були швидшими (за рік ~500 000 записів замість 10 000 000)

Під час тривалої роботиДатчика виявилася проблема, іноді він мимовільно (раз на 3-4 години) видає рандомне значення. Тому я додав перевірку на зміну температури більше ніж на 1 градус протягом 15 секунд. Такі значення ігноруються.

Недоліки:
Точність датчика 0.5*, що для мене недостатньо. Але є спосіб покращити його характеристики. Знадобиться ще один або більше датчиків (бажано з різних партій). Отримуємо дані з усіх датчиків та вважаємо середнє арифметичне. Так можна досягти точності до сотих градусів.
Плани на майбутнє:
  • датчик вологості
  • датчик тиску
  • датчик швидкості вітру
  • датчик освітленності
  • поставити кілька таких у місті та робити свої прогнози погоди
  • живити Arduino за Power over Ethernet
  • автоматизувати включення та частоту обертання вентилятора залежно від освітлення
  • віддалене управління
  • скидання даних у разі відсутності зв'язку (для мене це критично)
Відомі мені недоліки:
- висока ціна- 2180 руб. (Freeduino 2009 (800 р.) + Ethernet Shield v2 (1300 р.) + 1 датчик (80 р.))
- якщо вентилятор включити занадто швидко, він сам вносить похибку в температуру, обдуючи датчик. Він не повинен здувати, а лише проштовхувати повітря.

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

Що нам потрібно

  • комп'ютер із встановленою Arduino IDE(я використовую версію 1.6.5);
  • бібліотека VirtualWire (посилання нижче);
  • ATMega328P;
  • програматор AVR MKII ISP;
  • датчик температури та відносної вологості повітря DHT11;
  • компоненти із переліку елементів, наведеного нижче.

Вступ

У цій статті я покажу вам, як зібрати пристрій, який вимірює температуру та відносну вологість повітря та надсилає виміряні значення за допомогою стандартного радіочастотного модуля 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;
  • спосіб відображення температури та вологості → 16x2 LCD.

Принципові схеми

Передавач


Передавальна частина бездротового термометра на ATMega328p
()

У даному прикладія не виводитиму невикористані висновки мікроконтролера на зовнішні контактитермометра, після чого їх можна було б використовувати для подальшого вдосконалення пристрою. Тут ми розглядаємо лише ідею для пристрою та зберемо його лише на макетній платі.

Приймач



(для збільшення масштабу можна натиснути на картинку правою кнопкоюмиші та вибрати «Відкрити посилання/зображення у новій вкладці/новому вікні»)

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

Список елементів

Передавач


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

Приймач



(для збільшення масштабу можна натиснути на картинку правою кнопкою миші і вибрати «Відкрити посилання/зображення в новій вкладці/новому вікні»)

Програма

Програма передавача

Спочатку розглянемо програму передавальної частини:

#include // Визначення #define dhtPin 4 #define dhtType DHT11 #define txPowerPin 8 // Використання бібліотеки DHT DHT dht(dhtPin, dhtType); // Змінні char msg0; char msg1; 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 = (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; // Змінна для зберігання прийнятих даних uint8_t buflen = VW_MAX_MESSAGE_LEN; // Змінна для зберігання довжини прийнятих даних lcd.setCursor(0,0); lcd.print("Temp: " );if (vw_get_message(buf, &buflen)) // Якщо дані прийняті ( for (i=0;i<2;i++) // Получить два первых байта { Serial.write(buf[i]); // Для отладки lcd.write(buf[i]); // Вывести первые байты на LCD } Serial.println(); // Для отладки lcd.write(1); // Вывести символ градусов на LCD lcd.print(" C"); lcd.setCursor(0,1); lcd.print("Hum: "); for (i=2;i<4;i++) // Получаем последние два байта { Serial.write(buf[i]); // Отладка lcd.write(buf[i]); // Вывести последние байты на LCD } lcd.print("% RH"); } }

Цікавий спосіб використання бібліотеки LiquidCrystal - це створення символів користувача. За допомогою createChar я створив символ градусів. У такий же спосіб ви можете створити свої власні символи. Щоб створити символ користувача або значок, вам необхідно оголосити його, як масив з восьми байт, і «намалювати», які пікселі будуть включені (1 - включений, 0 - вимкнений).

При створенні різних технічних проектів часто виникає у облаштуванні температурних індикаторів. Ці компоненти дозволяють краще стежити за роботою пристроїв. У цьому огляді ми дізнаємося, як переробити аналоговий вольтметр на точний термометр. Для роботи нам знадобиться плата Arduino (спеціальна схема, оснащена своєю пам'яттю, процесором, а також парою десятків функціональних контактів) та датчик температури моделі DS18B20.

Характеристика температурного модуля DS18B20

Не можна не згадати про ще одну перевагу модулів DS18B20. Кожен датчик цього типу використовує для роботи унікальний послідовний 64-бітний код. Це означає, що всі подібні компоненти можуть функціонувати на одній шині типу 1 Wire, якою, як зазначалося вище, передається вся інформація. Таким чином, для керування кількома модулями знадобиться всього один мікропроцесор, причому самі температурні датчики можуть бути розкидані по солідній площі.

Деталі для роботи над термометром із DS18B20 на основі Arduino

Щоб зібрати якісний аналоговий термометр, потрібно підготувати:

  • електросхему типу Arduino (бажано нову);
  • температурний детектор моделі DS18B20;
  • аналоговий вольтметр;
  • 5 шнурів - два шнури знадобляться для створення ланцюга між платою Arduino та Вольтметром; 3 дроти потрібні для підключення до електросхеми температурного сенсора;
  • зовнішній акумулятор.

Створення електричного кола для термометра з DS18B20 на основі Arduino

Тут алгоритм роботи досить простий, тому з'єднати всі компоненти в єдиний ланцюг зможе навіть новачок. Для початку на модулі DS18B20 необхідно знайти негативний контакт (якщо дивитися на сенсор зверху, цей контакт буде зліва). Негативний штирок треба з'єднати з нижньою точкою заземлення на платі Arduino (вона позначатиметься абревіатурою GND). Штир із позитивним зарядом (правий) треба підключити до контакту живлення на 5 В (теж розташовується внизу плати). Далі робиться сигнальний висновок на цифровий контакт 2 (перебуває вгорі плати), щоб стало можливим вимірювання температури (у цьому випадку використовується центральний штирок сенсора).

Щоб під час роботи забезпечувалося управління вольтметром, потрібно з'єднати його позитивний контакт із цифровим виведенням під номером 9. Негативний контакт вольтметра підключається до верхньої точки заземлення плати (вона також позначається скороченням GND). Щоб змінити цифрову шкалу вольтметра, потрібно легко роздрукувати заздалегідь підготовлену картинку з градусами Цельсія. Ця картинка або приклеюється поверх старої шкали, або замість неї вставляється.

Опис широтно-імпульсної модуляції

Якщо коротко, широтно імпульсна модуляція є методом отримання аналогових результатів (таких, як температура) за допомогою цифрових засобів. Вона хороша тим, що навіть дуже високі чи дуже низькі значення передаються каналами зв'язку одним імпульсом. Весь процес широтно-імпульсної модуляції проходить так: датчик відправляє процесору сигнальний імпульс, а процесор вже проводить його обробку, після чого видає значення на термометр. Щоб мати можливість отримувати інформацію таким чином, необхідно використовувати спеціальні контактні штирі на платі Arduino. Розпізнати ці контакти дуже просто - поруч із ними є ось такий значок «~». До речі, цей значок є і біля контакту під номером 9, з яким ми з'єднуємо позитивний штир вольтметра. 9-й висновок був задіяний тільки як приклад; за бажання можна використовувати будь-який інший контакт, поруч із яким стоїть значок «~».

Прописування коду для роботи термометра з DS18B20 на основі Arduino

Насамперед, у програму розробки треба додати бібліотеку під назвою DallasTemperature. Варто віддавати перевагу саме їй, адже вона містить найвищі температурні значення (а це важливо під час використання модуля DS18B20).

Під час створення коду потрібно буде прописати три основні команди:

  1. Читання температурних значень, які від датчика.
  2. Перетворення температури методом широтно-імпульсної модуляції.
  3. Виведення значень на термометр.
Виходячи з цього, на початку налаштовується зчитування температури від датчика. Після цього налагоджується процес широтно-імпульсної модуляції. За наявності зазначеної бібліотеки користувач зможе отримувати значення в діапазоні від 0 до 255. Налаштування широтно-імпульсної модуляції здійснюється у програмі розробки (для цього передбачено пункт меню під назвою «map»). За допомогою коду встановлюється мінімальна та максимальна температура, яку враховуватиме термометр. Щоб забезпечити програмний зв'язок між вольтметром та платою Arduino, потрібно прописати 9-й цифровий контакт у конкретній частині коду (вище було зазначено, що саме до нього підключається сам вольтметр).

Слід враховувати, що мінімальний і максимальний поріг температури може бути різним (тут все залежить від переваг користувача). Однак необхідно пам'ятати одну деталь: чим більший розрив між нижньою та верхньою межею, тим меншими будуть цифри на шкалі.

Ось як виглядає весь код, необхідний налаштування роботи термометра.

Сьогодні ми розглянемо проект 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: «); );

Тепер перейдемо до логіки програми. Спочатку нам необхідно оголосити змінну long «A», щоб зберегти значення, зчитане з LM35, яке має діапазон від 0 до 1023. Потім оголошуємо іншу цілочисленну змінну «B» для зберігання відображеного (перетвореного) значення.

Значення температури зчитується з виводу A0 і зберігається у змінній "A". Потім змінна "A" перетворюється в діапазон від 0 до 500 і зберігається в змінній "B". Значення "B" виводиться безпосередньо на РК-екрані 16х2.