Датчик температуры Arduino DS18B20. Arduino и цифровой датчик температуры DS18B20 Ds18b20 arduino подключение несколько датчиков

В предыдущих уроках мы уже работали с датчиком температуры и влажности 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); return; } ds.reset(); ds.select(addr); ds.write(0x44, 1); // команда на измерение температуры delay(1000); ds.reset(); ds.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 с Arduino UNO для создания термометра. Датчик DS18B20 является хорошим вариантом, когда в проекте с высокой точностью требуется хорошая реакция. Мы покажем как подключить DS18B20 к вашему и отобразить данные температуры на ЖК-дисплее 16x2.

Обзор датчика DS18B20

Датчик DS18B20 взаимодействует с Arduino через 1-проводную шину. По определению для связи с Arduino требуется только одна линия данных (и земля).

Каждый DS18B20 имеет уникальный 64-битный последовательный код или адрес, который позволяет нескольким DS18B20s работать на той же однопроводной шине. Поэтому использование микропроцессора упрощает управление несколькими DS18B20, распределенными по большой площади. Приложения для этой функции включают в себя экологический контроль, системы контроля температуры в зданиях и механическом оборудовании.

Особенности DS18B20

  • Необходим только один однопроводный интерфейс для связи между микроконтроллером и датчиком.
  • Требуется только один внешний компонент: резистор 4,7 кОм.
  • Может питаться от линии передачи данных напрямую, требуя напряжения от 3,0 до 5,5 В.
  • Каждое устройство имеет уникальный 64-битный последовательный код, хранящийся на встроенном ПЗУ.
  • Может измерять температуру в диапазоне от -55° C до + 125° C (от -67° F до + 257° F).
  • Точность ± 0,5° C в диапазоне от -10° C до + 85° C.

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

Требования к комплектующим

Требования к оборудованию для вашего термометра достаточно стандартные, нам пригодятся:

  • ЖК-дисплей 16х2
  • Датчик температуры DS18B20
  • Провода для перемычек
  • Резистор 1K
  • Макетная плата

Схема соединения

Сделайте соединения согласно приведенной ниже схеме.

Соединяем датчик и Ардуино

  • VCC -> Arduino 5V, плюс резистор 4,7K, идущий от VCC к Data
  • Data -> Пин 7 Arduino
  • GND -> GND Arduino

Соединения для ЖК-дисплея и Arduino UNO

  • Пин 1 -> GND
  • Пин 2 -> VCC
  • Пин 3 -> Arduino Пин 3
  • Пин 4 -> Arduino Пин 33
  • Пин 5 -> GND
  • Пин 6 -> Arduino Пин 31
  • Пин 7-10 -> GND
  • Пин 11 -> Arduino Пин 22
  • Пин 12 -> Arduino Пин 24
  • Пин 13 -> Arduino Пин 26
  • Пин 14 -> Arduino Пин 28
  • Пин 15 -> VCC через резистор 220 Ом
  • Пин 16 -> GND

Подключите потенциометр, как показано выше, к контакту 3 на ЖК-дисплее, для управления контрастностью.

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

Исходный код для термометра

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

  • Первая библиотека называется - OneWire ().
  • Вторая библиотека называется - DallasTemperature ().

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

//Code begins #include #include #include #define ONE_WIRE_BUS 7 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); float tempC = 0; float tempF = 0; LiquidCrystal lcd(12,11,5,4,3,2); void setup() { sensors.begin(); lcd.begin(16,2); lcd.clear(); pinMode(3, OUTPUT); analogWrite(3, 0); Serial.begin(9600); } void loop() { sensors.requestTemperatures(); tempC = sensors.getTempCByIndex(0); tempF = sensors.toFahrenheit(tempC); delay(1000); Serial.println(tempC); lcd.setCursor(0,0); lcd.print("C: "); lcd.print(tempC); lcd.print(" degrees"); lcd.setCursor(0,1); lcd.print("F: "); lcd.print(tempF); lcd.print(" degrees"); }

Примерно это выглядит так:

Мы смогли измерить температуру до 100°C с помощью этого датчика! Он очень отзывчив.

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

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");

Естественно и вывода температурных составляющих также по три.

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

Разрешите представить - цифровой датчик температуры буржуинской фирмы "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. То есть, она может принимать как положительные значения, так и отрицательные. Проверим работу нашего устройства на морозце:

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

Рассмотрим как при помощи 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 // // The DallasTemperature library can do 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 ="); for(i = 0; i < 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"); }