Подключение нескольких цифровых датчиков температуры DS18B20 к Arduino

Подключение нескольких цифровых датчиков температуры DS18B20 к Arduino

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

Эта функция очень полезна, когда вы хотите контролировать температуру в разных местах — например, в разных комнатах дома, секциях теплицы или на любой большой территории. И самое лучшее — всё это можно сделать с помощью одного провода данных!

В этом руководстве вы узнаете, как настроить и считывать температуру с нескольких датчиков DS18B20, подключённых к одному проводу.

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

Подключение нескольких цифровых датчиков температуры DS18B20 к Arduino

Теперь, когда вы готовы, давайте начнём подключение датчиков DS18B20 к нашему Arduino!

Схема подключения нескольких датчиков DS18B20 к Arduino

Подключение нескольких датчиков DS18B20 к вашему Arduino довольно простое.

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

Затем подключите провод VDD к выходу 5 В на Arduino, провод GND — к выводу заземления Arduino, а сигнальный провод — к цифровому выводу 2 на Arduino.

Для стабильной передачи данных вам нужно добавить подтягивающий резистор 4,7 кОм между сигнальной линией и линией питания. Обратите внимание — использование внутренних подтягивающих резисторов Arduino в данном случае не подойдёт, поэтому вам необходимо использовать настоящий физический резистор.

Вот краткая справочная таблица подключения выводов:

DS18B20ArduinoNotes
VDD5V
GNDGND
DQ2pulled up by 4.7kΩ
Подключение нескольких цифровых датчиков температуры DS18B20 к Arduino

Установка библиотеки

Протокол связи 1-Wire®, используемый датчиком DS18B20, довольно сложен, и написание всего кода для него с нуля заняло бы много времени. К счастью, существует специальная библиотека DallasTemperature, которая значительно упрощает задачу.

Для установки библиотеки:

  1. Сначала откройте вашу программу Arduino IDE. Затем нажмите на иконку Менеджер библиотек на левой боковой панели.

  2. Введите «ds18b20» в поле поиска для фильтрации результатов.

  3. Найдите библиотеку DallasTemperature от Miles Burton.

  4. Нажмите кнопку Install, чтобы добавить её в вашу Arduino IDE.

Подключение нескольких цифровых датчиков температуры DS18B20 к Arduino

Для правильной работы библиотеке DallasTemperature необходима другая библиотека — OneWire.

Для установки библиотеки OneWire:

  1. Снова откройте Менеджер библиотек.

  2. В поле поиска введите «onewire».

  3. Найдите библиотеку OneWire и нажмите Install.

Подключение нескольких цифровых датчиков температуры DS18B20 к Arduino

После установки обеих библиотек вы будете готовы начать работу с датчиками DS18B20!

Методы считывания нескольких датчиков DS18B20

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

  • Считывание по индексу — в этом методе библиотека автоматически присваивает каждому датчику номер индекса в порядке их обнаружения. Вы можете использовать эти номера индексов, чтобы запросить у Arduino считывание температуры с конкретного датчика. Этот метод полезен, когда вам не нужно точно знать, какой датчик является каким физически, а просто хотите прочитать все в порядке их обнаружения.

  • Считывание по адресу — каждый датчик DS18B20 имеет свой уникальный 64-битный адрес. В этом методе вы используете эти специальные адреса для прямой связи с каждым датчиком, поэтому вы всегда знаете, с какого именно датчика получаете температуру — независимо от его расположения на шине.

Давайте подробнее рассмотрим, как работает каждый метод.

Метод 1: Считывание датчиков DS18B20 по индексу

Когда мы используем библиотеку DallasTemperature с датчиками DS18B20, первое, что она делает — сканирует шину 1-Wire для поиска всех подключённых датчиков. Библиотека присваивает каждому датчику индекс, начиная с нуля. После присвоения индекса мы можем легко считать температуру с любого датчика, просто обратившись к его номеру индекса.

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

#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into digital pin 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire device
OneWire oneWire(ONE_WIRE_BUS);

// Pass oneWire reference to DallasTemperature library
DallasTemperature sensors(&oneWire);

int deviceCount = 0;
float tempC;

void setup(void) {
  sensors.begin();  // Start up the library
  Serial.begin(9600);

  // locate devices on the bus
  Serial.print("Locating devices...");
  Serial.print("Found ");
  deviceCount = sensors.getDeviceCount();
  Serial.print(deviceCount, DEC);
  Serial.println(" devices.");
  Serial.println("");
}

void loop(void) {
  // Send command to all the sensors for temperature conversion
  sensors.requestTemperatures();

  // Display temperature from each sensor
  for (int i = 0; i < deviceCount; i++) {
    Serial.print("Sensor ");
    Serial.print(i + 1);
    Serial.print(" : ");
    tempC = sensors.getTempCByIndex(i);
    Serial.print(tempC);
    Serial.print("°C  |  ");
    Serial.print(DallasTemperature::toFahrenheit(tempC));
    Serial.println("°F");
  }

  Serial.println("");
  delay(1000);
}

После загрузки скетча на ваш Arduino откройте монитор последовательного порта и установите скорость 9600 бод. Вы увидите текущую температуру от каждого датчика в градусах Цельсия (°C) и Фаренгейта (°F).

Подключение нескольких цифровых датчиков температуры DS18B20 к Arduino

Объяснение кода:

Скетч начинается с подключения двух важных библиотек: OneWire.h, которая обеспечивает связь с устройствами, использующими протокол 1-Wire, и DallasTemperature.h, которая упрощает работу с датчиками DS18B20 для получения показаний температуры.

#include <OneWire.h>
#include <DallasTemperature.h>

Далее мы указываем Arduino, к какому выводу подключены датчики — в данном случае это цифровой вывод 2.

#define ONE_WIRE_BUS 2

Для связи с датчиками нужно сделать две вещи. Сначала мы создаём объект OneWire и указываем, к какому выводу подключён датчик. Затем создаём объект DallasTemperature и передаём ему ссылку на только что созданный объект OneWire.

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

Мы также создаём две переменные: deviceCount хранит количество найденных на шине датчиков, а tempC хранит показания температуры от каждого датчика.

int deviceCount = 0;
float tempC;

В секции setup мы сначала вызываем функцию begin(), которая сканирует шину для поиска всех подключённых датчиков DS18B20. По мере обнаружения каждого датчика библиотека присваивает ему номер индекса.

sensors.begin();

Затем мы используем getDeviceCount(), чтобы узнать, сколько датчиков было обнаружено, и выводим это число в монитор последовательного порта.

Serial.print("Locating devices...");
Serial.print("Found ");
deviceCount = sensors.getDeviceCount();
Serial.print(deviceCount, DEC);
Serial.println(" devices.");

В секции loop() мы вызываем функцию sensors.requestTemperatures(). Эта команда сообщает всем датчикам на шине о необходимости выполнить преобразование температуры.

sensors.requestTemperatures();

Наконец, мы используем простой цикл for для последовательного перебора каждого датчика. Для каждого датчика мы получаем его температуру с помощью getTempCByIndex(index) и выводим температуру в градусах Цельсия и Фаренгейта.

for (int i = 0; i < deviceCount; i++) {
  Serial.print("Sensor ");
  Serial.print(i + 1);
  Serial.print(" : ");
  tempC = sensors.getTempCByIndex(i);
  Serial.print(tempC);
  Serial.print("°C  |  ");
  Serial.print(DallasTemperature::toFahrenheit(tempC));
  Serial.println("°F");
}

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

Метод 2: Считывание датчиков DS18B20 по адресу

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

В этом примере мы используем два скетча. Сначала мы используем один скетч для поиска и записи адреса каждого датчика. Затем, во втором скетче, мы используем эти адреса для индивидуального считывания температуры с каждого датчика.

Поиск адресов DS18B20 на шине

Первое, что нам нужно сделать — узнать адрес каждого датчика. Наш скетч будет искать все датчики DS18B20, подключённые к проводу данных, и выводить адрес каждого из них в монитор последовательного порта.

Рекомендуется подключать по одному датчику за раз при выполнении этого шага. Так вы сможете легко отслеживать, какой датчик имеет какой адрес, и даже присвоить каждому метку или имя.

#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// variable to hold device addresses
DeviceAddress Thermometer;

int deviceCount = 0;

void setup(void) {
  // start serial port
  Serial.begin(9600);

  // Start up the library
  sensors.begin();

  // locate devices on the bus
  Serial.println("Locating devices...");
  Serial.print("Found ");
  deviceCount = sensors.getDeviceCount();
  Serial.print(deviceCount, DEC);
  Serial.println(" devices.");
  Serial.println("");

  Serial.println("Printing addresses...");
  for (int i = 0; i < deviceCount; i++) {
    Serial.print("Sensor ");
    Serial.print(i + 1);
    Serial.print(" : ");
    sensors.getAddress(Thermometer, i);
    printAddress(Thermometer);
  }
}

void loop(void) {
}

void printAddress(DeviceAddress deviceAddress) {
  for (uint8_t i = 0; i < 8; i++) {
    Serial.print("0x");
    if (deviceAddress[i] < 0x10) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
    if (i < 7) Serial.print(", ");
  }
  Serial.println("");
}

После загрузки скетча на ваш Arduino откройте монитор последовательного порта. Вы увидите адрес каждого подключённого датчика.

Подключение нескольких цифровых датчиков температуры DS18B20 к Arduino

Примечание: Обязательно скопируйте эти адреса и сохраните их, так как они понадобятся для следующего скетча.

Объяснение кода:

Мы начинаем с подключения двух важных библиотек, необходимых для связи с датчиками DS18B20. Затем указываем, какой цифровой вывод Arduino подключён к проводу данных — в данном случае вывод 2. Мы также создаём специальную переменную для хранения адреса каждого найденного датчика.

В секции setup() кода мы запускаем последовательную связь, инициализируем библиотеку датчиков и просим её выполнить поиск подключённых датчиков. После их обнаружения библиотека подсчитывает их количество и выводит это число. Затем программа последовательно перебирает каждый датчик и отображает его уникальный адрес.

Функция printAddress() используется для форматирования адреса, чтобы он отображался в удобном виде в мониторе последовательного порта.

Считывание DS18B20 по адресу

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

#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Addresses of 3 DS18B20s
uint8_t sensor1[8] = { 0x28, 0xEE, 0xD5, 0x64, 0x1A, 0x16, 0x02, 0xEC };
uint8_t sensor2[8] = { 0x28, 0x61, 0x64, 0x12, 0x3C, 0x7C, 0x2F, 0x27 };
uint8_t sensor3[8] = { 0x28, 0x61, 0x64, 0x12, 0x3F, 0xFD, 0x80, 0xC6 };

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

void loop(void) {
  sensors.requestTemperatures();

  Serial.print("Sensor 1: ");
  printTemperature(sensor1);

  Serial.print("Sensor 2: ");
  printTemperature(sensor2);

  Serial.print("Sensor 3: ");
  printTemperature(sensor3);

  Serial.println();
  delay(1000);
}

void printTemperature(DeviceAddress deviceAddress) {
  float tempC = sensors.getTempC(deviceAddress);
  Serial.print(tempC);
  Serial.print("°C  |  ");
  Serial.print(DallasTemperature::toFahrenheit(tempC));
  Serial.println("°F");
}

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

Подключение нескольких цифровых датчиков температуры DS18B20 к Arduino

Объяснение кода:

Как и прежде, мы подключаем необходимые библиотеки, указываем, к какому выводу подключён провод данных, и создаём объект из библиотеки DallasTemperature.

#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

Далее мы вводим адреса датчиков в том же формате, который был отображён ранее. Эти адреса хранятся в специальных массивах — по одному на каждый датчик.

uint8_t sensor1[8] = { 0x28, 0xEE, 0xD5, 0x64, 0x1A, 0x16, 0x02, 0xEC };
uint8_t sensor2[8] = { 0x28, 0x61, 0x64, 0x12, 0x3C, 0x7C, 0x2F, 0x27 };
uint8_t sensor3[8] = { 0x28, 0x61, 0x64, 0x12, 0x3F, 0xFD, 0x80, 0xC6 };

В секции setup() мы вызываем функцию begin(), которая сканирует шину для поиска всех подключённых датчиков DS18B20.

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

В секции loop() мы даём всем датчикам команду выполнить преобразование температуры с помощью функции requestTemperatures(). Затем мы последовательно перебираем каждый датчик и используем пользовательскую функцию printTemperature(deviceAddress) для отображения температуры датчика, чей deviceAddress передаётся в качестве параметра.

void loop(void) {
  sensors.requestTemperatures();

  Serial.print("Sensor 1: ");
  printTemperature(sensor1);

  Serial.print("Sensor 2: ");
  printTemperature(sensor2);

  Serial.print("Sensor 3: ");
  printTemperature(sensor3);

  Serial.println();
  delay(1000);
}

Функция printTemperature() просто вызывает функцию getTempC(deviceAddress) для получения температуры от конкретного датчика по его адресу, а затем выводит температуру в градусах Цельсия и Фаренгейта.

void printTemperature(DeviceAddress deviceAddress) {
  float tempC = sensors.getTempC(deviceAddress);
  Serial.print(tempC);
  Serial.print("°C  |  ");
  Serial.print(DallasTemperature::toFahrenheit(tempC));
  Serial.println("°F");
}