Датчики — Температура с интерфейсом 1-Wire и DS18B20
Продолжая тему прошлого урока об использовании датчика i2c, на этой неделе мы рассмотрим ещё один стандартный протокол — «1-wire». Как следует из названия, для передачи подробной информации о состоянии датчика используется всего один провод. На самом деле датчику нужны три провода, так как необходимо подавать питание, но «1-wire» относится именно к передаче данных.
Один из распространённых датчиков 1-wire — это температурный датчик 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 внизу. Это обеспечивает датчик температуры питанием.
Если вы используете водонепроницаемый датчик, у вас могут возникнуть проблемы с вставкой жил провода в отверстия макетной платы. Я использую клеммную колодку и прикручиваю к ней провода.
Другой конец резистора нужно вставить в другой столбец макетной платы, между красным выводом датчика температуры и соединительным проводом, подключённым к «шине» 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
Теперь наблюдайте за температурой датчика, пока вы держите его в руке или опускаете в стакан с водой (если у вас водонепроницаемая версия!).