Датчики — Температура с интерфейсом 1-Wire и DS18B20

Продолжая тему прошлого урока об использовании датчика i2c, на этой неделе мы рассмотрим ещё один стандартный протокол — «1-wire». Как следует из названия, для передачи подробной информации о состоянии датчика используется всего один провод. На самом деле датчику нужны три провода, так как необходимо подавать питание, но «1-wire» относится именно к передаче данных.

Один из распространённых датчиков 1-wire — это температурный датчик Dallas DS18B20. Он выпускается в разных корпусах, основной из которых выглядит как транзистор с тремя ножками. Другой форм-фактор, который я предпочитаю, — это водонепроницаемая версия, где датчик встроен в металлическую трубку на конце длинного провода.

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

Сборка схемы

Вам понадобятся:

  • Датчик Dallas DS18B20 (любая версия)

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

    • Если полосок четыре, цвета будут: Жёлтый, Фиолетовый, Красный, а затем Золотой

    • Если полосок пять, цвета будут: Жёлтый, Фиолетовый, Чёрный, Коричневый, Коричневый

  • 4 соединительных провода «мама-папа»

  • 2 соединительных провода «папа-папа»

Перед сборкой этой схемы вы должны выключить Raspberry Pi.

В схеме будет использоваться контакт «земля» (GND), который выполняет роль «минуса» или 0 вольт батареи. Один из контактов, обозначенных 3v3, обеспечит питание датчика. 3v3 означает, что это источник питания 3,3 вольта.

Используйте два соединительных провода «мама-папа», чтобы подключить контакты GND и 3v3 GPIO к двум нижним рядам отверстий на макетной плате. Совместите цвета, отмеченные на макетной плате — красный и синий — с соединительными проводами от Raspberry Pi: подключите 3v3 к красному ряду, а GND — к синему ряду. Эти две «шины» (как их называют) обеспечат заземление и питание для всей макетной платы.

Подключите датчик температуры, как показано на рисунке, с помощью соединительного провода «папа-папа», идущего к нижней «шине», подключённой к земле (GND) Raspberry Pi. Подключите красный провод с помощью перемычки к «шине» 3v3 внизу. Это обеспечивает датчик температуры питанием.

Схема подключения датчика DS18B20 к Raspberry Pi

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

Клеммная колодка PCB

Другой конец резистора нужно вставить в другой столбец макетной платы, между красным выводом датчика температуры и соединительным проводом, подключённым к «шине» 3v3. Жёлтый вывод вставляется в столбец с одним концом резистора 4,7 кОм и ещё одним соединительным проводом (показан жёлтым), который идёт к контакту GPIO 4. Программа будет считывать температуру с этого контакта.

Настройка Raspberry Pi

Прежде чем вы сможете использовать любые устройства 1-wire, необходимо сначала указать Raspberry Pi, как их читать. Откройте окно терминала и введите следующее, чтобы отредактировать файл конфигурации Raspberry Pi:

sudo nano /boot/config.txt

Посмотрите, есть ли строка, содержащая dtoverlay=w1-gpio. Если нет, добавьте следующее в конец файла:

dtoverlay=w1-gpio

Теперь перезагрузите Raspberry Pi:

sudo reboot

Чтобы проверить конфигурацию, соберите схему, описанную выше, для подключения DS18B20 и введите следующее в окне терминала:

sudo modprobe w1-gpio
sudo modprobe w1-therm
cd /sys/bus/w1/devices
ls

Это выведет список всех устройств, подключённых к интерфейсу 1-wire. Датчик Dallas DS18B20 начинается с «28-», за которым следует длинный номер. Введите следующее, заменив «xxxx» текстом, следующим за «28-»:

cd 28-xxxx
cat w1_slave

В ответ вы должны получить следующее, показывающее, что DS18B20 работает:

a3 01 4b 46 7f ff 0e 10 d8 : crc=d8 YES
a3 01 4b 46 7f ff 0e 10 d8 t=32768

Чтение данных с датчика

Создайте новый скрипт Python из окна терминала (с помощью nano 3-temperature.py) или из IDLE — «интерактивной среды разработки». Введите следующий пример кода:

# Импорт библиотек
import os
import glob
import time

# Инициализация контактов GPIO
os.system('modprobe w1-gpio')  # Включает модуль GPIO
os.system('modprobe w1-therm') # Включает модуль температуры

# Находит правильный файл устройства, содержащий данные температуры
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'

# Функция, которая считывает данные с датчика
def read_temp_raw():
  f = open(device_file, 'r') # Открывает файл устройства температуры
  lines = f.readlines() # Возвращает текст
  f.close()
  return lines

# Преобразование значения датчика в температуру
def read_temp():
  lines = read_temp_raw() # Считывает «файл устройства» температуры

  # Пока первая строка не содержит 'YES', ждём 0.2 секунды
  # и затем снова считываем файл устройства.
  while lines[0].strip()[-3:] != 'YES':
    time.sleep(0.2)
    lines = read_temp_raw()

  # Ищем позицию '=' во второй строке файла устройства.
  equals_pos = lines[1].find('t=')

  # Если '=' найден, преобразуем остаток строки после '='
  # в градусы Цельсия, затем в градусы Фаренгейта
  if equals_pos != -1:
    temp_string = lines[1][equals_pos+2:]
    temp_c = float(temp_string) / 1000.0
    temp_f = temp_c * 9.0 / 5.0 + 32.0
    return temp_c, temp_f

# Выводим температуру, пока программа не будет остановлена.
while True:
  print(read_temp())
  time.sleep(1)

Чтобы запустить код, нужно быть суперпользователем, поэтому запускайте код с помощью:

sudo python temperature.py

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