Датчик температуры DS18B20

Датчик температуры DS18B20+ позволяет определять температуру окружающего воздуха в диапазоне от −55…+125 °C и получать данные в виде цифрового сигнала с 12-битным разрешением по 1-Wire протоколу.

Используя 1-Wire протокол, для подключения целой армии датчиков к управляющей электронике можно обойтись всего 2 проводами: земли и сигнала. В этом случае применяется так называемое «паразитное питание», при котором датчик получает энергию прямо с линии сигнала. Каждый датчик имеет уникальный прошитый на производстве 64-битный код, который может использоваться микроконтроллером для общения с конкретным сенсором на общей шине. Код отдельного сенсора может быть считан отдельной командой. В постоянной памяти DS18B20 можно сохранить граничные значения температуры, при выходе из которых сенсор будет переходить в режим тревоги. На общей шине из многих сенсоров микроконтроллер может за раз узнать, какие из них перешли в этот режим. Таким образом становится легко определить проблемный участок в контролируемой среде.

Разрешение показаний настраивается и может составлять от 9 до 12 бит. Меньше разрешение — выше скорость преобразования. Благодаря своим возможностям, DS18B20 часто используется в системах «умного» дома, террариума и т.д. Вам достаточно всего двух проводов для организации комплексного контроля температуры в большом количестве точек.

Для подключения 1-Wire устройств к Arduino существует готовая библиотека, а для работы именно с DS18B20 существует библиотека-надстройка от Майлса Бёртона.

диапазон измеряемых температур: −55…+125 °C
точность: ±0,5°C (в пределах −10…+85 °C)
время получения данных: 750 мс при 12-битном разрешении; 94 мс при 9-битном разрешении
напряжение питания: 3–5,5 В
потребляемый ток при бездействии: 750 нА
потребляемый ток при опросе: 1 мА
#include <OneWire.h>
#include <DallasTemperature.h>
 
// Пин Arduino куда подключен датчик
#define ONE_WIRE_BUS 10
 
// Объявляем переменные
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
 
// тут будет хранится адрес нашего датчика. Каждый DS18B20 имеет свой уникальный адрес, зашитый на заводе
DeviceAddress insideThermometer;
 
void setup(void)
{
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");
 
  // Поиск устройств на выбранном пине
  Serial.print("Поиск устройств...");
  sensors.begin();
  Serial.print("Found ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" штук.");
 
  // определяемся с режимом питания датчиков. Они кстати могут питаться по тому же проводу, по которому отправляют данные
  Serial.print("Parasite power is: "); 
  if (sensors.isParasitePowerMode()) Serial.println("ON");
  else Serial.println("OFF");
 
  // тут можно прописать адрес вручную
  // Есть 2 варианта:
  // 1) oneWire.search(deviceAddress) – сразу если известен адрес датчика
  // 2) sensors.getAddress(deviceAddress, index) – по номеру подключения, начиная с 0
  //insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };
 
  // Мы будем использовать 2 вариант – поищем первый датчик (номер=0):
  if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Не найден адрес датчика 0");  
 
  // Показываем адрес, который нашли
  Serial.print("Адрес датчика 0: ");
  printAddress(insideThermometer);
  Serial.println();
 
  // устанавливаем разрешение датчика на 9 бит. Можно попробовать 10 поставить. Эта штука отвечает за точность показаний. Чем выше точность тем меньше скорость получения температуры.
  sensors.setResolution(insideThermometer, 9);
 
  Serial.print("Разрешение датчика 0: ");
  Serial.print(sensors.getResolution(insideThermometer), DEC); 
  Serial.println();
}
 
// Эта волшебная функция пишет температуру в Serial
void printTemperature(DeviceAddress deviceAddress)
{
  // вариант 1 - медленнее
  //Serial.print("Temp C: ");
  //Serial.print(sensors.getTempC(deviceAddress)); // в цельсиях
  //Serial.print(" Temp F: ");
  //Serial.print(sensors.getTempF(deviceAddress)); // в фаренгейтах. причем чтобы получить температуру в фаренгейтах мы делаем второй запрос к датчику.
 
  // вариант 2 - быстрее
  float tempC = sensors.getTempC(deviceAddress);
  Serial.print("Temp C: ");
  Serial.print(tempC);
  Serial.print(" Temp F: ");
  Serial.println(DallasTemperature::toFahrenheit(tempC)); // чтобы получить фаренгейты в этот раз мы не делаем второй запрос к DS18B20, а просто конвертим температуру по формуле.
}
 
void loop(void)
{ 
  Serial.print("Получаем температуру...");
  sensors.requestTemperatures(); // Отправка команды на получение температуры
  Serial.println("готово");
 
  // ну и теперь вывод данных
  printTemperature(insideThermometer);
}
 
// А эта функция выводит адрес в Serial
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}