Датчик температуры DS18B20,Arduino и библиотека OneWire.

Так исторически сложилось, что на текущий момент одним из самых популярных  цифровых температурных датчиков является датчик DS18B20 корпорации Dallas Semiconductor. Конечно  же и мы не можем обойти его стороной.

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

Особенности датчика :

  • Простой  интерфейс подключения 1-Wire .
  • Наличие уникального 64-битного адреса датчика, для использование систем с большим числом датчиков.
  • Напряжение питания от  3 V до 5.5 V .
  • Точность  в ±0,5 С,  для диапазона -10…+85 С . Для диапазона -55… +125  точность ± 2 С.
  • Возможность паразитного питания (Parasite power).

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

Вся память  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);

Запись байта. Передает байт в устройство на шине.

  • v – байт;
  • power – признак выбора режима питания;
    power = 0 – питание от внешнего источника.
    power = 1 – “паразитное” питание.

Отправим команду 0x44 инициализации измерения температуры.

Пауза 1 сек. Ожидание на время, необходимое для выполнения датчиком преобразования температуры. Это время зависит от выбранной разрешающей способности датчика.  Разрешение 12 бит установлено в датчике по умолчанию. Время преобразования для него – 750 мс.

Затем мы отправляем команду ResetSkip ROM ( 0xCC ) , а замет команду 0xBE чтения памяти датчика.  

uint8_t.read_bytes(buf, 9) —  Чтение 9 ти байтов данных.

uint8_t.read();  Или читаем по байтно. 
Основные команды библиотеке OneWire :
  • search(addressArray) – ищет температурный датчик, при нахождении в массив addressArray записывается его код, в ином случае – false.
  • reset_search() – производится поиск на первом приборе.
  • reset() – выполнение сброса шины перед тем, как связаться с устройством.
  • select(addressArray) – выбирается устройство после операции сброса, записывается его ROM код.
  • write(byte) – производится запись байта информации на устройство.
  • write(byte, 1) – аналогично write(byte), но в режиме паразитного питания.
  • read() – чтение байта информации с устройства.
  • crc8(dataArray, length) – вычисление CRC кода. dataArray – выбранный массив, length – длина кода.

Вот и сам код из библиотеке :

#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); //  датчик на выводе 10 (а резистор 4.7 K является необходимым)

void setup(void) {
 Serial.begin(9600);
 }

void loop(void) {
 byte i;
 byte present = 0; //переменные
 byte type_s;
 byte data[12];
 byte addr[8];
 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[7]) {
 Serial.println("CRC недопустимый!");
 return;
 }
 Serial.println();

// первый байт ROM указывает, какой чип  (8 бит код чипа,  48 бит серийный номер , 8 бит CRC )
 switch (addr[0]) {
 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[1] << 8) | data[0];
 if (type_s) {
 raw = raw << 3; // 9 бит разрешение по умолчанию у датчиков DS18S20 or old DS1820
 if (data[7] == 0x10) {
 // "количество остается" дает полное разрешение 12 бит
 raw = (raw & 0xFFF0) + 12 - data[6];
 }
 } else {
 byte cfg = (data[4] & 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) подключение не чем не отключаются. Ну а некоторые различия можно уже узнать из datesheet к ним.