Raspberry Pi и датчик температуры ds18b20

Dallas Semiconductors, теперь часть Maxim Integrated, имеет некоторые очень хорошие чипы-термометры в их серии DS1820. Уникальное свойство этих термометров заключается в том, что они могут быть соединены единым цифровым интерфейсом по одной проводной шине данных (1-Wire). Вы даже можете разместить несколько датчиков (не только термометры) на одном и том же проводе, если пожелаете.

Подключение одного или нескольких цифровых датчиков температуры ds18b20 до Raspberry Pi осуществляется через резистор 4.7 кОм (рисунок 1).

raspberry_pi+ds18b20
Рисунок 1 – Схема подключения датчиков ds18b20 к Raspberry Pi

Использование 1-Wire термометров реализовано на Paspbery Pi очень просто. Все, что вам нужно это загрузить два специальные модули ядра и все, можно читать температуру. Модули загружаются набором в командной строке следующих команд:
sudo modprobe w1-gpio
sudo modprobe w1-therm

Первая строка активирует протокол модуля 1-wire на GPIO4. Вторая строка загружает модуль, который, собственно, читает температуру с 1-wire шины. Для того, чтобы модули автоматически загружались после перезагрузки или выключения Raspberry Pi, две вышеприведенные строки нужно добавить в файл /etc/modules. Делается это так:
sudo nano /etc/modules

И добавляем в конец файла (если их там нет) две строчки:
w1-gpio
w1-therm

Таким образом вопрос чтения текущей температуры сводится к чтению специального файла. Этот файл расположен в каталоге /sys/bus/w1/devices. Этот каталог содержит один или несколько подкаталогов. Один, который всегда присутствует, называется w1_bus_master1. Но нас он не интересует. Нас интересуют каталоги вида 28-000800575c8b. Для каждого подключенного по 1-wire датчика температуры создается свой такой каталог. Может потребоваться несколько секунд для их появления. Название каждого каталога – это уникальный серийный номер датчика ds18b20. Если вы подключили более одного датчика по шине, вам придется выяснить какой каталог с серийным номером какому датчику принадлежит. Сделать это можно путем прогревания одного датчика, считывания температуры со всех датчиков и проверки температура которого именно меняется. Или можно подключать датчики поочередно и записывать, какой каталог какому датчику отвечает.

Считать температурные показания датчика можно так (замените серийный номер на номер вашего датчика):
cat 28-000800575c8b/w1_slave

В результате вы увидите нечто вроде этого:
30 00 4b 46 ff ff 0f 10 b8 : crc=b8 YES
30 00 4b 46 ff ff 0f 10 b8 t=23812

Шестнадцатеричные числа воспроизводят байтовую информацию, которую датчик вернул вашему Raspberry Pi. Первая строка проверяет, корректность контрольной суммы CRC (последний байт ответа должен быть таким же как исчисленная CRC). Если все правильно выводится “YES”, если нет – выводится “NO”. Если ответ “NO”, необходимо снова считать данные с датчика, ибо данная температура не корректна. Вторая строчка содержит считанную температуру в градусах Цельсия, умноженную на 1000, поэтому необходимо разделить ее на 1000, чтобы сделать читабельной для человека.
Ниже приведен пример скрипта для считывания и воспроизведения всех датчиков на шине.



#! /bin/bash

# This script reads the temperature from all connected 1-wire temperature
# sensors of the DS1820 family.
# The script will answer nothing if it can't find any sensors.
#
# Author: San Bergmans
# www.sbprojects.com

W1DIR="/sys/bus/w1/devices"

# Exit if 1-wire directory does not exist
if [ ! -d $W1DIR ]
then
echo "Can't find 1-wire device directory"
exit 1
fi

# Get a list of all devices
DEVICES=$(ls $W1DIR)

# Loop through all devices
for DEVICE in $DEVICES
do
# Ignore the bus master device
if [ $DEVICE != "w1_bus_master1" ]
then
# Get an answer from this device
ANSWER=$(cat $W1DIR/$DEVICE/w1_slave)

# See if device really answered
# When a previously existing device is removed it will
# read 00 00 00 00 00 00 00 00 00, which results in a
# valid CRC. That's why we need this extra test.
echo -e "$ANSWER" | grep -q "00 00 00 00 00 00 00 00 00"

if [ $? -ne 0 ]
then
# The temperature is only valid if the CRC matches
echo -e "$ANSWER" | grep -q "YES"
if [ $? -eq 0 ]
then
# Isolate the temprature from the second line
TEMPERATURE=$(echo -e "$ANSWER" | grep "t=" | cut -f 2 -d "=")
# Isolate integer and fraction parts so we know where
# the decimal point should go
INTEGER=${TEMPERATURE:0:(-3)}
FRACTION=${TEMPERATURE:(-3)}

# Restore the leading 0 for positive and negative numbers
if [ -z $INTEGER ]
then
INTEGER="0"
fi
if [ "$INTEGER" == "-" ]
then
INTEGER="-0"
fi

# Write result of this sensor
echo "$DEVICE=$INTEGER.$FRACTION"
else
# A CRC was found, show error message instead
echo "$DEVICE=CRC error"
fi
fi
fi
done

4 комментария

  1. Мне думается, что опрос датчика происходит в момент чтения файла. Или даже не в момент чтения, а в момент открытия файлового дескриптора. И пока дескриптор не будет переоткрыт значение температуры не изменится.

  2. У ds18b20 хранимое значение температуры может отличаться от реальной температуры. В нем разделяется измерение температуры и получение сохраненного значения температуры. После окончания измерения температуры (длится около 750 мс) обновляется сохраненное значение. В момент чтения файла считывается сохраненное значение и запускается новое измерение температуры. Т.е. при следующем считывании будет прочитано значение температуры, на момент предыдущего считывания файла. Если ваш скрипт будет считывать файл редко, то эта особенность будет очень сильно заметна. Т.е. если последний раз считывали температуру час назад, то при считывании получите температуру, которая была час назад.
    В своем скрипте, я вначале открываю файл, читаю и тут же закрываю его, не обрабатывая результат, а потом открываю его через 1 секунду (нужно как минимум 750 мс чтобы ds18b20 закончил измерение и обновил сохраненное значение температуры при 12 битном разрешении)., проверяю наличие слова YES и читаю температуру, которую при правильной CRC можно считать действительной.

  3. у меня заработало только после добавления в файл /boot/config.txt строчки

    dtoverlay=w1-gpio,gpiopin=4

    а так всё очень даже чудненько, с учётом комментария о сохранённом значении

Оставить ответ

Обязательные поля помечены*

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.