День #8 адвент-календаря для мейкеров: следим за температурой!
Добро пожаловать на восьмой день вашего адвент-календаря «12 проектов Кодмас». Сегодня мы будем измерять температуру окружающей среды и использовать эти показания для создания интересных проектов!
Датчики температуры — ещё один компонент, мимо которого вы, скорее всего, проходите каждый день. Термостат домашней системы отопления — будь то традиционная модель или современный умный термостат — использует нечто похожее на то, что вы найдёте в своей коробке сегодня. Духовки, автомобили, офисы и многие другие предметы и места повседневной жизни используют датчики температуры.
С приходом зимы, которая с каждым днём становится всё холоднее, самое время научиться следить за температурой с помощью кода и вашего Pico!
Содержимое коробки #8
В этой коробке вы найдёте:
1x Водонепроницаемый датчик температуры с разъёмами «папа»
1x Резистор 4,7 кОм
3x Провода «папа-папа»
Сегодняшний проект
Сегодня мы используем датчик температуры для измерения температуры воздуха в вашем доме, а затем перейдём к более интересным проектам: измерению температуры жидкости и созданию сигнализации, которая предупредит вас, когда в доме становится слишком холодно!
Датчик в вашей коробке — это специальная версия нашего популярного водонепроницаемого датчика температуры. Металлический наконечник содержит внутри сам датчик (а именно DS18B20-совместимый однопроводной (1-wire) датчик) и заключён в защитную оболочку кабеля, что позволяет погружать его в воду и другие жидкости для измерения температуры.
Мы добавили к этой версии разъёмы «папа», чтобы её было удобнее использовать с макетной платой.
Что такое 1-wire?
1-wire — это последовательный протокол связи, позволяющий устройствам общаться с контроллером…
…Хм, давайте объясним по-человечески! 1-wire позволяет специальному устройству, например нашему датчику температуры, разговаривать с контроллером, например нашим Pico, передавая ему данные для использования в программе.
Несмотря на своё название, для работы с 1-wire устройствами вам потребуется как минимум два провода, а в некоторых примерах (например, с нашим датчиком) мы используем три провода. Название связано с передачей данных: для двусторонней связи между устройствами достаточно одного провода.
Собираем схему
Мы снова будем использовать светодиоды и зуммер вместе с датчиком температуры (они отлично сочетаются с самыми разными датчиками и компонентами!), поэтому уберите схему с PIR-датчиком из предыдущего дня, оставив на главной макетной плате только светодиоды и зуммер.
Исходная схема должна выглядеть так:
Теперь подключим датчик температуры к мини-макетной плате. У вашего датчика должны быть три провода: красный, жёлтый и белый (белый провод может быть чёрным в зависимости от партии).
Вставьте провода в верхний край мини-макетной платы в порядке белый-жёлтый-красный, как показано на изображении ниже:
Далее добавьте резистор, соединив жёлтый и красный провода так, как показано ниже:
Теперь нужно добавить три провода для завершения схемы и подключения датчика к нашему Pico:
Подключите левую ногу к синей шине GND
Подключите среднюю ногу к GPIO 26 (физический вывод 31)
Подключите правую ногу к 3,3 В на физическом выводе 36
Ваша схема должна выглядеть примерно так:
Задание 1: простое измерение температуры
Начнём с минимальной программы для получения одного показания температуры с датчика.
Импорт библиотек
Этот датчик требует нескольких новых импортов, которые берут на себя большую часть сложной работы: библиотека **onewire** и библиотека **ds18x20**. К счастью, они теперь встроены в MicroPython, поэтому нам не нужно ничего дополнительно скачивать.
Код для 1-wire
Мы настраиваем вывод датчика как вход, как делали раньше с другими датчиками, однако этот конкретный 1-wire датчик требует дополнительного кода для корректной работы.
Нам нужно сообщить MicroPython, что мы используем 1-wire датчик DS18B20, с помощью следующей строки в коде ниже: sensor = ds18x20.DS18X20(onewire.OneWire(SensorPin))
Также нам нужно просканировать вывод GPIO на наличие 1-wire устройств. Такие устройства, как наш датчик, имеют уникальный регистрационный номер в своей п**остоянной **п**амяти (**rom). Следующая строка в нашем коде ниже выполняет сканирование датчиков (roms), подключённых к нашему выводу: roms = sensor.scan().
Цикл for
Затем мы используем цикл **while**, содержащий цикл **for**. Мы использовали цикл **for** вчера с датчиком движения при использовании функции **range**, но на этот раз наш диапазон будет roms (количество rom, найденных при сканировании, то есть наш единственный датчик). Цикл for говорит: «для каждого rom, который я найду, сделай это».
Затем код преобразует показания температуры датчика в градусы Цельсия и выводит их, добавляя в конце символ °C. Комментарии в коде должны всё прояснить — попробуйте!
Код
# Импорты
import onewire, ds18x20, time
from machine import Pin
# Устанавливаем вывод данных для датчика
SensorPin = Pin(26, Pin.IN)
# Сообщаем MicroPython, что используем датчик DS18B20 и указываем, к какому выводу он подключён
sensor = ds18x20.DS18X20(onewire.OneWire(SensorPin))
# Ищем датчики DS18B20 (каждый содержит уникальный код rom)
roms = sensor.scan()
while True: # Запускаем бесконечно
sensor.convert_temp() # Конвертируем единицы датчика в градусы Цельсия
time.sleep(2) # Ждём 2 секунды (нужно подождать не менее 1 секунды перед снятием показания)
for rom in roms: # Для каждого найденного датчика (только 1 в нашем случае)
print((sensor.read_temp(rom)),"°C") # Выводим показание температуры с °C в конце
time.sleep(5) # Ждём 5 секунд перед повторным запуском цикла
Задание 2: индикаторы температуры
Теперь, когда основы разобраны, используем эти показания для управления светодиодами, которые дадут нам визуальную индикацию температуры.
Пример ниже возвращает наши светодиоды и использует цикл **while** с несколькими условиями оператора **if** для управления светодиодами в зависимости от температуры: красный — если температура опускается ниже 18°C, янтарный — если она находится в комфортном диапазоне 18°C–22°C, и зелёный — если превышает 22°C.
Мы уже рассматривали циклы while, операторы if, if/elif и диапазоны в предыдущих коробках, поэтому код в этом примере должен быть вам очень знаком.
Возьмите несколько стаканов воды при разной температуре (никакого кипятка!) и попробуйте опустить водонепроницаемый конец датчика в каждый из них, наблюдая за изменением показаний и загоранием разных светодиодов. Держите Pico как можно дальше от воды… вода и электроника не лучшие друзья…
Код
# Импорты
import onewire, ds18x20, time
from machine import Pin
# Настраиваем выводы светодиодов
red = Pin(18, Pin.OUT)
amber = Pin(19, Pin.OUT)
green = Pin(20, Pin.OUT)
# Устанавливаем вывод данных для датчика
SensorPin = Pin(26, Pin.IN)
# Сообщаем MicroPython, что используем датчик DS18B20 и указываем, к какому выводу он подключён
sensor = ds18x20.DS18X20(onewire.OneWire(SensorPin))
# Ищем датчики DS18B20 (каждый содержит уникальный код rom)
roms = sensor.scan()
while True: # Запускаем бесконечно
time.sleep(5) # Ждём 5 секунд между показаниями
for rom in roms: # Для каждого найденного датчика (только 1 в нашем случае)
sensor.convert_temp() # Конвертируем единицы датчика в градусы Цельсия
time.sleep(1) # Всегда ждём 1 секунду после конвертации
reading = sensor.read_temp(rom) # Снимаем показание температуры
print(reading) # Выводим показание
if reading <= 18: # Если показание меньше или равно 18
red.value(1) # Красный ВКЛ
amber.value(0)
green.value(0)
elif 18 < reading < 22: # Если показание между 18 и 22
red.value(0)
amber.value(1) # Янтарный ВКЛ
green.value(0)
elif reading >= 22: # Если показание больше или равно 22
red.value(0)
amber.value(0)
green.value(1) # Зелёный ВКЛ
Задание 3: температурная сигнализация
Теперь мы можем снова добавить наш зуммер и функцию сигнализации в код, создав интересный проект температурной тревоги.
Тогда как вчерашняя сигнализация с датчиком движения отлично подходила для обнаружения перемещения людей в помещении, эта сигнализация позволяет следить за температурой в конкретной комнате или зоне.
У большинства из нас дома есть термостаты, но создание собственного температурного сигнализатора для мониторинга конкретного места — это очень интересное занятие. Он может пригодиться для поддержания вашего здоровья или контроля условий содержания растений и домашних животных.
Код
Пример сигнализации ниже похож на вчерашнюю сигнализацию движения: он использует функцию сигнализации для включения светодиодов и звука зуммера, когда температура опускается ниже 18°C — измените 18 на значение, подходящее для вашего проекта или сценария.
Мы добавили как можно больше комментариев, чтобы помочь вам вспомнить, что делает каждый раздел:
# Импорты
import onewire, ds18x20, time
from machine import Pin, PWM
# Настраиваем выводы светодиодов
red = Pin(18, Pin.OUT)
amber = Pin(19, Pin.OUT)
green = Pin(20, Pin.OUT)
# Настраиваем вывод зуммера как ШИМ
buzzer = PWM(Pin(13))
# Устанавливаем коэффициент заполнения ШИМ на 0% при старте программы
buzzer.duty_u16(0)
# Устанавливаем вывод данных для датчика
SensorPin = Pin(26, Pin.IN)
# Сообщаем MicroPython, что используем датчик DS18B20 и указываем, к какому выводу он подключён
sensor = ds18x20.DS18X20(onewire.OneWire(SensorPin))
# Ищем датчики DS18B20 (каждый содержит уникальный код rom)
roms = sensor.scan()
def alarm(): # Наша функция сигнализации
buzzer.duty_u16(10000) # Увеличиваем коэффициент заполнения зуммера (громкость)
for i in range(5): # Запускаем 5 раз
buzzer.freq(5000) # Высокий тон
# Светодиоды ВКЛ
red.value(1)
amber.value(1)
green.value(1)
time.sleep(0.2) # Ждём 0,2 секунды
buzzer.freq(1000) # Низкий тон
# Светодиоды ВЫКЛ
red.value(0)
amber.value(0)
green.value(0)
time.sleep(0.2) # Ждём 0,2 секунды
buzzer.duty_u16(0) # Отключаем зуммер (громкость на 0)
while True: # Запускаем бесконечно
time.sleep(5) # Ждём 5 секунд между показаниями
for rom in roms: # Для каждого найденного датчика (только 1 в нашем случае)
sensor.convert_temp() # Конвертируем единицы датчика в градусы Цельсия
time.sleep(1) # Всегда ждём 1 секунду после конвертации
reading = sensor.read_temp(rom) # Снимаем показание температуры
print(reading) # Выводим показание
if reading < 18: # Если показание меньше 18
alarm() # Вызываем функцию сигнализации
День #8 завершён!
Ещё один день, ещё один освоенный компонент! Теперь в вашем растущем арсенале деталей для создания проектов появился датчик температуры, и мы уверены, что вы будете использовать его снова и снова.
Как вы, вероятно, начинаете замечать, многие датчики и компоненты программируются очень похожим образом. Иногда нам нужна помощь импортируемых библиотек, иногда требуются резисторы и дополнительное оборудование, но фундаментальный способ написания кода для них (с циклами, операторами if и переменными) достаточно последователен.
Так что же мы изучили в день #8? Сегодня вы:
Собрали схему с датчиком температуры
Научились использовать датчик температуры с MicroPython и Pico
Использовали свой первый 1-wire компонент и 1-wire библиотеку
Создали монитор температуры и систему температурной сигнализации
Узнали больше о циклах for
Как всегда, сохраните схему в безопасном месте до завтра (ничего не разбирайте пока) и до встречи завтра — нас ждёт ещё больше веселья!
—
Схемы подключения на макетной плате созданы с помощью Fritzing.