Плата Raspberry Pi хорошо известна в современном мире благодаря своей вычислительной мощности и широкой распространенности в проектах интернета вещей, автоматизации дома. Тем не менее, ни один достаточно сложный электронный проект не может нормально работать без информации об окружающем мире, получаемой с помощью разнообразных датчиков.
Одним из таких часто используемых датчиков является датчик температуры DS18B20, способный работать в условиях агрессивной окружающей среды: заводы, химические производства и т.д. В данной статье мы рассмотрим его подключение к плате Raspberry Pi. Получаемое от датчика значение температуры мы будем выводить на экран ЖК дисплея 16×2. Ранее на нашем сайте мы рассматривали подключение датчика DS18B20 к плате Arduino и микроконтроллеру AVR. Также вы можете посмотреть статью о подключении к плате Raspberry Pi датчика температуры и влажности DHT11.
Необходимые компоненты
- Плата Raspberry Pi (купить на AliExpress).
- ЖК дисплей 16×2 (купить на AliExpress).
- Датчик температуры DS18B20 (купить на AliExpress).
- Подтягивающий резистор 10 кОм (купить на AliExpress).
- Потенциометр 10 кОм (купить на AliExpress).
- Макетная плата.
- Соединительные провода.
Реклама: ООО «АЛИБАБА.КОМ (РУ)» ИНН: 7703380158
Общие принципы работы датчика DS18B20
DS18B20 представляет собой датчик температуры с 3 выводами, упакованный в корпус TO-92 (транзисторный тип). С ним очень просто работать и для его подключения необходимо использовать всего один внешний компонент (подтягивающий резистор). Для его подключения к микроконтроллеру используется всего один контакт. Внешний вид датчика DS18B20 и его распиновка показаны на следующем рисунке.
Датчик DS18B20 доступен также в водонепроницаемом варианте, при котором он заключен в цилиндрическую металлическую трубку. В этом проекте мы его будем использовать в обычном виде – в транзисторном корпусе. DS18B20 является однопроводным программируемым датчиком температуры, что означает что ему необходим всего лишь один контакт данных чтобы передавать информацию микроконтроллеру (в нашем случае плате Raspberry Pi). Каждый датчик имеет свой уникальный адрес длиной 64 бита, что позволяет по одной и той же шине (проводу) подключать к одному и тому же микроконтроллеру множество подобных датчиков – в этом случае обращение к конкретному датчику осуществляется по его адресу.
Датчик DS18B20 имеет следующие технические характеристики:
— рабочее напряжение: 3-5V;
— диапазон измеряемых температур: от -55°C до +125°C;
— точность измерения температуры: ±0.5°C;
— разрешение: от 9 до 12 бит.
Схема проекта
Схема подключения датчика температуры DS18B20 к плате Raspberry Pi представлена на следующем рисунке.
В представленной схеме датчик DS18B20 и ЖК дисплей запитываются от контакта 5V платы Raspberry Pi. ЖК дисплей подключен к плате в 4-битном режиме, его контакты данных подключены к контактам GPIO 18, 23, 24 и 25 платы, а контакты управления – к контактам GPIO 7 и 8 платы. Потенциометр используется для регулировки контрастности ЖК дисплея. Контакт данных датчика DS18B20 подключен к контакту GPIO 4 платы Raspberry Pi. Резистор 10 кОм, подключенный к датчику, выполняет роль подтягивающего резистора.
Чтобы вам легче было делать соединения в схеме на следующем рисунке представлена схема расположения контактов платы Raspberry Pi.
После сборки схемы на макетной плате у нас получилась конструкция следующего вида:
Установка библиотеки Adafruit для работы с ЖК дисплеем
Библиотека от Adafruit позволяет значительно упростить управление ЖК дисплеем в 4-битном режиме с платы Raspberry Pi. Поэтому откроем терминал и выполним следующую последовательность шагов.
Шаг 1. Установим инструмент git на плату Raspberry Pi. Git позволяет клонировать файлы любого проекта на Github и затем использовать их в плате. Для установки git выполним следующую команду:
1 |
apt-get install git |
Шаг 2. Клонируем нужную нам библиотеку от Adafruit с Github с помощью инструмента git.
1 |
git clone git://github.com/adafruit/Adafruit_Python_CharLCD |
Шаг 3. Сменим каталог на тот, куда мы клонировали библиотеку.
1 |
cd Adafruit_Python_CharLCD |
Шаг 4. Установим библиотеку с помощью файла setup.py, который находится в каталоге со скачанной библиотекой. Для этого используем следующую команду:
1 |
sudo python setup.py install |
В результате выполнения этой команды необходимая нам библиотека будет установлена.
Активация однопроводного (One-Wire) интерфейса в Raspberry Pi
Поскольку датчик DS18B20 передает данные по однопроводному интерфейсу (One-Wire) нам необходимо включить использование данного интерфейса в настройках платы Raspberry Pi. Для этого выполните следующую последовательность шагов.
Шаг 1. Откройте в редакторе файл config.txt.
1 |
sudo nano /boot/config.txt |
Шаг 2. Внутрь данного файла добавьте строку “dtoverlay=w1-gpio” как показано на следующем рисунке и сохраните изменения в файле.
Шаг 3. Используйте Ctrl+X чтобы выйти из файла и “Y”, и затем Enter чтобы сохранить изменения в файле. После этого перезагрузите плату Raspberry Pi.
1 |
sudo reboot |
Шаг 4. После перезагрузки платы снова откройте терминал и выполните следующую последовательность команд:
1 2 3 4 |
sudo modprobe w1-gpio sudo modprobe w1-therm. cd /sys/bus/w1/devices ls |
После этого в окне терминала у вас должна появиться примерно следующая картина:
Шаг 5. В конце шага 4 вы вводите команду ls, в результате ее выполнения ваша плата покажет вам уникальный номер, этот номер будет уникальный для каждого датчика, но он всегда будет начинаться с 28-. В нашем случае мы получили адрес датчика 28-03172337caff.
Шаг 6. Теперь проверим корректно ли работает датчик с помощью следующих команд:
1 2 |
cd 28-XXXXXXXXXXXX [use the name of your directory or use Tab key for auto complete) cat w1_slave |
Эти две команды считают данные с датчика и отобразят их в терминале как показано на следующем рисунке. На этом рисунке значение температуры обведено красной линией – оно равно 37*C.
Объяснение программы для Raspberry Pi
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
В программе нам необходимо по однопроводному протоколу считать значение температуры с датчика DS18B20 и отобразить его на экране ЖК дисплея.
Первым делом в программе нам необходимо подключить (импортировать) используемые библиотеки:
- time – для использования задержек в программе;
- LCD – для работы с ЖК дисплеем;
- os – для обработки файлов в операционной системе.
1 2 3 4 |
import time #import time for creating delay import Adafruit_CharLCD as LCD #Import LCD library import os #Import for file handling import glob #Import for global |
Далее в программе нам необходимо указать контакты платы Raspberry Pi, к которым подключен ЖК дисплей. Затем мы должны указать количество строк и столбцов ЖК дисплея и инициализировать его.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
lcd_rs = 7 #RS of LCD is connected to GPIO 7 on PI lcd_en = 8 #EN of LCD is connected to GPIO 8 on PI lcd_d4 = 25 #D4 of LCD is connected to GPIO 25 on PI lcd_d5 = 24 #D5 of LCD is connected to GPIO 24 on PI lcd_d6 = 23 #D6 of LCD is connected to GPIO 23 on PI lcd_d7 = 18 #D7 of LCD is connected to GPIO 18 on PI lcd_backlight = 0 #LED is not connected so we assign to 0 lcd_columns = 16 #for 16*2 LCD lcd_rows = 2 #for 16*2 LCD lcd = LCD.Adafruit_CharLCD(lcd_rs, lcd_en, lcd_d4, lcd_d5, lcd_d6, lcd_d7, lcd_columns, lcd_rows, lcd_backlight) #Send all the pin details to library |
Далее мы покажем приветственное сообщение на экране ЖК дисплея. Символ ‘\n’ в представленной ниже команде обозначает новую строку, то есть мы печатаем приветственное сообщение на второй строке ЖК дисплея. После этого мы делаем задержку в программе на 2 секунды.
1 2 |
lcd.message('DS18B20 with Pi \n -CircuitDigest') #Give a intro message time.sleep(2) #wait for 2 secs |
После этого нам необходимо вспомнить шаг 4 предыдущего пункта статьи, в котором мы активировали однопроводный интерфейс в плате. Нам необходимо повторить те же самые строчки кода, поэтому мы будем использовать функцию os.system чтобы выполнить те же самые строки. Затем мы определим местоположение файла откуда должно считываться значение температуры. Переменная device_folder указывает на каталог, имя которого начинается с ‘28-‘. Поскольку мы не знаем точное название каталога, мы используем символ «*» чтобы открыть любой каталог, который начинается с 28. Наконец, внутри каталога мы используем другую переменную с именем device_file, которая указывает на файл, который содержит значение температуры.
1 2 3 4 5 6 |
os.system('modprobe w1-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' |
Затем мы используем функцию get_temp, внутри которой мы запрограммируем последовательность шагов по считыванию значения температуры из файла, который мы определили на предыдущем шаге. Как мы ранее определили в окне терминала, файл, который содержит значение температуры, имеет следующий формат:
В нашем случае из этого файла нам понадобится только значение 37000, которое обозначает температуру равную 37.00*C. Таким образом, из этого файла мы должны удалить все ненужные нам данные, получить число целого типа 37000 и разделить его на 1000 чтобы получить действительное значение температуры. В результате мы получим следующий необходимый код для нашей функции:
1 2 3 4 5 6 7 8 9 10 11 |
def get_temp(): #Function to read the value of Temperature file = open(device_file, 'r') #opent the file lines = file.readlines() #read the lines in the file file.close() #close the file trimmed_data = lines[1].find('t=') #find the "t=" in the line if trimmed_data != -1: temp_string = lines[1][trimmed_data+2:] #trim the strig only to the temoerature value temp_c = float(temp_string) / 1000.0 #divide the value of 1000 to get actual value return temp_c #return the value to print on LCD |
Переменная lines используется для считывания строк внутри файла. Затем в каждой из этих строк происходит поиск символов “t=” и символы, которые следуют за ними (то есть значением температуры), сохраняются в переменной temp_string. Далее, чтобы получить действительное значение температуры мы делим число, содержащееся в строке temp_string, на 1000. Это полученное значение температуры мы сохраняем в переменной temp_c и возвращаем значение этой переменной в качестве результата функции.
Затем в бесконечном цикле программы нам будет всего лишь необходимо вызывать запрограммированную функцию чтобы получить требуемое нам значение температуры, которое после этого мы должны отобразить на экране ЖК дисплея. Также мы очищаем экран дисплея каждую секунду чтобы обновлять считанное значение температуры.
1 2 3 4 |
while 1: #Infinite Loop lcd.clear() #Clear the LCD screen lcd.message ('Temp = %.1f C' % get_temp()) # Display the value of temperature time.sleep(1) #Wait for 1 sec then update the values |
Тестирование работы проекта
После того как аппаратная часть проекта будет готова запустите программу проекта (приведена в конце данной статьи) на выполнение. При этом убедитесь в том, что вы включили однопроводный интерфейс в настройках платы Raspberry Pi. Если все работает так, как надо, вы должны увидеть приветственное сообщение на экране ЖК дисплея. После этого на экране дисплея должны начать показываться значения температуры, считанные с датчика.
Если на экране ЖК дисплея ничего не показывается, то отрегулируйте контрастность дисплея с помощью потенциометра. Если и это не помогло, то проверьте в схеме соединения с ЖК дисплеем.
Исходный код программы на Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
import time # библиотека для использования задержек в программе import Adafruit_CharLCD as LCD # библиотека для работы с ЖК дисплеем import os # библиотека для обработки файлов import glob #Import for global lcd_rs = 7 #RS of LCD is connected to GPIO 7 on PI lcd_en = 8 #EN of LCD is connected to GPIO 8 on PI lcd_d4 = 25 #D4 of LCD is connected to GPIO 25 on PI lcd_d5 = 24 #D5 of LCD is connected to GPIO 24 on PI lcd_d6 = 23 #D6 of LCD is connected to GPIO 23 on PI lcd_d7 = 18 #D7 of LCD is connected to GPIO 18 on PI lcd_backlight = 0 #LED is not connected so we assign to 0 lcd_columns = 16 #for 16*2 LCD lcd_rows = 2 #for 16*2 LCD lcd = LCD.Adafruit_CharLCD(lcd_rs, lcd_en, lcd_d4, lcd_d5, lcd_d6, lcd_d7, lcd_columns, lcd_rows, lcd_backlight) # инициализируем ЖК дисплей lcd.message('DS18B20 with Pi \n -CircuitDigest') # показываем приветственное сообщение time.sleep(2) # ждем 2 секунды os.system('modprobe w1-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 get_temp(): # функция для считывания значения температуры с датчика file = open(device_file, 'r') # открываем файл lines = file.readlines() # считываем строки файла file.close() # закрываем файл trimmed_data = lines[1].find('t=') # находим символы "t=" в строке if trimmed_data != -1: temp_string = lines[1][trimmed_data+2:] # вырезаем из строки необходимое нам значение температуры temp_c = float(temp_string) / 1000.0 # делим считанное значение температуры на 1000 чтобы получить правильное значение температуры return temp_c # возвращаем определенное значение температуры как результат функции while 1: # бесконечный цикл lcd.clear() # очищаем экран ЖК дисплея lcd.message ('Temp = %.1f C' % get_temp()) # отображаем значение температуры на экране ЖК дисплея time.sleep(1) # ждем 1 секунду чтобы после этого обновить результат |
2 ответа к “Подключение датчика температуры DS18B20 к Raspberry Pi”
Все конечно красиво написано и нарисовано, Но!
Если скопипастить команду из шага 4: sudo modprobe w1–gpio
в терминал, получаем ошибку: modprobe: FATAL: Module w1–gpio not found in directory /lib/modules/
И вот теперь попробуйте догадаться, что причиной всему вот эта непонятна черточка ‘–’ с кодом 8211, который у Вас вместо нормального дефиса ‘-‘ с кодом 45 🙁
Спасибо за внимательность, исправил опечатку