Подключение DS18B20 к ESP32/ESP8266

DS18B20 удобный цифровой термосенсор. В промышленной эксплуатации обычно используются датчики в водонепроницаемой капсуле из нержавеющей стали. Характеристики датчиков:

  • Диапазон измеряемых температур -55 ° ~ +125 °.
  • Напряжение питания 3.0V ~ 5.5V
  • Низкая стоимость (~1,3 USD)
  • Однопроводной интерфейс 1Wire.
  • Точность ±0.5°C в диапазоне от -10°C до +85°C.
  • Программируемое разрешение от 9 Bits до 12 Bits.
  • Уникальный 64 битный серийный номер у каждого датчика исключающий конфликты на одной шине.
  • Можно напрямую подключать к микроконтроллерам без дополнительных конвертеров.
Распиновка DS18B20
Распиновка DS18B20

Выходы у датчика в нержавейке : Red (VCC), yellow (DATA), black (GND)

Схема подключения крайне простая. Датчик подключается к цифровому входу через резистор 4,7 К на +питания.

Я приобретал датчики в металлических водонепроницаемых капсулах оптом, 10 шт. у этого продавца на Aliexpress. Цена ~1,3 USD за шт. с оперативной доставкой в Россию. Если время доставки не критично, то датчик можно заказать по цене порядка 1 USD у множества продавцов на Aliexpress с бесплатной доставкой.

Получение адресов датчиков DS18B20

#include <OneWire.h>

OneWire ds(15);  //data wire connected to GPIO15

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

void loop(void) {
  byte i;
  byte addr[8];
  
  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);
  }
}

Опрос датчиков DS18B20

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

// Data wire is connected to GPIO15
#define ONE_WIRE_BUS 15
// Setup a oneWire instance to communicate with a OneWire device
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature sensor 
DallasTemperature sensors(&oneWire);

DeviceAddress sensor1 = { 0x28, 0xB1, 0x13, 0x46, 0x92, 0xD, 0x2, 0xA7 };

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

void loop(void)
{ 
  //Serial.print("Requesting temperatures...");
  sensors.requestTemperatures(); // Send the command to get temperatures
  //Serial.println("DONE");
  
  Serial.print("Sensor 1: ");
  Serial.print(String(sensors.getTempC(sensor1)) + " C, "); 
  Serial.println(String(sensors.getTempF(sensor1)) + " F"); 

  //  tempSensor.requestTemperaturesByIndex(0);
  //Get single sensor value
  Serial.print("Temperature: ");
  Serial.print(sensors.getTempCByIndex(0));
  Serial.print(" C, ");
  Serial.print(sensors.getTempFByIndex(0));
  Serial.println(" F");
  delay(1000);
}

Если на одной шине висит несколько сенсоров, код будет несколько посложнее. В данном случае тестируется два DS18B20 датчиков подключенных к GPIO32 микроконтроллера ESP32.

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

#define OneWire_PIN 32

OneWire ds(OneWire_PIN);

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

// count of DS18xxx Family devices on bus
uint8_t devices = 0; // Reset the number of devices when we enumerate wire devices
uint8_t ds18Count = 0; // Reset number of DS18xxx Family devices

void setup()
{
  sensors.begin();

  ScanOneWireDevicesAndShowTemp();

  // выведем общее количество найденных устройств
  Serial.println("Found [" + String(ds18Count) + "] DS18XXX sensors of [" + String(devices) + "] iWare devices.");
  //Serial.print(sensors.getDeviceCount(), DEC);
  //Serial.print(sensors.getDS18Count(), DEC);

  // проверяем способ подключения питания
  Serial.print("Parasite power is: ");
  Serial.println(sensors.isParasitePowerMode() ? "ON" : "OFF");
}

void loop()
{
  ScanOneWireDevicesAndShowTemp();
  delay(1000);
}

String getSensorModel(uint8_t modelByte)
{
  //deviceAddress[0]
  String res = "";
  switch (modelByte) 
  {
    case DS18S20MODEL:
      return "DS18S20";
    case DS18B20MODEL:
      return "DS18B20";
    case DS1822MODEL:
      return "DS1822";
    case DS1825MODEL:
      return "DS1825";
    case DS28EA00MODEL:
      return "DS28EA00";
    default:
      return "Unknown";
  }
}

void ScanOneWireDevicesAndShowTemp()
{
    DeviceAddress deviceAddress;
  
    while (ds.search(deviceAddress)) 
    {
      if (sensors.validAddress(deviceAddress)) 
      {
        //bitResolution = max(bitResolution, sensors.getResolution(deviceAddress));
        devices++;
        if (sensors.validFamily(deviceAddress)) 
        {
          sensors.requestTemperatures(); // Send the command to get temperatures
          Serial.print("Sensor ");
          printAddress(deviceAddress);
          Serial.println(". Temp: " + String(sensors.getTempC(deviceAddress)) + " oC with resolution " + String(sensors.getResolution(deviceAddress)) + " bit. Sensor " + getSensorModel(deviceAddress[0]) + "."); 
          ds18Count++;
        }
      }
    }
}

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

Результат работы кода опроса датчиков DS18B20:

11:42:18.863 -> Sensor 28B11346920D02A7. Temp: 24.19 oC with resolution 12 bit. Sensor DS18B20.
11:42:18.999 -> Sensor 28FF6C7997090341. Temp: 28.12 oC with resolution 12 bit. Sensor DS18B20.
11:42:20.022 -> Found [2] DS18XXX sensors of [2] iWare devices.
11:42:20.022 -> Parasite power is: OFF

Разброс показаний датчиков DS18B20

Не смотря на то, что датчики цифровые — они не калиброванные. Для примера снятие данных с 12 датчиков DS18B20 в течении 8 часов.

Разброс показаний датчиков DS18B20
Разброс показаний датчиков DS18B20

Как видно по графикам, разброс в показаниях составляет почти 2 градуса. Я не нашел в командах DS18B20 вариантов прописать калибровочные коэффициенты непосредственно в датчик, так что придется поправлять значения «снаружи».

Полезные ссылки

Spread the love
Запись опубликована в рубрике IT рецепты с метками , , , . Добавьте в закладки постоянную ссылку.

Добавить комментарий