Raspberry Pi с DHT11/DHT22: регистратор данных температуры и влажности (Python)

В этом проекте вы создадите регистратор данных (data logger) на Raspberry Pi с датчиком DHT11/DHT22, который автоматически сохраняет температуру, влажность и соответствующую метку времени в файл .txt. Этот проект даёт вам основы сбора данных, что полезно во многих различных приложениях, использующих датчики. Вы можете применить концепции из этого проекта к любому датчику.

Raspberry Pi с DHT11 DHT22 — регистратор данных температуры и влажности на Python

Впервые работаете с датчиком температуры DHT11 или DHT22? Прочитайте наше руководство по началу работы: :doc:`Raspberry Pi: DHT11/DHT22 — температура и влажность (Python) </raspberry/rnt/raspberry-pi-dht11-dht22-python/index>`_

Предварительные требования

Прежде чем продолжить это руководство, проверьте следующие предварительные требования.

  1. Ознакомьтесь с платой Raspberry Pi — если вы не знакомы с Raspberry Pi, вы можете прочитать наше :doc:`Руководство по началу работы с Raspberry Pi здесь </raspberry/rnt/getting-started-with-raspberry-pi/index>`_.

  2. Вы должны знать, как запускать и создавать файлы Python на вашем Raspberry Pi. Мы предпочитаем программировать Raspberry Pi через SSH с помощью расширения в VS Code. У нас есть подробное руководство на эту тему: :doc:`Программирование Raspberry Pi удалённо с помощью VS Code (Remote-SSH) </raspberry/rnt/raspberry-pi-remote-ssh-vs-code/index>`_.

  3. Знайте, как использовать GPIO Raspberry Pi, чтобы правильно подключить схему. Прочитайте следующее руководство: :doc:`Руководство по распиновке Raspberry Pi: как использовать GPIO Raspberry Pi? </raspberry/rnt/raspberry-pi-pinout-gpios/index>`_

Знакомство с датчиком DHT11/DHT22

Датчики DHT11 и DHT22 используются для измерения температуры и относительной влажности. Они очень популярны среди мейкеров и любителей электроники.

Датчики температуры и влажности DHT11/DHT22

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

Для более подробного знакомства с датчиком DHT11/DHT22 прочитайте наше руководство по началу работы:

Необходимые компоненты

Raspberry Pi с датчиком DHT22 — схема

Вот список компонентов, необходимых для сборки схемы (если у вас нет платы расширения DHT, вам понадобится резистор 4,7 кОм):

Вы можете использовать ссылки выше или перейти непосредственно на MakerAdvisor.com/tools, чтобы найти все компоненты для ваших проектов по лучшей цене!

Подключение датчика DHT11/DHT22 к Raspberry Pi

Подключите датчик DHT22 или DHT11 к Raspberry Pi, как показано на следующей принципиальной схеме. Если у вас есть плата расширения DHT, игнорируйте резистор.

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

В этом примере мы подключаем вывод данных DHT к GPIO 4. Однако вы можете использовать любой другой подходящий цифровой GPIO. :doc:`Узнайте больше о GPIO Raspberry Pi здесь </raspberry/rnt/raspberry-pi-pinout-gpios/index>`_.

Получение данных температуры и влажности DHT11/22

Существуют различные способы получения показаний температуры и влажности с датчиков DHT11 или DHT22 с помощью Raspberry Pi и Python. Мы будем использовать Python-библиотеку Adafruit_CircuitPython_DHT.

Обновление Raspberry Pi

Сначала обновите ваш Raspberry Pi, если доступны какие-либо обновления. Выполните следующую команду:

sudo apt update && sudo apt upgrade

Если необходимо обновление, система спросит, хотите ли вы продолжить. Нажмите Y и Enter для продолжения. Возможно, вам придётся подождать несколько минут, если требуется обновление.

Создание виртуального окружения

Мы установим библиотеку DHT в виртуальном окружении. Создание виртуального окружения изолирует используемые нами Python-библиотеки, в данном случае библиотеку DHT, от остальной системы.

Мы создадим виртуальное окружение в каталоге на нашем Рабочем столе. Введите следующую команду в окне терминала, чтобы перейти на Рабочий стол:

cd ~/Desktop

Создайте папку для вашего проекта. Именно здесь мы создадим виртуальное окружение и установим библиотеку. Мы создадим папку с именем dht_test.

mkdir dht_test

Перейдите в только что созданную папку:

cd ~/Desktop/dht_test

Создайте виртуальное окружение для этого каталога с именем myenv. Это должен быть тот же каталог, где мы установим библиотеку DHT. Замените myenv на желаемое имя для вашего виртуального окружения.

python3 -m venv myenv

Затем вы можете выполнить следующую команду, чтобы проверить, что виртуальное окружение создано.

ls -l
Создание виртуального окружения Raspberry Pi Python

Активируйте виртуальное окружение:

source myenv/bin/activate

Ваше приглашение командной строки должно измениться, указывая на то, что вы теперь находитесь в виртуальном окружении.

Активация виртуального окружения Python

Установка библиотеки Adafruit_CircuitPython_DHT

Теперь, когда мы находимся в нашем виртуальном окружении, мы можем установить библиотеку. Выполните следующую команду:

python3 -m pip install adafruit-circuitpython-dht

Через несколько секунд библиотека будет установлена (игнорируйте любые жёлтые предупреждения об устаревших пакетах).

Установка библиотеки Adafruit_CircuitPython_DHT

Теперь у вас всё готово для написания кода на Python.

Python-скрипт регистратора данных DHT для Raspberry Pi

Создайте новый файл Python на вашем Raspberry Pi с именем dht-datalogger.py и скопируйте следующий код. Он должен быть сохранён в той же папке, где вы создали виртуальное окружение (в нашем случае Desktop/dht_test).

# Complete Project Details: https://RandomNerdTutorials.com/raspberry-pi-temperature-humidity-data-logger/

import adafruit_dht
import board
import time
import os

# Sensor data pin is connected to GPIO 4
sensor = adafruit_dht.DHT22(board.D4)
# Uncomment for DHT11
#sensor = adafruit_dht.DHT11(board.D4)

# create a variable to control the while loop
running = True

# Check if the file exists before opening it in 'a' mode (append mode)
file_exists = os.path.isfile('sensor_readings.txt')
file = open('sensor_readings.txt', 'a')

# Write the header to the file if the file does not exist
if not file_exists:
    file.write('Time and Date, temperature (ºC), temperature (ºF), humidity (%)\n')

# loop forever
while running:
    try:
        # read the humidity and temperature
        temperature_c = sensor.temperature
        temperature_f = temperature_c * (9 / 5) + 32
        humidity = sensor.humidity

        #print readings on the shell
        print("Temp={0:0.1f}ºC, Temp={1:0.1f}ºF, Humidity={2:0.1f}%".format(temperature_c, temperature_f, humidity))

        # save time, date, temperature, and humidity in .txt file
        file.write(time.strftime('%H:%M:%S %d/%m/%Y') + ', {:.2f}, {:.2f}, {:.2f}\n'.format(temperature_c, temperature_f, humidity))

        # log new readings every 10 seconds
        time.sleep(10)

    except RuntimeError as error:
        # Errors happen fairly often, DHT's are hard to read, just keep going
        print(error.args[0])
        time.sleep(2.0)
        continue

    except KeyboardInterrupt:
        print('Program stopped')
        running = False
        file.close()

    except Exception as e:
        print('An unexpected error occurred:', str(e))
        running = False
        file.close()
        sensor.exit()

Посмотреть исходный код

Как работает код

Вот краткое описание того, что делает код:

  • он сохраняет показания датчика и соответствующую метку времени в файл с именем sensor_readings.txt.

  • но сначала он проверяет, существует ли уже файл с именем sensor_readings.txt (это нужно для предотвращения многократной записи заголовка файла при перезапуске или остановке/запуске программы).

  • если файл не существует, он создаст новый файл.

  • есть бесконечный цикл, в котором вы получаете показания температуры и влажности и записываете их в файл с соответствующей меткой времени.

  • программа продолжает работать и записывать в файл, пока вы не остановите программу прерыванием с клавиатуры или пока программа не остановится по какой-либо другой причине. В этом случае мы закрываем файл.

Продолжайте читать для более подробного объяснения кода или перейдите к разделу демонстрации.

Код очень похож на тот, что в :doc:`этом руководстве </raspberry/rnt/raspberry-pi-dht11-dht22-python/index>`_ (но добавляет несколько строк для регистрации данных).

Импорт необходимых библиотек

Сначала вам нужно импортировать необходимые библиотеки. adafruit_dht — для получения показаний с датчика DHT, модуль board — для взаимодействия с GPIO, модуль time — для получения меток времени и добавления задержек в ваш код, и модуль os, который позволит нам взаимодействовать с операционной системой (в нашем случае нам нужно проверить, существует ли уже файл в файловой системе).

import adafruit_dht
import board
import time
import os

Датчик DHT

В следующей строке мы инициализируем наш датчик DHT. Мы используем DHT22, подключённый к GPIO 4 (вы можете использовать любой другой подходящий GPIO, если измените код в следующей строке):

# Sensor data pin is connected to GPIO 4
sensor = adafruit_dht.DHT22(board.D4)

Если вы используете DHT11, это должно выглядеть так:

sensor = adafruit_dht.DHT11(board.D4)

С этого момента мы будем обращаться к нашему датчику DHT как sensor в нашем коде.

Работа с файлами

Следующая строка проверяет, существует ли уже файл с именем sensor_readings.txt (он будет искать в пути папки проекта). Если файл уже существует, переменная file_exists будет True. В противном случае она будет False.

file_exists = os.path.isfile('sensor_readings.txt')

Затем он открывает файл в режиме 'a' (добавление). Если файл ещё не существует, он автоматически создаст файл перед его открытием.

file = open('sensor_readings.txt', 'a')

При использовании функции open() вы можете указать различные режимы для управления тем, как файл открывается и используется. При записи в файл наиболее популярными методами являются 'w' (запись) и 'a' (добавление).

Режим записи (Write) и режим добавления (Append): режим записи открывает файл для записи и очищает файл, если он уже существует. Режим добавления открывает файл для записи и добавляет новые данные в конец файла. Если вы хотите вести учёт своих показаний с течением времени, лучший режим — добавление, чтобы вы могли сохранить все предыдущие данные.

Если файл ещё не существует, код записывает строку заголовка в файл, содержащую имена столбцов. Мы сохраним сначала дату и время, затем температуру в Цельсиях и Фаренгейтах, и наконец влажность.

if not file_exists:
    file.write('Time and Date, temperature (ºC), temperature (ºF), humidity (%)\n')

Получение показаний датчика и регистрация данных

Далее у нас есть цикл while, который всегда выполняется, пока переменная running равна True. Мы установили эту переменную в True в начале кода. Переменная running изменится на False, когда выполнение программы будет остановлено прерыванием с клавиатуры или при возникновении непредвиденной ошибки.

while running:
    try:

Внутри цикла блок try пытается прочитать влажность и температуру с датчика DHT и сохраняет показания в переменных humidity и temperature_c. Мы также преобразуем температуру в Фаренгейты.

temperature_c = sensor.temperature
temperature_f = temperature_c * (9 / 5) + 32
humidity = sensor.humidity

Все показания выводятся в терминал.

print("Temp={0:0.1f}ºC, Temp={1:0.1f}ºF, Humidity={2:0.1f}%".format(temperature_c, temperature_f, humidity))

Затем мы используем функцию write() объекта файла для записи данных в файл. Мы записываем метку времени, температуру в Цельсиях, температуру в Фаренгейтах и влажность.

file.write(time.strftime('%H:%M:%S %d/%m/%Y') + ', {:.2f}, {:.2f}, {:.2f}\n'.format(temperature_c, temperature_f, humidity))

Для получения метки времени мы используем time.strftime("%H:%M:%S %d/%m/%Y") — аргумент в скобках указывает формат, в котором должны отображаться время и дата: часы, минуты, секунды, день, месяц и год соответственно.

Этот скрипт считывает и записывает температуру и влажность каждые 10 секунд, но вы можете изменить это, изменив время задержки. Датчик способен снимать показания каждые 2 секунды, но не быстрее.

time.sleep(10)

Обработка прерываний и исключений

В случае ошибки чтения с датчика DHT мы выводим сообщение об ошибке, делаем паузу на две секунды и используем оператор continue для перехода к следующей итерации блока try.

except RuntimeError as error:
    # Errors happen fairly often, DHT's are hard to read, just keep going
    print(error.args[0])
    time.sleep(2.0)
    continue

Если вы прервёте программу, нажав Ctrl + C, код перехватит исключение KeyboardInterrupt, выведет сообщение о завершении программы, а затем закроет файл перед установкой running в False для выхода из цикла.

except KeyboardInterrupt:
    print('Program stopped')
    running = False
    file.close()

Важно: вам необходимо вызвать file.close(), чтобы все данные были записаны в файл.

Аналогично мы поступаем при возникновении любой другой ошибки или исключения.

except Exception as e:
    print('An unexpected error occurred:', str(e))
    running = False
    file.close()

Демонстрация

Сохраните ваш файл Python в том же каталоге, где находится ваше виртуальное окружение. Затем запустите его на вашем Raspberry Pi. Выполните следующую команду (в том же пути виртуального окружения):

python dht-datalogger.py

Вы начнёте получать новые показания температуры и влажности в окне терминала, и в папке вашего проекта будет создан новый файл с именем sensor_readings.txt. Если вы используете VS Code, вы увидите вновь созданный файл в проводнике файлов (пока не открывайте его).

Регистратор данных Raspberry Pi в VS Code

Позвольте коду поработать некоторое время, чтобы он собрал значительное количество данных. Затем остановите выполнение кода, нажав CTRL+C.

Регистратор данных DHT Raspberry Pi — прерывание с клавиатуры

Теперь вы можете открыть файл sensor_readings.txt и увидеть все собранные данные. Вы можете запустить программу снова, чтобы собрать больше данных, и она не перезапишет предыдущие данные.

Показания датчика — регистратор данных Raspberry Pi в VS Code

Если вы используете PuTTY, перейдите в папку вашего проекта. Перечислите все файлы внутри папки проекта с помощью команды ls и обратите внимание, что файл с именем sensor_readings.txt присутствует в списке.

Регистратор данных Raspberry Pi — список файлов в PuTTY

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

cat sensor_readings.txt

Затем вы увидите все данные, собранные вашим датчиком, с соответствующими метками времени.

Файл txt регистратора данных Raspberry Pi в PuTTY

Заключение

В этом проекте вы изучили очень полезную концепцию: регистрацию данных. Теперь вы можете использовать регистрацию данных в других проектах мониторинга. Вот несколько идей:

Надеемся, вы нашли это руководство полезным. Если вы совсем недавно начали работать с Raspberry Pi, ознакомьтесь со следующими руководствами:

Вы можете ознакомиться со всеми нашими проектами для Raspberry Pi по следующей ссылке: