Підключення ds18b20 до arduino. Ось так виглядає ця "супер-складна" схема DS18B20 підключення до Arduino

Розглянемо як за допомоги Arduinoчитати показання з цифрового датчика температури DS18B20 або DS18S20. У заразм/с DS18B20 фірми Dallas є найбільш поширеним та доступним цифровим датчикомтемператури. Працює за протоколом. Даташит датчика:

Схема підключення датчика DS18B20 до Arduino наведена нижче. Підтягуючий Pull-Up резистор номіналом 4.7 кОм (5 кОм) включається між виведенням DQ (Data) та живленням датчика Vdd.

Робочий скетч представлений нижче. Необхідна бібліотека OneWire, останню версіюякої можна завантажити.

Після встановлення бібліотеки, в меню з'явиться робочий приклад, яким можна скористатися.

#include "OneWire.h" // OneWire DS18S20, DS18B20, DS1822 Temperature Example // // http://www.pjrc.com/teensy/td_libs_OneWire.html // // DallasTemperature library can all this work for you ! // http://milesburton.com/Dallas_Temperature_Control_Library OneWire ds(10); // on pin 10 (a 4.7K resistor is necessary) void setup(void) ( Serial.begin(9600); ) void loop(void) ( byte i; byte present = 0; byte type_s; byte data; byte addr; float celsius, fahrenheit; if (!ds.search(addr)) ( Serial.println("No more addresses."); Serial.println(); ds.reset_search(); delay(250); return; ) Serial. print("ROM =");< 8; i++) { Serial.write(" "); Serial.print(addr[i], HEX); } if (OneWire::crc8(addr, 7) != addr) { Serial.println("CRC is not valid!"); return; } Serial.println(); // the first ROM byte indicates which chip switch (addr) { case 0x10: Serial.println(" Chip = DS18S20"); // or old DS1820 type_s = 1; break; case 0x28: Serial.println(" Chip = DS18B20"); type_s = 0; break; case 0x22: Serial.println(" Chip = DS1822"); type_s = 0; break; default: Serial.println("Device is not a DS18x20 family device."); return; } ds.reset(); ds.select(addr); ds.write(0x44, 1); // start conversion, with parasite power on at the end delay(1000); // maybe 750ms is enough, maybe not // we might do a ds.depower() here, but the reset will take care of it. present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad Serial.print(" Data = "); Serial.print(present, HEX); Serial.print(" "); for (i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); Serial.print(data[i], HEX); Serial.print(" "); } Serial.print(" CRC="); Serial.print(OneWire::crc8(data, 8), HEX); Serial.println(); // Convert the data to actual temperature // because the result is a 16 bit signed integer, it should // be stored to an "int16_t" type, which is always 16 bits // even when compiled on a 32 bit processor. int16_t raw = (data << 8) | data; if (type_s) { raw = raw << 3; // 9 bit resolution default if (data == 0x10) { // "count remain" gives full 12 bit resolution raw = (raw & 0xFFF0) + 12 - data; } } else { byte cfg = (data & 0x60); // at lower res, the low bits are undefined, so let"s zero them if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms //// default is 12 bit resolution, 750 ms conversion time } celsius = (float)raw / 16.0; fahrenheit = celsius * 1.8 + 32.0; Serial.print(" Temperature = "); Serial.print(celsius); Serial.print(" Celsius, "); Serial.print(fahrenheit); Serial.println(" Fahrenheit"); }

Час переходити до чогось кориснішого в господарстві. Ну, наприклад, зробити цифровий термометр, чи що. Тим більше, що з Ардуїно - це зовсім не так складно, як було у "доконтролерну епоху". У ті часи електронний термометр був складною конструкцією з десятка мікросхем, аналогового датчика, який потрібно було ще відкалібрувати, і трансформаторного блоку живлення на кілька вихідних напруг. Ну і - відповідної підготовки радіоаматора, який задумає все це зібрати. Зараз із цим – все набагато простіше.

Дозвольте уявити цифровий датчик температури буржуїнської фірми "Dallas semiconductor" DS18B20.

Повністю функціональний пристрій для точного (до декількох знаків після коми) вимірювання температури в діапазоні від -55 до +120 градусів за Цельсієм. Крім того - є навіть трохи "мозків" (осередків пам'яті) для запам'ятовування чогось корисного. Але поки що ми ними не користуватимемося. Як видно на малюнку – випускається у кількох варіаціях. Найпоширеніша і для нас зручна – та, де написано "ТО-92".

Датчик має лише 3 висновки, на два з яких подається напруга живлення 5в, а середній висновок – для передачі даних. Все керування датчиком (подача на нього команд, зчитування виміряної температури) йде по єдиному провіднику, тому вся ця технологія та протокол приймання-передачі називається "1-Wire" або "One-Wire".

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

Кожен сеанс передачі чи прийому даних починається з команди ініціалізації. Знову ж таки не вдаватимемося в подробиці спілкування Ардуїни з термометром, за нас це зробили сторонні люди (подумки скажемо їм спасибі). Просто передамо їй одну команду – "ініціалізація", і вона сама розбереться, що треба зробити.

Далі, після ініціалізації, починаємо подавати керуючі команди. Тут слід зазначити, що на одному керуючому проводку, теоретично, може бути кілька пристроїв сімейства "1-Wire". Причому не лише датчики температури. Тому є можливість звертатися до кожного з них за унікальним серійним номером. Але оскільки у нас на дроті єдиний датчик, то ні до чого іншого ми не можемо звернутися в принципі. Тому ці прелюдії пропускаються командою (байтом "0хСС", що передається). Забув сказати - тут і далі використовується шістнадцятковий запис двійкових чисел (байтів).

Після того, як визначилися з адресатом – передаємо команду "виміряти температуру" ("0х44"). Після цього потрібно залишити датчик у спокої приблизно на 1 секунду, поки він робитиме свої справи.

За цей час "ds-ка" виміряє температуру і запише результати в два байти, які нам потрібно у неї вивудити і привести до людського вигляду. Починаємо, як завжди, з ініціалізації сеансу зв'язку. Потім знову передаємо команду "скидання передачі адреси" ("0хСС"). І відразу слідом - повідомляємо, що готові прийняти результат вимірювання: ("0хВЕ").

Після цього Ардуїна отримує послідовно 2 байти (або двобайтне число – кому як подобається) з результатами. Подивимося, що це за результати і як нам привести їх до зручного вигляду.

Знову ж таки, щоб не сильно завантажуватися, визначимося з тим, що для нас важливо. А саме – у молодшому і, частково, у старшому байті знаходиться результат вимірювання температури з точністю до 4-го знака після коми (нам така точність – зайва). Знак температури ("+" або "-") визначається значенням старшого біта старшого байта.

Але, досить слів - настав час зайнятися конструюванням. Схема підключення DS18B20 до Ардуїни не тільки проста – а елементарно проста:

Виводи живлення датчика підключені до відповідних висновків Ардуїни, а вихід даних - до цифрового виходу "10". Крім того, виведення даних підключений до шини +5 вольт через резистор 3 - 5 кілоом (так званий "резистор, що підтягує"). Зауважте, що цифровий вихід "10", хоча він працюватиме і на вихід, і на вхід, нам уже не доведеться налаштовувати, як у попередньому прикладі зі світлодіодами. Розробники бібліотеки "1-Wire" дбайливо звільнили нас від будь-якої чорнової роботи. Дякую їм за це!

Загалом, у мене вийшло, приблизно, так:

Так! Зовсім забув! Бібліотека "1-Wire" не входить до базового постачання Arduino IDE, тому її потрібно завантажити, наприклад, звідси. Розпакуємо архів і покладемо папку з бібліотекою в директорію \libraries, що знаходиться в папці, де встановлена ​​Arduino IDE. При наступному запуску середовища розробки бібліотека буде доступна для використання. Ось де її можна знайти:

Однак, не будемо використовувати скетч з "Зразків", там дуже наворочено. Краще скопіюємо в Arduino IDE такий скетч:

#include

OneWire ds(10); //

void setup(void) (
Serial.begin(9600); //налаштовуємо послідовний порт для виведення результатів
}

void loop() (
byte data; // Оголошуємо масив з 2-х байт
ds.reset(); // ініціалізуємо датчик
ds.write(0xCC); // Пропускаємо адресацію до конкретного датчика (у нас він один)
ds.write(0x44); // даємо команду вимірювати температуру
delay(1000); // Чекаємо 1 секунду, доки вимірюється температура

ds.reset(); // знову ініціалізуємо датчик
ds.write(0xCC); // знову пропускаємо адресацію
ds.write(0xBE); // даємо команду готовності зчитувати температуру
data = ds.read(); //зчитуємо молодший
data = ds.read(); // та старший байти
int Temp = (data<< 8) + data; // преобразуем считанную информацию
Temp = Temp >> 4; // До потрібного вигляду.
Serial.println(Temp); // Виводимо результат у послідовний порт.

Що тут бачимо... Спочатку до скетчу підключається бібліотека "OneWire". Вказуємо, що наш датчик підключений до виведення "10" Ардуїни.Потім налаштовується послідовний порт для виведення результатів виміру. Усі, підготовчі операції закінчено, починаємо вимірювати. Готуємо (резервуємо та називаємо) 2 байти, куди записуватимемо результат вимірювання температури. Потім - подаємо команди, як описувалося вище і, нарешті, отримуємо 2 байти з нашою температурою. Потім відбувається перетворення ліченої інформації та видалення зайвих знаків після коми для того, щоб отримати ціле значення температури, без десяткових дробів. Ця інформація виводиться через послідовний порт. Де ми можемо побачити її? А ось тут:

Отже, завантажуємо цей скетч в Ардуїну, відкриваємо "Монітор послідовного порту" та спостерігаємо кожну секунду виміряну температуру:

Ура! Запрацювало! Не будемо вдаватися до подробиць процес перетворення отриманих від датчика 2-х байт на цілу кількість температури, це тема для окремої великої статті. Скажу тільки, що отримане число – змінна Temp типу integer. Тобто вона може набувати як позитивних значень, так і негативних. Перевіримо роботу нашого пристрою на морозці:

Ну що ж, показує і негативні температури. Навіть одразу зі знаком. Надалі, коли ми виводитимемо температуру на різні індикатори, треба буде запам'ятати цю особливість нашої програми. І передбачити додатково індикацію символу плюсової температури. Але про те – вже у наступних статтях.

У попередніх уроках ми вже працювали з датчиком температури та вологості DHT11, а також із терморезистором. На цей раз спробуємо розібратися ще з одним популярним датчиком, що вимірює температуру - DS18B20. Цей пристрій дозволяє вимірювати температуру від –55°C до +125°C з точністю ±0.5°C (при температурі від –10°C до +85°C). Харчуватись DS18B20 може як від 3.3, так і від 5 Вольт. Сам по собі датчик це мікросхема, яка може зустрічатися в різних корпусах: Також популярними є готові модулі, на яких розміщений датчик, резистор підтяжки і роз'єм.
Інший варіант - датчик у герметичній сталевій капсулі з проводом:

1. Підключення модуля DS18B20-ROC до Ардуїно

У цьому уроці ми будемо працювати з модулем датчика температури, розробленим у RobotClass. Підключати ми його будемо до контролера Ардуїно Уно. Як і DHT11 датчик DS18B20 використовує однопровідну шину (1-wire) для обміну даними з контролером. Так що нам знадобиться всього три дроти щоб підключити датчик до Ардуїно. Принципова схема Зовнішній вигляд макету
Примітка.У разі використання не модуля, а окремої мікросхеми необхідно виведення мікросхеми OUT з'єднати з контактом живлення через резистор 4,7 КОм. У зазначеному вище модулі цей резистор вже встановлено.

2. Програма для отримання даних із датчика DS18B20

Напишемо програму, яка кожну секунду зчитуватиме показання температури з датчика і виводитиме їх у COM-порт. #include OneWire ds(2); void setup() ( Serial.begin(9600); ) void loop() ( byte i; byte data; byte addr; float celsius; // пошук адреси датчика if (!ds.search(addr)) ( ds.reset_search( );delay(250); ds.reset(); .select(addr); ds.write(0xBE); // команда початку читання виміряної температури // зчитуємо показання температури з внутрішньої пам'яті датчика for (i = 0; i< 9; i++) { data[i] = ds.read(); } int16_t raw = (data << 8) | data; // датчик может быть настроен на разную точность, выясняем её byte cfg = (data & 0x60); if (cfg == 0x00) raw = raw & ~7; // точность 9-разрядов, 93,75 мс else if (cfg == 0x20) raw = raw & ~3; // точность 10-разрядов, 187,5 мс else if (cfg == 0x40) raw = raw & ~1; // точность 11-разрядов, 375 мс // преобразование показаний датчика в градусы Цельсия celsius = (float)raw / 16.0; Serial.print("t="); Serial.println(celsius); } Процедура на первый взгляд может показать совершенно непонятной. На самом деле, все эти 0xBE, 0x44 и т.п. взяты из спецификации к датчику. Для удобства мы можем всю процедуру вычисления выделить в отдельную функцию или даже в отдельный модуль. Загружаем программу на Ардуино и запускаем монитор COM-порта. В окне терминала мы должны увидеть данные о температуре, обновляющиеся раз в секунду: t=23.15 t=23.47 t=23.32 Вот и всё, датчик работает!

Висновок

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

Так історично склалося, що на даний момент одним із найпопулярніших цифрових температурних датчиків є датчик DS18B20 корпорації Dallas Semiconductor. Звичайно ж, і ми не можемо обійти його стороною.

Вся пам'ять DS18B20 включає оперативну (SRAM) і енергонезалежну (EEPROM) пам'ять. У EEPROM зберігаються регістри TH, TL та регістр конфігурації. Якщо функція тривожного сигналу не використовується, регістри TH і TL можуть використовуватися як регістри загального призначення. У режимі термостата TH містить значення верхнього порогу температури, TL відповідно нижнього порога.

Кодінг.

Насамперед нам знадобиться бібліотека OneWire, яка нам дуже спростить життя. Завантажити можна з GitHub або з нашого сайту.

Будь-яке спілкування з датчиком починається з команди Reset. Тобто МК притискає шину даних у стан логічний "0" на 480 µs, потім відпускає її. Датчик відповідає це сигналом присутності, після чого ми відправляємо команду Skip ROM (0xCC) . Тобто звернемося до всіх датчика які присутні на шині.

OneWire(uint8_t pin);

Конструктор, Pin– номер виводу, до якого підключено датчик.

uint8_t reset(void);

Ініціалізація операції на шині. З цієї команди має починатися будь-яка операція обміну даними. Повертає:

  • 1 – якщо пристрій підключено до шини (був у відповідь імпульс присутності);
  • 0 – якщо пристрій відсутній на шині (імпульсу у відповідь не було).
void write(uint8_t v, uint8_t power = 0);

Запис байт. Передає байт пристрій на шині.

Відправимо команду 0x44ініціалізації вимірювання температури.

Пауза 1 сек.Очікування на час, необхідне виконання датчиком перетворення температури. Цей час залежить від обраної роздільної здатності датчика. Роздільна здатність 12 біт встановлено в датчику за замовчуванням. Час перетворення йому – 750 мс.

Потім ми відправляємо команду Reset, Skip ROM (0xCC) , а поміт команду 0xBE читання пам'яті датчика.

Ось і сам код із бібліотеки:

#include // OneWire DS18S20, DS18B20, DS1822 Temperature Example // // http://www.pjrc.com/teensy/td_libs_OneWire.html // // DallasTemperature library може зробити все це для вас! // http://milesburton.com/Dallas_Temperature_Control_Library OneWire ds(10); // датчик на виводі 10 (а резистор 4.7 K є необхідним) void setup(void) ( Serial.begin(9600); ) void loop(void) ( byte i; byte present = 0; // змінні byte type_s; byte data ; byte addr; float celsius, fahrenheit; if (!ds.search(addr)) ( Serial.println("No more addresses."); ; ) Serial.print("ROM =");< 8; i++) { Serial.write(" "); Serial.print(addr[i], HEX); } if (OneWire::crc8(addr, 7) != addr) { Serial.println("CRC недопустимый!"); return; } Serial.println(); // первый байт ROM указывает, какой чип (8 бит код чипа, 48 бит серийный номер, 8 бит CRC) switch (addr) { case 0x10: Serial.println(" Chip = DS18S20"); // or old DS1820 type_s = 1; break; case 0x28: Serial.println(" Chip = DS18B20"); type_s = 0; break; case 0x22: Serial.println(" Chip = DS1822"); type_s = 0; break; default: Serial.println("Не является устройством семейства DS18x20."); return; } ds.reset(); ds.select(addr); ds.write(0x44, 0); // старт преобразования с питание от внешнего источника. delay(1000); // ждем конца преобразования. // we might do a ds.depower() here, but the reset will take care of it. present = ds.reset(); ds.select(addr); ds.write(0xBE); // Читаем память. Serial.print(" Data = "); Serial.print(present, HEX); Serial.print(" "); for (i = 0; i < 9; i++) { // нам нужно 9 байт data[i] = ds.read(); Serial.print(data[i], HEX); Serial.print(" "); } Serial.print(" CRC="); Serial.print(OneWire::crc8(data, 8), HEX); Serial.println(); // Преобразование данных в фактическую температуру //поскольку результатом является 16-разрядное целое число со знаком // ранится в типе "int16_t", который всегда составляет 16 бит // даже при компиляции на 32-битном процессоре. int16_t raw = (data << 8) | data; if (type_s) { raw = raw << 3; // 9 бит разрешение по умолчанию у датчиков DS18S20 or old DS1820 if (data == 0x10) { // "количество остается" дает полное разрешение 12 бит raw = (raw & 0xFFF0) + 12 - data; } } else { byte cfg = (data & 0x60); // при более низком разрешении низкие биты не определены, поэтому давайте обнуляем их. if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms //// default is 12 bit resolution, 750 ms conversion time } celsius = (float)raw / 16.0; fahrenheit = celsius * 1.8 + 32.0; Serial.print(" Temperature = "); Serial.print(celsius); Serial.print(" Celsius, "); Serial.print(fahrenheit); Serial.println(" Fahrenheit"); }

Власне це бібліотека підходить для всіх датчиків сімейства. DS18(DS18B20, DS18S20, DS1820, DS1822) підключення не чим не відключаються. Ну а деякі відмінності можна вже дізнатися з даних,що до них.

DS18B20 підключення до Arduino— це фантастичний датчик визначення температурної складової з цифровим інтерфейсом у своєму складі — отже, він не вимагає виконання калібрування. Тому такі пристрої можна підключити одночасно в множині до одного контакту arduino. Таку можливість надає оригінальна адреса, яка була запрограмована у схему DS18B20 при його виготовленні.

Ось так виглядає ця "супер-складна" схема DS18B20 підключення до Arduino:

Тут потрібен лише один резистор і більше нічого))). До того ж тут немає потреби в калібруванні температури, а також виключаються можливі неточності при виконанні складання. Напругу живлення можна подавати в діапазоні від 3v до 5v. Все просто. А відображення температурного значення – три рядки)). Нижче показаний зразок, все досконало та чітко розписано.

Ось звідси потрібно завантажити бібліотеку:

Тут все аналогічно, код у зразку Multiple.pde. Різниця лише в тому, що застосовано деяку кількість змінних величин термометрів, що мають адреси — отже на три датчики три змінні величини зі своєю адресою і аналогічний код для пошуку:

If (!sensors.getAddress(Thermometer1, 0)) Serial.println("Не знайдено адресу датчика 0"); if (!sensors.getAddress(Thermometer2, 1)) Serial.println("Не знайдено адресу датчика 1"); if (!sensors.getAddress(Thermometer3, 2)) Serial.println("Не знайдено адресу датчика 2");

Природно і виведення температурних складових також три.