В этом проекте мы рассмотрим подключение нескольких датчиков температуры DS18B20 к плате Arduino и отобразим значения температуры всех датчиков в градусах Цельсия или Фаренгейта. Для подключения нескольких подобных датчиков температуры требуется только один цифровой контакт Arduino. Мы можем подключить максимум 1024 датчика с использованием протокола I2C. Но здесь мы рассмотрим подключение 3 датчиков температуры DS18B20 к Arduino.
Датчик температуры DS18B20 — это цифровой датчик температуры, работающий по протоколу 1-Wire. Он поставляется в герметичном корпусе, позволяет точно измерять температуру во влажных средах с помощью простого интерфейса 1-Wire, который использует общую шину для подключения нескольких устройств. Это означает, что можно подключать несколько устройств и считывать их значения, используя всего один цифровой контакт платы Arduino.
Ранее на нашем сайте мы рассматривали подключение одного датчика температуры DS18B20 к Arduino, также мы рассматривали его подключение к другим микроконтроллерам и платам:
- к плате Raspberry Pi;
- к плате Raspberry Pi Pico;
- к плате STM32F103C8 (Blue Pill);
- к модулю ESP8266;
- к микроконтроллеру PIC.
Необходимые компоненты
- Плата Arduino Uno (купить на AliExpress).
- Несколько цифровых датчиков температуры DS18B20 (купить на AliExpress).
- ЖК дисплей 16х2 (купить на AliExpress).
- Резистор 4,7 кОм.
- Макетная плата.
- Соединительные провода.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Водонепроницаемый цифровой датчик температуры DS18B20
Это предварительно подключенная и водонепроницаемая версия датчика DS18B20. Удобно, когда вам нужно измерить что-то на большом расстоянии или во влажных условиях. Датчик может измерять температуру в диапазоне от -55 до 125 °C (от -67 °F до +257 °F). Кабель покрыт оболочкой из ПВХ.
Поскольку он цифровой, нет никакого ухудшения сигнала даже на больших расстояниях. Эти 1-проводные цифровые датчики температуры довольно точны, т. е. ±0,5°C в большей части диапазона. Он может выдавать до 12 бит точности от встроенного цифро-аналогового преобразователя. Они отлично работают с любым микроконтроллером, использующим один цифровой вывод.
Единственный недостаток в том, что они используют протокол Dallas 1-Wire, который довольно сложен и требует кучу кода для разбора коммуникации (но для большинства современных микроконтроллерных плат эту проблему успешно решают соответствующие библиотеки). Мы добавляем резистор 4,7 кОм, который требуется в качестве подтягивающего от линии DATA к линии VCC при использовании датчика.
Схема проекта
Схема подключения нескольких датчиков температуры DS18B20 к плате Arduino представлена на следующем рисунке.
Подключите контакты 11,12, 5, 4, 3, 2 Arduino к контактам 4, 6, 11, 12, 13, 14 ЖК-дисплея.
Подключите вывод VDD DS18B20 к 5 В, а вывод GND к заземлению. Подключите вывод данных всех DS18B20 к цифровому выводу 9 Arduino, а также к резистору 4,7 кОм (подключите другой конец резистора 4,7 кОм к 5 В), как показано на приведенном рисунке.
Собранная на макетной плате конструкция проекта представлена на следующем рисунке.
Исходный код программы
Для сопряжения нескольких датчиков температуры DS18B20 с платой Arduino вам понадобятся две разные библиотеки:
1. Загрузите библиотеку 1 Wire
2. Загрузите библиотеку Dallas Temperature
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
#include <LiquidCrystal.h> LiquidCrystal lcd(11, 12, 5, 4, 3, 2); #include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 9 // Data wire is plugged into port 9 on the Arduino #define precision 12 // OneWire precision Dallas Sensor int sen_number = 0; // Counter of Dallas sensors OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature. DeviceAddress T1, T2, T3, T4, T5, T6, T7, T8; // arrays to hold device addresses void setup(void) { lcd.begin(16,2); Serial.begin(9600); //Start serial port Serial.println("Dallas Temperature IC Control Library"); // Start up the library sensors.begin(); // locate devices on the bus Serial.print("Found: "); Serial.print(sensors.getDeviceCount(), DEC); Serial.println(" Devices."); // report parasite power requirements Serial.print("Parasite power is: "); if (sensors.isParasitePowerMode()) Serial.println("ON"); else Serial.println("OFF"); // Search for devices on the bus and assign based on an index. if (!sensors.getAddress(T1, 0)) Serial.println("Not Found Sensor 1"); if (!sensors.getAddress(T2, 1)) Serial.println("Not Found Sensor 2"); if (!sensors.getAddress(T3, 2)) Serial.println("Not Found Sensor 3"); if (!sensors.getAddress(T4, 3)) Serial.println("Not Found Sensor 4"); if (!sensors.getAddress(T5, 4)) Serial.println("Not Found Sensor 5"); if (!sensors.getAddress(T6, 5)) Serial.println("Not Found Sensor 6"); if (!sensors.getAddress(T7, 6)) Serial.println("Not Found Sensor 7"); if (!sensors.getAddress(T8, 7)) Serial.println("Not Found Sensor 8"); // show the addresses we found on the bus for (int k =0; k < sensors.getDeviceCount(); k++) { Serial.print("Sensor "); Serial.print(k+1); Serial.print(" Address: "); if (k == 0) { printAddress(T1); Serial.println(); } else if (k == 1) { printAddress(T2); Serial.println(); } else if (k == 2) { printAddress(T3); Serial.println(); } else if (k == 3) { printAddress(T4); Serial.println(); } else if (k == 4) { printAddress(T5); Serial.println(); } else if (k == 5) { printAddress(T6); Serial.println(); } else if (k == 6) { printAddress(T7); Serial.println(); } else if (k == 7) { printAddress(T8); Serial.println(); } } // set the resolution to 12 bit per device sensors.setResolution(T1, precision); sensors.setResolution(T2, precision); sensors.setResolution(T3, precision); sensors.setResolution(T4, precision); sensors.setResolution(T5, precision); sensors.setResolution(T6, precision); sensors.setResolution(T7, precision); sensors.setResolution(T8, precision); for (int k =0; k < sensors.getDeviceCount(); k++) { Serial.print("Sensor "); Serial.print(k+1); Serial.print(" Resolution: "); if (k == 0) { Serial.print(sensors.getResolution(T1), DEC); Serial.println(); } else if (k == 1) { Serial.print(sensors.getResolution(T2), DEC); Serial.println(); } else if (k == 2) { Serial.print(sensors.getResolution(T3), DEC); Serial.println(); } else if (k == 3) { Serial.print(sensors.getResolution(T4), DEC); Serial.println(); } else if (k == 4) { Serial.print(sensors.getResolution(T5), DEC); Serial.println(); } else if (k == 5) { Serial.print(sensors.getResolution(T6), DEC); Serial.println(); } else if (k == 6) { Serial.print(sensors.getResolution(T7), DEC); Serial.println(); } else if (k == 7) { Serial.print(sensors.getResolution(T8), DEC); Serial.println(); } } } // function to print a device address void printAddress(DeviceAddress deviceAddress) { for (uint8_t i = 0; i < 8; i++) { // zero pad the address if necessary if (deviceAddress[i] < 16) Serial.print("0"); Serial.print(deviceAddress[i], HEX); } } // function to print the temperature for a device void printTemperature(DeviceAddress deviceAddress) { float tempC = sensors.getTempC(deviceAddress); Serial.print("Temp : "); Serial.print(tempC); Serial.print(" Celcius degres "); // Serial.print(" Temp F: "); // Serial.print(DallasTemperature::toFahrenheit(tempC)); } // function to print a device's resolution void printResolution(DeviceAddress deviceAddress) { } void printData(DeviceAddress deviceAddress) { Serial.print("Device Address: "); printAddress(deviceAddress); Serial.print(" "); printTemperature(deviceAddress); Serial.println(); } void loop(void) { // call sensors.requestTemperatures() to issue a global temperature request to all devices on the bus Serial.print("Reading DATA..."); sensors.requestTemperatures(); Serial.println("DONE"); // print the device information for (int k =0; k < sensors.getDeviceCount(); k++) { Serial.print("Sensor "); Serial.print(k+1); Serial.print(" "); if (k == 0) { printData(T1); } else if (k == 1) { printData(T2); } else if (k == 2) { printData(T3); } else if (k == 3) { printData(T4); } else if (k == 4) { printData(T5); } else if (k == 5) { printData(T6); } else if (k == 6) { printData(T7); } else if (k == 7) { printData(T8); } } if (sen_number == sensors.getDeviceCount()) { sen_number = 0; // reset counter // lcd.clear(); // clear screen on LCD } lcd.setCursor(0,0); lcd.print("Sensor Number "); lcd.print(sen_number+1); lcd.setCursor(0,1); lcd.print(" Temp: "); if (sen_number == 0) { lcd.print(sensors.getTempC(T1)); lcd.write((char)223); lcd.print("C "); } else if (sen_number == 1) { lcd.print(sensors.getTempC(T2)); lcd.write((char)223); lcd.print("C "); } else if (sen_number == 2) { lcd.print(sensors.getTempC(T3)); lcd.write((char)223); lcd.print("C "); } else if (sen_number == 3) { lcd.print(sensors.getTempC(T4)); lcd.write((char)223); lcd.print("C "); } else if (sen_number == 4) { lcd.print(sensors.getTempC(T5)); lcd.write((char)223); lcd.print("C "); } else if (sen_number == 5) { lcd.print(sensors.getTempC(T6)); lcd.write((char)223); lcd.print("C "); } else if (sen_number == 6) { lcd.print(sensors.getTempC(T7)); lcd.write((char)223); lcd.print("C "); } else if (sen_number == 7) { lcd.print(sensors.getTempC(T8)); lcd.write((char)223); lcd.print("C "); } Serial.print("Sensor Number="); Serial.println(sen_number); delay(2000); sen_number++ ; } |
Принцип работы нескольких датчиков температуры DS18B20 с Arduino
DS18B20 обеспечивает показания температуры в формате от 9 до 12 бит (настраивается), которые указывают температуру устройства. Он взаимодействует по шине 1-Wire, которая по определению требует только одну линию данных (и заземление) для связи с центральным микропроцессором. Кроме того, он может получать питание непосредственно от линии данных («паразитное питание»), устраняя необходимость во внешнем источнике питания.
Основная функциональность DS18B20 — это датчик температуры с прямым цифровым преобразованием. Разрешение датчика температуры настраивается пользователем на 9, 10, 11 или 12 бит, что соответствует шагу 0,5°C, 0,25°C, 0,125°C и 0,0625°C соответственно. Разрешение по умолчанию при включении питания составляет 12 бит.
Каждый DS18B20 имеет определенный адрес устройства в формате HEX, например {0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 }. Таким образом, программа разработана на основе считывания температуры с определенного адреса устройства. Поэтому сначала Arduino сканирует количество датчиков. Предположим, что здесь подключено 3 датчика. Таким образом, он просто отобразит значения 3 различных показаний. Если подключено больше датчиков, показания переключатся на несколько значений. Значение температуры, считываемое каждым датчиком, отображается с интервалом в 2 секунды как Sensor Number 1 Temperature (температура датчика номер 1), Sensor Number 2 Temperature (температура датчика номер 2) и до значения номера подключенного датчика.