Raspberry Pi и Pi4J. Урок 8. Работа с DHT11 и DHT22 из Java и C/C++

В этой статье подключим датчики DHT11 и DHT22 к Raspberry Pi, а точнее к Orange Pi PC, так как эта плата у меня есть. В принципе это не имеет значения, потому что ниже приведённые библиотеки и примеры запустятся и на Banana Pi, Odroid и NanoPi. Это что касается примеров на Java, использующие библиотеки Pi4J. А примеры на C/C++ можно запустить на все платы, на которые можно установить WiringPi.

Я раньше писал о популярных датчиках влажности и температуры DHT11 и DHT22 в статье Датчики температуры и влажности DHT11 и DHT22. Там же и документация по DHT11 и DHT22.

За основу использовалась библиотека от Adafruit — одна из стабильных версий, найденных мною в Интернете. Это Python библиотека для чтения данных с датчиков влажности и температуры DHT серии на Raspberry Pi и Beaglebone Black. Однако для чтения данных непосредственно с датчика используется язык программирования C, чтобы уменьшить вероятность ошибки во время чтения.

Библиотека C/C++

Изначально планировал сделать только на Java, так как это серия уроков по Pi4J, но решил сделать библиотеку и на C/C++, чтобы не писать отдельную статью.

DHTxx.h

init()

Инициализация GPIO и WiringPi.

read(float*, float*)

Считывает данные с датчика DHT, подключенного к выводу GPIO (с использованием нумерации WiringPi). Влажность и температура будут возвращены в заданных параметрах. Если чтение успешное, будет возвращено значение 0 (DHT_SUCCESS). Если при считывании данных произошла ошибка, возвращается отрицательное значение. Некоторые ошибки можно игнорировать и повторять чтение, в частности DHT_ERROR_TIMEOUT или DHT_ERROR_CHECKSUM.

busyWaitMilliseconds(uint32_t)

Приостанавливает работу потока, в котором она была вызвана, на указанное в аргументе время, загрузка процессора высокая, а точность высокая. Используйте этот метод только в течение короткого периода времени (не более нескольких сотен миллисекунд)!

sleepMilliseconds(uint32_t)

Приостанавливает работу потока, в котором она была вызвана, на указанное в аргументе время, загрузка процессора низкая, но точность потенциально плохая.

setMaxPriority()

Увеличивает приоритет планирования и алгоритм, чтобы попытаться получить результаты «реального времени» (SCHED_FIFO: планировщик FIFO (First In-First Out)).

setDefaultPriority();

Сбрасывает приоритет на нормальный/по умолчанию (SCHED_OTHER: стандартный алгоритм планировщика с разделением времени).

DHTxx.cpp

Подключение DHT11 к Orange Pi One

Чтобы проверить работоспособность приведённого выше года, я подключил DHT11 к Orange Pi PC, скомпилировал и запустил ниже приведённый пример. На схеме Orange Pi One, потому что не нашёл компонент Orange Pi PC в fritzing.

Схема подключения DHT11 к Orange Pi One

Лучше использовать подтягивающий резистор на 10 кОм, при подключении резистора номинала 4.7 к — датчик не заработал.

Схема подключения DHT11 к Orange Pi One

Пример программы на C/C++

main.cpp

Принцип работы примера

  1. Включаем файл DHTxx.h
  2. Объявляем переменные humidity и temperature для сохранения данных температуры и относительной влажности
  3. Создаём объект класса DHTxx. Первый параметр — это WiringPi пин, а второй — тип датчика
  4. Инициализируем датчик и продолжаем читать данные, если возвращаемый результат метода init() равен DHT_SUCCESS
  5. Создаём цикл и читаем данные при помощи метода int result = dht11.read(&humidity, &temperature);. Если возвращаемый результат метода read() в переменную result равен DHT_SUCCESS, тогда выводим температуру и влажность на экран. А если во время чтения возникла какая-то ошибка, тогда выводим на экран код ошибки.
  6. Минимальный интервал очередного чтения около двух секунд, я поставил 3.

Результат

Подключение DHT22 к Orange Pi One

Всё вышесказанное про DHT11 подойдёт и для DHT22. Единственное отличие только в том, что, при инициализации объекта класса DHTxx, второй параметр — это DHT22.

Схема подключения DHT22 к Orange Pi One

Схема подключения DHT22 к Orange Pi One

Пример программы на C/C++

main.cpp

Результат

Библиотека Java

С помощью инструмента Pi4J я перевёл C/C++ код на Java. Проблема Джавы в том, что при чтении данных с датчика очень часто возникают ошибки. Проблема может быть решена двумя костылями: первое — это использовать нативные методы и вызывать C/C++ функции с помощью JNI, что является более правильным решением; второе и самое простое — это запросить данные с датчика пока не получим правильный результат.

Если ещё не установили Pi4J на вашу плату перейдите на страницу Установка Pi4J на Raspberry Pi и Orange Pi, Banana Pi.

DhtData.java

Класс DhtData содержит информацию о влажности и температуре.

DHTxx.java

Интерфейс DHTxx — это абстракция устройств DHT. Он позволяет инициализировать GPIO/WiringPi и читать данные с DHT11/DHT22.

init()

Метод инициализирует GPIO/WiringPi, выбрасывает исключение, если это не удалось сделать.

getData()

Метод считывает и проверяет данные с датчика, а после возвращает эти данные в виде объекта класса DhtData. В случае ошибки выбрасывает исключение.

DHTxxBase.java

В абстрактном классе DHTxxBase реализованы методы: getPin(), setPin() и init(). Также добавлен метод getRawData(), именно здесь происходит чтение и преобразование данных с датчиков DHT11/DHT22. Эти методы являются общими для обоих датчиков.

DHTxxBase(Pin)

Конструктор класса DHTxxBase, как параметр получает номер пина по WiringPi, к которому подключён DHT датчик.

getRawData()

Метод считывает и преобразовывает данные с датчиков DHT11/DHT22. Возвращает массив из 5 байт, содержащий сведения о влажности, температуре и контрольной сумме. Выбрасывает исключение, если во время чтения возникла ошибка.

DHT11.java

DHT22.java

Классы DHT11 и DHT22 расширяют класс DHTxxBase, переопределён конструктор класса и реализован метод getData().

getData()

Метод getData() классов DHT11 и DHT22 почти одинаковые, отличаются лишь тем, как преобразовываются данные в градусах цельсия и процентах. Полученные данные возвращаются в виде объекта класс DhtData.

Из-за того, что очень часто при чтении возникают ошибки, функция пытается считывать данные из датчика до первой удачной попытки. Количество попыток ограничено 3.

Если не удалось получить результат, тогда выбрасывается исключение.

Проблема в том, Raspberry Pi/Orange Pi не работают в режиме реального времени, то есть, программные задержки не всегда точны и это приводит к ошибкам при считывании данных.

Работа с DHT11 из Java

Ниже приведён пример программы, которая 10 запрашивает данные с интервалом в 2 секунд и выводит результат в терминале. Для DHT11 нужно создать экземпляр класса DHT11.

Схема подключения DHT11 к Orange Pi One

Raspberry Pi и Pi4J. Урок 8. Схема подключения DHT11 к Orange Pi One

Пример программы на Java, DHT11Test.java

Результат

Работа с DHT22 из Java

Для работы с DHT22 создаём экземпляр класса DHT22, в остальном всё то же самое как и с DHT11.

Схема подключения DHT22 к Orange Pi One

Raspberry Pi и Pi4J. Урок 8. Схема подключения DHT22 к Orange Pi One

Пример программы на Java, DHT22Test.java

Результат

Проекты Eclipse

DHT11 — Eclipse C++
DHTxx — Eclipse Java

Материалы

Adafruit Python DHT Sensor Library
Датчики температуры и влажности DHT11 и DHT22
Проект OpenNet: MAN sched_setscheduler (2) Системные вызовы (FreeBSD и Linux)

Похожие записи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *