Взаимодействие ds18b20, однопроводного (1-wire) цифрового датчика температуры, с arduino

Взаимодействие ds18b20, однопроводного (1-wire) цифрового датчика температуры, с arduino

Взаимодействие ds18b20, однопроводного (1-wire) цифрового датчика температуры, с arduino
СОДЕРЖАНИЕ
0
405 просмотров
01 января 2021

С чем мы имеем дело?

Определения понятия «подделка» разнятся, но согласно документу AIR6273 подделка представляет собой умышленное несанкционированное копирование, имитацию, замену или модификацию подлинного предмета от авторизованного производителя . Начиная с 2019 года основной проблемой являются копии (клоны), имеющие определенную маркировку,  чтобы ввести в заблуждение ничего не подозревающего покупателя. К счастью, клоны DS18B20 почти легко идентифицировать: маркировка на чипе напечатана, а не нанесена лазером? Нет отметки на заднем отступе? Вероятно, подделка. Содержимое памяти (регистра «блокнота», Scratchpad) не соответствует спецификации? Вероятно, подделка. Систематически ведет себя не так, как подлинный датчик? Вероятно, подделка.

Примеры работы для Arduino

Один датчик

Рассмотрим простой пример — подключения одного датчика.

Сенсор подключается к управляющей плате через один сигнальный пин.
При подключении к Arduino в компактном формфакторе, например Arduino Micro или Iskra Nano Pro, воспользуйтесь макетной платой и парочкой нажимных клеммников.

Между сигнальным проводом и питанием установите сопротивление 4,7 кОм.


При коммуникации сенсора со стандартными платами Arduino формата Rev3, Arduino Uno или Iskra Neo, используйте Troyka Slot Shield совместно с модулем подтяжки.

Код программы

Выведем температуру сенсора в Serial-порт.

simple.ino
// библиотека для работы с протоколом 1-Wire
#include <OneWire.h>
// библиотека для работы с датчиком DS18B20
#include <DallasTemperature.h>
 
// сигнальный провод датчика
#define ONE_WIRE_BUS 5
 
// создаём объект для работы с библиотекой OneWire
OneWire oneWire(ONE_WIRE_BUS);
 
// создадим объект для работы с библиотекой DallasTemperature
DallasTemperature sensor(&oneWire);
 
void setup(){
  // инициализируем работу Serial-порта
  Serial.begin(9600);
  // начинаем работу с датчиком
  sensor.begin();
  // устанавливаем разрешение датчика от 9 до 12 бит
  sensor.setResolution(12);
}
 
void loop(){
  // переменная для хранения температуры
  float temperature;
  // отправляем запрос на измерение температуры
  sensor.requestTemperatures();
  // считываем данные из регистра датчика
  temperature = sensor.getTempCByIndex();
  // выводим температуру в Serial-порт
  Serial.print("Temp C: ");
  Serial.println(temperature);
  // ждём одну секунду
  delay(1000);
}

Серия датчиков

Каждый сенсор DS18B20 хранит в своей памяти уникальный номер, такое решение позволяет подключить несколько датчиков к одному пину.

Добавим к предыдущем схемам подключения ещё по паре датчиков в параллель.

Код программы

Просканируем все устройства на шине и выведем температуру каждого сенсора отдельно в Serial-порт.

multipleSensors.ino
// библиотека для работы с протоколом 1-Wire
#include <OneWire.h>
// библиотека для работы с датчиком DS18B20
#include <DallasTemperature.h>
 
// сигнальный провод датчика
#define ONE_WIRE_BUS 5
 
// создаём объект для работы с библиотекой OneWire
OneWire oneWire(ONE_WIRE_BUS);
// создадим объект для работы с библиотекой DallasTemperature
DallasTemperature sensors(&oneWire);
// создаём указатель массив для хранения адресов датчиков
DeviceAddress *sensorsUnique;
// количество датчиков на шине
int countSensors;
 
// функция вывода адреса датчика
void printAddress(DeviceAddress deviceAddress){
  for (uint8_t i = ; i < 8; i++){
    if (deviceAddressi < 16) Serial.print("0");
    Serial.print(deviceAddressi, HEX);
  }
}
 
void setup(){
  // инициализируем работу Serial-порта
  Serial.begin(9600);
  // ожидаем открытия Serial-порта
  while(!Serial);
  // начинаем работу с датчиком
  sensors.begin();
  // выполняем поиск устройств на шине
  countSensors = sensors.getDeviceCount();
  Serial.print("Found sensors: ");
  Serial.println(countSensors);
  // выделяем память в динамическом массиве под количество обнаруженных сенсоров
  sensorsUnique = new DeviceAddresscountSensors;
 
  // определяем в каком режиме питания подключены сенсоры
  if (sensors.isParasitePowerMode()) {
    Serial.println("Mode power is Parasite");
  } else {
    Serial.println("Mode power is Normal");
  }
 
  // делаем запрос на получение адресов датчиков
  for (int i = ; i < countSensors; i++) {
    sensors.getAddress(sensorsUniquei, i);
  }
  // выводим полученные адреса
  for (int i = ; i < countSensors; i++) {
    Serial.print("Device ");
    Serial.print(i);
    Serial.print(" Address: ");
    printAddress(sensorsUniquei);
    Serial.println();
  }
  Serial.println();
  // устанавливаем разрешение всех датчиков в 12 бит
  for (int i = ; i < countSensors; i++) {
    sensors.setResolution(sensorsUniquei, 12);
  }
}
 
void loop(){
  // переменная для хранения температуры
  float temperature10;
  // отправляем запрос на измерение температуры всех сенсоров
  sensors.requestTemperatures();
  // считываем данные из регистра каждого датчика по очереди
  for (int i = ; i < countSensors; i++) {
    temperaturei = sensors.getTempCByIndex(i);
  }
  // выводим температуру в Serial-порт по каждому датчику
  for (int i = ; i < countSensors; i++) {
    Serial.print("Device ");
    Serial.print(i);
    Serial.print(" Temp C: ");
    Serial.print(temperaturei);
    Serial.println();
  }
  Serial.println();
  // ждём одну секунду
  delay(1000);
}

DS18B20 – однопроводной датчик температуры

DS18B20 – это датчик температуры с однопроводным интерфейсом 1-Wire, изготовленный Dallas Semiconductor Corp. Уникальный интерфейс 1-Wire требует только одного цифрового контакта для двухсторонней связи с микроконтроллером.

Датчик обычно поставляется в двух форм-факторах. Тот, что идет в корпусе TO-92, выглядит точно так же, как обычный транзистор. Другой, в виде водонепроницаемого зонда, может быть более полезен, когда вам нужно измерить что-то далеко, под водой или под землей.

Рисунок 1 – Типы датчиков температуры DS18B20

Датчик температуры DS18B20 достаточно точный и не требует для работы внешних компонентов. Он может измерять температуру от -55°C до +125°C с точностью ±0,5°C.

Разрешение датчика температуры настраивается пользователем до 9, 10, 11 или 12 бит. Однако разрешение по умолчанию при включении питания составляет 12 бит (то есть соответствует точности 0,0625°C).

Датчик может питаться от источника напряжения от 3 В до 5,5 В и потреблять всего 1 мА во время активных преобразований температуры.

Вот полная спецификация:

Характеристики датчика температуры DS18B20
Напряжение питания от 3 В до 5,5 В
Потребляемый ток 1мА
Диапазон температур от -55°C до 125°C
Точность ±0,5°С
Разрешение от 9 до 12 бит (выбирается)
Время преобразования <750 мс

Скетч для Arduino и сенсора DS18B20

Установливаем библиотеку OneWire Library

После того как вы скачали архив с библиотекой, ее надо импортировать. Для этого в Arduino IDE выберите пункт “Sketch” – “Import Library” – “Add Library” и выберите архив, который вы скачали. Если у вас возникли проблемы, с установкой библиотеки, ознакомьтесь с инструкцией по установке библиотек в Arduino.

Загружаем скетч на Arduino

Скетч, который представлен ниже, есть в библиотеке OneWire, в категории examples. Перейдите в “File” – “Examples” – “OneWire” и выберите пример “DS18x20_Temperature”. Код программы представлен ниже.

Данный пример использует библиотеку OneWire Library, для того, чтобы собрать данные со всех подключенных датчиков температуры DS28B20 (как подключить несколько сенсоров описано в конце статьи) и отобразить их в окне серийного монитора Arduino IDE.

В окне серийного монитора вы увидите примерно следующее:

ROM = 28 88 84 82 5 0 0 6A

Chip = DS18B20

Data = 1 56 1 4B 46 7F FF A 10 D1 CRC=D1

Temperature = 21.37 Celsius, 70.47 Fahrenheit

No more addresses.

ROM = 28 88 84 82 5 0 0 6A

Chip = DS18B20

Data = 1 56 1 4B 46 7F FF A 10 D1 CRC=D1

Temperature = 21.37 Celsius, 70.47 Fahrenheit

No more addresses.

ROM = 28 88 84 82 5 0 0 6A

Chip = DS18B20

Data = 1 56 1 4B 46 7F FF A 10 D1 CRC=D1

Temperature = 21.37 Celsius, 70.47 Fahrenheit

No more addresses.

Обычное или паразитное питание?

DS18B20 может работать в обычном или в так называемом “паразитном” режиме. В обычном режиме для подключения используется 3 коннектора, в “паразитном” режиме – в его лишь 2.

Вам надо настроить правильный режим в скетче, чтобы снять достоверные показания с датчика:

  • Для “паразитного” режима в строке 65 надо указать: ds.write(0x44, 1);
  • Для обычного режима в строке 65 указывается: ds.write(0x44);

Убедитесь, что вы указали корректные пины!

В строке 10, где указано “OneWire ds(2);” устанавливается пин, к которому подключен контакт data с сенсора.

В этом примере использован пин 2, но значения пина по умолчанию в примере OneWire стоит на 10. Можно использовать и его.

#include &ltOneWire.h&gt

// пример использования библиотеки OneWire DS18S20, DS18B20, DS1822

OneWire ds(2); // на пине 10 (нужен резистор 4.7 КОм)

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

Serial.write(‘ ‘);

Serial.print(addr, HEX);

}

if (OneWire::crc8(addr, 7) != addr) {

Serial.println(“CRC is not valid!”);

return;

}

Serial.println();

// первый байт определяет чип

switch (addr) {

case 0x10:

Serial.println(” Chip = DS18S20″); // или более старый 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); // начинаем преобразование, используя ds.write(0x44,1) с “паразитным” питанием

delay(1000); // 750 может быть достаточно, а может быть и не хватит

// мы могли бы использовать тут ds.depower(), но reset позаботится об этом

present = ds.reset();

ds.select(addr);

ds.write(0xBE);

Serial.print(” Data = “);

Serial.print(present, HEX);

Serial.print(” “);

for ( i = 0; i

data = ds.read();

Serial.print(data, HEX);

Serial.print(” “);

}

Serial.print(” CRC=”);

Serial.print(OneWire::crc8(data, 8), HEX);

Serial.println();

// конвертируем данный в фактическую температуру

// так как результат является 16 битным целым, его надо хранить в

// переменной с типом данных “int16_t”, которая всегда равна 16 битам,

// даже если мы проводим компиляцию на 32-х битном процессоре

int16_t raw = (data

if (type_s) {

raw = raw

if (data == 0x10) {

raw = (raw & 0xFFF0) + 12 – data;

}

} else {

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 мс

//// разрешение по умолчанию равно 12 бит, время преобразования – 750 мс

}

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

}

На что они похожи?

На Рисунке 1 приведен пример подлинного датчика DS18B20 производства Maxim в корпусе TO-92.

Рисунок 1. Пример маркировки оригинальных датчиков DS18B20 на корпусе TO-92.

На момент написания статьи (2019) маркировка оригинальных  микросхем Maxim наносилась лазером, а не печаталась.

  • Первые две строки, DALLAS 18B20, указывают, что это датчик DS18B20 (Dallas Semiconductor является первоначальным производителем), датчики только с паразитным питанием маркируются DALLAS 18B20P.
  • Знак «+» в четвертой строке означает, что компонент соответствует требованиям RoHS.
  • 3-я строка указывает год выпуска и номер недели в году (в данном случае это 32 неделя 2019 года).
  • Последние два символа в строке 3 указывают ревизию кристалла (на данный момент С4).
  • В строке 4 трехзначное число, за которым следуют два символа, является формой кода партии, которая позволяет Maxim отследить историю производства.
  • В микросхемах, выпущенных в 2016 году или позже, встречалась только комбинация символов AB и AC .

Маркировка внутри отступа на задней части:

  • Маркировка P (Филиппины?). На всех последних микросхемах (2016 и моложе) и на большинстве микросхем, выпуск которых уходит, как минимум, в 2009 год.
  • Маркировка THAI <буква> (Таиланд?), где <буква> – это одна из I, J, K, L, M, N, O, S, T, U, V, W, X, и, возможно, других, по крайней мере, на некоторых микросхемах произведенных в 2011 году . Шрифт <буквы>  отличается от шрифта символов, составляющих слово THAI.

Из того, что было автором замечено на корпусе TO-92, только для микросхем с маркировкой P в отступе на задней части один код партии соответствует коду даты производства. Это не относится к микросхемам с маркировкой THAI в отступе.

↑ Общение с датчиком

  • 0x33h – считать ромкод (уникальное имя каждого устройства). Применение возможно только, если на шине всего одно устройство.
  • 0x55h – обратиться по ром коду к конкретному устройству. После необходимо также передать 64 битный ром код. Только устройство у которого переданный код совпадет с записанным в него на заводе останется на шине, остальные отключатся.
  • 0xCCh — После приема данной команды все устройства останутся активными на шине. Удобно использовать если устройство одно или есть однотипные.
  • 0x44h – Запуск преобразования температуры. Если датчик питает не от линии данных, то после можно прочитать состояние шины 0 – если преобразование не завершено и 1 – если преобразование завершено.
  • 0xBEh – Считать 8 байт данных. Первые два байта – вычисленная температура.
  • 0x4Eh – запись в память датчика. Необходимо передать три байта – верхнюю границу термостата, нижнюю границу термостата и значение контрольного регистра.
  • 0x1Fh — 9 бит (±0,5 градуса Цельсия), преобразование примерно 94 миллисекунды;
  • 0x3Fh — 10 бит (±0,25 градуса Цельсия), преобразование примерно 188 миллисекунд;
  • 0x5Fh — 11 бит (±0,125 градуса Цельсия), преобразование примерно 375 миллисекунд;
  • 0x7Fh — 12 бит (±0,0625 градуса Цельсия), преобразование примерно 750 миллисекунд;

Настройка датчика:

термостатСчитываем температуру.Исключён фрагмент. Полный вариант статьи доступен меценатам и полноправным членам сообщества. Читай условия доступа.

Функция выдачи ром кода на шину:

Другие полезные функции в библиотеке DallasTemperature.h

Есть еще несколько полезных функций, которые вы можете использовать с объектом . Несколько из них перечислены ниже:

  • Функция устанавливает разрешение внутреннего аналого-цифрового преобразователя DS18B20 на значение 9, 10, 11 или 12 бит, что соответствует шагу температуры 0,5°C, 0,25°C, 0,125°C и 0,0625°C соответственно ,
  • Функция возвращает значение флага . Это может быть полезно, когда вы хотите проверить, завершено ли преобразование температуры.
  • Функции и устанавливают внутренние пороги тревоги высокой и низкой температуры для устройства в градусах Цельсия. Допустимый диапазон от -55°C до +125°C
  • Функция возвращает , если устройство имеет состояние тревоги, когда температура выходит за пределы диапазона между верхним и нижним уровнями тревоги.

Подключение DS18B20 к Arduino

Датчик подключается элементарно.

Контакт GND с DS18B20 подключается к GND на Arduino.

Контакт Vdd с DS18B20 подключается к +5V на Arduino.

Контакт Data с DS18B20 подключается к любому цифровому пину на Arduino. В данном примере используется пин 2.

Единственное, что необходимо добавить из внешней дополнительной обвязки – это подтягивающий резистор на 4.7 КОм.

Схема подключения DS18B20 к Arduino показана ниже (в скетче, который будет приведен ниже, проверьте строки 10 и 65. В них указаны пины, к которым вы подключали контакт сигнала с датчика и режим питания!):

На рисунке ниже приведена фотография нашей простой схемы “в жизни”.

Паразитное и обычное питание

Есть альтернативный вариант подключения – так называемое “паразитное” подключение. В этом случае мы не будем подключать пин +5V к пину Vdd на датчике DS18B20. Вместо этого мы подключим контакт Vdd с датчика DS18B20 к GND. Преимущества такого подключения очевидны: нам понадобится всего два коннектора!

Недостатком такого подключения является ограничение количества одновременно подключаемых сенсоров. Кабели для подключения должны быть максимально короткими!

В общем, с “паразитным” подключением надо быть аккуратнее и лучше его все-таки не использовать. Результаты (значения температур) могут оказаться самыми неожиданными.

Подключение датчика температуры DS18B20 к Arduino

Достаточно теории, давайте практиковаться! Давайте подключим DS18B20 к Arduino.

Подключение довольно простое. Начните с подключения VDD к 5V выходу на Arduino, и GND – к земле.

Затем подключите оставшийся цифровой сигнальный вывод DQ к цифровому выводу 2 на Arduino. Вам также необходимо добавить подтягивающий резистор 4,7 кОм между сигнальным выводом и выводом питания, чтобы обеспечить стабильную передачу данных (внутренние подтягивающие резисторы на ардуино не работают).

Будьте осторожны, чтобы правильно подключить DS18B20. Если вы сделаете это неправильно, он нагреется, а затем выйдет из строя.

Рисунок 3 – Подключение датчика температуры DS18B20 к Arduino

Если вы используете водонепроницаемую версию DS18B20, подключите красный провод к 5V, черный провод соединится с землей, а желтый провод – данные, которые поступают на цифровой вывод 2 на Arduino. Вам всё еще нужно подключить подтягивающий резистор 4,7 кОм между линией данных и шиной 5 В.

Рисунок 4 – Подключение водонепроницаемого датчика температуры DS18B20 к Arduino

Как подключить несколько сенсоров DS18B20 к Arduino?

Вы можете подключить несколько цифровых датчиков температуры DS18B20 параллельно. При этом библиотека OneWire library позволит вам считывать данные со всех датчиков одновременно.

Ниже описаны два метода подключения сенсоров.

Для большого количества сенсоров (больше 10), надо использовать резисторы с меньшим сопротивлением (например, 1.6 КОм или даже меньше).

Кроме того, если вы подключаете параллельно более 10 датчиков, могут возникнуть проблемы (погрешности при съеме показаний). Поэтому рекомендуется устанавливать дополнительный резистор сопротивлением 100…120 Ом между контактом data на Arduino и data на каждом сенсоре!

Результат работы предыдущего скетча с двумя подключенными сенсорами может выглядет примерно следующим образом:

ROM = 28 88 84 82 5 0 0 6A

Chip = DS18B20

Data = 1 51 1 4B 46 7F FF F 10 FE CRC=FE

Temperature = 21.06 Celsius, 69.91 Fahrenheit

ROM = 28 DA CA 27 5 0 0 49

Chip = DS18B20

Data = 1 4E 1 4B 46 7F FF 2 10 D9 CRC=D9

Temperature = 20.87 Celsius, 69.57 Fahrenheit

No more addresses.

Выбираем правильный сенсор

Было бы неплохо знать, с какого именно сенсора вы получаете данные, когда вы используете параллельно несколько датчиков. Как это сделать?

Серийный номер

Так как датчики цифровые, у каждого из них есть индивидуальный серийный номер, который можно использовать для опознавания того или иного сенсора. Вроде бы все просто. Но… нам ведь надо предварительно определить эти серийные номера, прежде чем использовать их для опознавания сенсора, правильно?

Вы могли обратить на примерах выше, что скетч выдает нам данные в виде 64-битного серийного номера – значение “ROM”. Например:

28 88 84 82 5 0 0 6A или 28 DA CA 27 5 0 0 49 в примере выше.

Не забывайте, если вы используете одновременно большое количество датчиков (10 и больше), надо добавить резисторы 100 … 120 Ом между контактами data с сенсора DS18B20 и пином data на Arduino (для каждого датчика!).

Ниже показана схема параллельного подключения нескольких сенсоров с использованием трех контактов.

Паразитный режим питания

В “паразитном” режиме контакт Vdd остается фактически не задействован. Питание датчика осуществляется через контакт data.

Оставляйте Ваши комментарии, вопросы и делитесь личным опытом ниже. В дискуссии часто рождаются новые идеи и проекты!

Выводы

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

За дополнительные возможности приходится платить относительной сложностью работы с датчиком. Для подключения DS18B20 нам обязательно понадобится резистор с номиналом около 5К. Для работы с датчиком в скетчах ардуино нужно установить дополнительную библиотеку и получить определенные навыки для работы с ней – там все не совсем тривиально. Впрочем, можно купить уже готовый модуль, а для скетча в большинстве случаев хватит простых примеров, приведенных в этой статье.

Комментировать
0
405 просмотров
Это интересно

Русские никогда не жили в избах Занимательные факты
197 комментариев