MicroPython: Датчик температуры DS18B20 с ESP32 и ESP8266

В этом руководстве показано, как использовать датчик температуры DS18B20 с ESP32 и ESP8266 с использованием прошивки MicroPython. Вы узнаете, как считывать температуру с одного датчика DS18B20 и с нескольких датчиков одновременно. Вы также создадите веб-сервер для отображения показаний датчика.

MicroPython DS18B20 датчик температуры с ESP32 и ESP8266 (один датчик, несколько датчиков и пример веб-сервера)

Вас также могут заинтересовать другие руководства по DS18B20:

Предварительные требования

Для выполнения этого руководства вам нужна прошивка MicroPython, установленная на вашу плату ESP32 или ESP8266. Вам также понадобится IDE для написания и загрузки кода на плату. Мы рекомендуем использовать Thonny IDE или uPyCraft IDE:

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

DS18B20 — это цифровой датчик температуры с интерфейсом one-wire. Это означает, что для обмена данными с вашим ESP32 или ESP8266 ему требуется только одна линия данных (и GND).

Он может питаться от внешнего источника питания или получать питание через линию данных (так называемый «паразитный режим»), что устраняет необходимость во внешнем источнике питания.

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

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

Датчик температуры DS18B20 также доступен в водонепроницаемом исполнении.

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

Вот краткое описание наиболее важных характеристик датчика температуры DS18B20:

  • Обмен данными по шине one-wire

  • Диапазон напряжения питания: от 3,0 В до 5,5 В

  • Диапазон рабочих температур: от -55 °C до +125 °C

  • Точность ±0,5 °C (в диапазоне от -10 °C до 85 °C)

Для получения дополнительной информации обратитесь к техническому описанию DS18B20.

Необходимые компоненты

Для выполнения этого руководства вам понадобятся следующие компоненты:

  • ESP32 или ESP8266

  • Датчик температуры DS18B20 (один или несколько) — обычный или водонепроницаемый

  • Резистор 4,7 кОм

  • Соединительные провода

  • Макетная плата

Схема подключения — ESP32

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

Если вы используете ESP32, следуйте одной из этих двух схем подключения.

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

Схема подключения датчика температуры DS18B20 к ESP32 в паразитном режиме

Обычный режим

Схема подключения датчика температуры DS18B20 к ESP32 в обычном режиме

Схема подключения — ESP8266

Если вы используете ESP8266, следуйте одной из этих двух схем подключения.

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

Схема подключения датчика температуры DS18B20 к ESP8266 в паразитном режиме

Обычный режим

Схема подключения датчика температуры DS18B20 к ESP8266 в обычном режиме

Примечание

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

Код (один DS18B20)

Скопируйте следующий код в файл main.py и загрузите его на вашу плату. Этот код просто считывает температуру с датчика DS18B20 и отображает показания в консоли.

# Подробности проекта на https://RandomNerdTutorials.com

import machine, onewire, ds18x20, time

ds_pin = machine.Pin(4)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))

roms = ds_sensor.scan()
print('Found DS devices: ', roms)

while True:
  ds_sensor.convert_temp()
  time.sleep_ms(750)
  for rom in roms:
    print(rom)
    print(ds_sensor.read_temp(rom))
  time.sleep(5)

Исходный код на GitHub

Этот код работает как с ESP32, так и с ESP8266 и работает независимо от того, используете ли вы один или несколько датчиков температуры DS18B20.

Как работает код

Импортируем модуль machine для взаимодействия с GPIO, модули onewire и ds18x20 для работы с датчиком температуры DS18B20 и модуль time для добавления задержек.

import machine, onewire, ds18x20, time

Создаем переменную ds_pin, которая ссылается на GPIO 4 — пин, к которому подключена линия данных датчика температуры DS18B20.

ds_pin = machine.Pin(4)

Здесь мы считываем температуру с GPIO 4, но вы можете использовать любой другой подходящий GPIO. Вы можете проверить лучшие GPIO для использования в следующих статьях:

Затем создаем объект ds18x20 с именем ds_sensor на ранее определенном ds_pin. Если вы хотите считывать показания датчика с другого пина, вам нужно изменить предыдущую строку.

ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))

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

Следующая строка использует функцию scan() для поиска датчиков DS18B20. Найденные адреса сохраняются в переменной roms (переменная roms имеет тип list).

roms = ds_sensor.scan()

Выводим адрес каждого датчика в консоль:

print('Found DS devices: ', roms)

Далее идет цикл while, который считывает температуру с датчика(ов) DS18B20 каждые 5 секунд.

Необходимо вызывать функцию convert_temp() объекта ds_sensor каждый раз, когда вы хотите измерить температуру.

ds_sensor.convert_temp()

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

time.sleep_ms(750)

После этого мы можем прочитать температуру по адресам, найденным ранее, с помощью метода read_temp(), передав адрес в качестве аргумента, как показано в следующей строке кода.

print(ds_sensor.read_temp(rom))

Поскольку к одной линии данных можно подключить несколько датчиков, мы используем цикл for, который перебирает все адреса и выводит температуру для каждого из них:

for rom in roms:
  print(rom)
  print(ds_sensor.read_temp(rom))

Демонстрация

После загрузки кода на вашу плату вы должны получать новые показания температуры каждые 5 секунд.

Показания температуры DS18B20 MicroPython с ESP32 и ESP8266

Считывание температуры с нескольких датчиков DS18B20

Несколько датчиков DS18B20 с ESP8266

Для получения температуры с нескольких датчиков DS18B20 вы можете использовать тот же скрипт, что и ранее. Вам нужно только подключить дополнительные датчики DS18B20. Эти датчики используют одну и ту же линию данных — в данном случае все датчики подключены к GPIO 4.

Если вы используете ESP32, можете следовать следующей схеме подключения.

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

Если вы используете ESP8266, следуйте этой схеме подключения.

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

Код (несколько DS18B20)

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

# Подробности проекта на https://RandomNerdTutorials.com

import machine, onewire, ds18x20, time

ds_pin = machine.Pin(4)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))

roms = ds_sensor.scan()
print('Found DS devices: ', roms)

while True:
  ds_sensor.convert_temp()
  time.sleep_ms(750)
  for rom in roms:
    print(rom)
    print(ds_sensor.read_temp(rom))
  time.sleep(5)

Исходный код на GitHub

Показания температуры нескольких датчиков DS18B20 MicroPython с ESP32 и ESP8266

Отображение показаний температуры DS18B20 на веб-сервере

Отображение показаний температуры DS18B20 на веб-сервере MicroPython

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

Для этого примера вам понадобятся два файла:

  • boot.py: запускается при старте устройства и устанавливает различные параметры конфигурации, такие как ваши сетевые учетные данные, импорт библиотек, настройку пинов и т.д.

  • main.py: это основной скрипт, в котором мы обрабатываем веб-сервер. Он выполняется сразу после boot.py.

Примечание

Хорошей практикой является использование файлов boot.py и main.py. Однако при желании вы можете включить весь код в файл main.py.

boot.py (веб-сервер DS18B20)

Создайте новый файл в вашей IDE с именем boot.py и скопируйте следующий код.

# Подробности проекта на https://RandomNerdTutorials.com

try:
  import usocket as socket
except:
  import socket

from time import sleep
from machine import Pin
import onewire, ds18x20

import network

import esp
esp.osdebug(None)

import gc
gc.collect()

ds_pin = Pin(4)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))

ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'

station = network.WLAN(network.STA_IF)

station.active(True)
station.connect(ssid, password)

while station.isconnected() == False:
  pass

print('Connection successful')
print(station.ifconfig())

Исходный код на GitHub (boot.py)

Этот файл импортирует необходимые библиотеки, настраивает датчик DS18B20 и подключается к вашей сети.

Здесь мы устанавливаем пин данных DS18B20 на GPIO 4, но вы можете использовать любой другой подходящий пин:

ds_pin = Pin(4)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))

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

ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'

main.py (веб-сервер DS18B20)

В файле main.py мы создаем веб-сервер и обрабатываем запросы. Скопируйте следующий код в файл main.py.

# Подробности проекта на https://RandomNerdTutorials.com

def read_ds_sensor():
  roms = ds_sensor.scan()
  print('Found DS devices: ', roms)
  print('Temperatures: ')
  ds_sensor.convert_temp()
  for rom in roms:
    temp = ds_sensor.read_temp(rom)
    if isinstance(temp, float):
      msg = round(temp, 2)
      print(temp, end=' ')
      print('Valid temperature')
      return msg
  return b'0.0'

def web_page():
  temp = read_ds_sensor()
  html = """<!DOCTYPE HTML><html><head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css"
    integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr"
    crossorigin="anonymous">
  <style> html { font-family: Arial; display: inline-block; margin: 0px auto;
    text-align: center; }
    h2 { font-size: 3.0rem; } p { font-size: 3.0rem; }
    .units { font-size: 1.2rem; }
    .ds-labels{ font-size: 1.5rem; vertical-align:middle;
      padding-bottom: 15px; }
  </style></head><body><h2>ESP with DS18B20</h2>
  <p><i class="fas fa-thermometer-half" style="color:#059e8a;"></i>
    <span class="ds-labels">Temperature</span>
    <span id="temperature">""" + str(temp) + """</span>
    <sup class="units">&deg;C</sup>
  </p>
    <p><i class="fas fa-thermometer-half" style="color:#059e8a;"></i>
    <span class="ds-labels">Temperature</span>
    <span id="temperature">""" + str(round(temp * (9/5) + 32.0, 2)) + """</span>
    <sup class="units">&deg;F</sup>
  </p></body></html>"""
  return html

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)

while True:
  try:
    if gc.mem_free() < 102000:
      gc.collect()
    conn, addr = s.accept()
    conn.settimeout(3.0)
    print('Got a connection from %s' % str(addr))
    request = conn.recv(1024)
    conn.settimeout(None)
    request = str(request)
    print('Content = %s' % request)
    response = web_page()
    conn.send('HTTP/1.1 200 OK\n')
    conn.send('Content-Type: text/html\n')
    conn.send('Connection: close\n\n')
    conn.sendall(response)
    conn.close()
  except OSError as e:
    conn.close()
    print('Connection closed')

Исходный код на GitHub (main.py)

Чтение датчика DS18B20

Код начинается с создания функции read_ds_sensor(), которая получает температуру с датчика DS18B20. Если вы следовали предыдущему разделу, вы должны быть знакомы с используемыми здесь методами.

def read_ds_sensor():
  roms = ds_sensor.scan()
  print('Found DS devices: ', roms)
  ds_sensor.convert_temp()
  for rom in roms:
    temp = ds_sensor.read_temp(rom)
    if isinstance(temp, float):
      temp = round(temp, 2)
      print('Valid temperature')
      return temp
  return '0'

Веб-страница

Функция web_page() возвращает HTML-страницу с последними показаниями температуры.

Мы создавали подобную веб-страницу в предыдущем руководстве. Если вы хотите узнать, как работает этот HTML, вы можете прочитать эту статью: MicroPython: ESP32/ESP8266 веб-сервер с DHT11/DHT22.

Создание веб-сервера

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

while True:
  try:
    if gc.mem_free() < 102000:
      gc.collect()
    conn, addr = s.accept()
    conn.settimeout(3.0)
    print('Got a connection from %s' % str(addr))
    request = conn.recv(1024)
    conn.settimeout(None)
    request = str(request)
    print('Content = %s' % request)
    response = web_page()
    conn.send('HTTP/1.1 200 OK\n')
    conn.send('Content-Type: text/html\n')
    conn.send('Connection: close\n\n')
    conn.sendall(response)
    conn.close()
  except OSError as e:
    conn.close()
    print('Connection closed')

По сути, когда ESP получает запрос, мы отправляем веб-страницу с последними показаниями в качестве ответа:

response = web_page()
conn.send('HTTP/1.1 200 OK\n')
conn.send('Content-Type: text/html\n')
conn.send('Connection: close\n\n')
conn.sendall(response)

Демонстрация веб-сервера

После загрузки файлов boot.py и main.py на вашу плату нажмите кнопку RST на ESP для запуска кода.

Затем откройте браузер и введите IP-адрес ESP. Вы должны увидеть веб-страницу с последними показаниями датчика в градусах Цельсия и Фаренгейта:

Показания температуры DS18B20 на веб-сервере ESP32 ESP8266

Заключение

Мы надеемся, что это руководство по MicroPython для датчика температуры DS18B20 с ESP32 и ESP8266 было для вас полезным. У нас есть другие проекты с ESP и MicroPython, которые могут вам понравиться: