Продолжим серию статей про ПАК «Рудирон» и его программирование. Сегодня мы осветим тему использования библиотек при создании своего программного обеспечения.
Библиотеки являются мощным инструментом при работе с проектами. Особенно когда используются внешние модули, подключенные к Рудирону. Библиотека – файл или набор файлов, к котором используется такой же код по синтаксису, как и в основном тексте программы. Можно подключить библиотеку в свой код и использовать тот функционал, который она нам в этом случае предоставляет, а вариантов там может быть очень много: готовые функции высокого уровня для работы с внешними датчиками, различными модулями, экранами и т.п., для работы с внутренней периферией микроконтроллера (часы, таймеры, АЦП), библиотеки различных математических функций и многое другое, всего и не перечислить. Для опытного программиста это способ сократить время разработки программы, а для начинающего – готовые рабочие примеры работы с внешней периферией.
Преимущество работы с библиотекой заключается в том, что нам необязательно знать, как функционирует устройство на низком уровне и как работает код, который обеспечивает эти функции, мы просто пользуемся готовыми функциями, которые предоставляет разработчик этой библиотеки. Ко многим библиотекам есть описание/документация и примеры использования, на базе которых можно понять, как использовать данную библиотеку.
Шаблоны и примеры проектов ПАК Рудирон размещены в репозитории: https://gitflic.ru/project/akvarius-rudiron/rudiron-projects

Как установить библиотеку
Библиотека представляет из себя набор текстовых файлов с кодом. В настоящее время библиотеку можно установить вручную, скачав архив необходимых библиотек из репозитория библиотек ПАК Рудирон. Исходный код библиотек для внешних модулей размещен в репозитории: https://gitflic.ru/project/akvarius-rudiron/rudiron-libraries
Архивы библиотек можно скачать по адресу https://gitflic.ru/project/akvarius-rudiron/rudiron-libraries/release?sort=TIME&direction=DESC

Ручная установка библиотеки подразумевает собой перемещение распакованной из архива папки с библиотекой в каталог, в котором VS Studio Code или Arduino IDE будут эту библиотеку искать.
Тут возможны два варианта размещения папки с библиотекой, все зависит от того как эту библиотеку планируется использовать:
1. Библиотека будет использована только в этом проекте и не планируется эту библиотеку использовать в других проектах. Ну, или как другой вариант – эту библиотеку планируется изменять или отлаживать. В этом случае удобнее размещать ее:
- В случае использования VS Code в каталоге “libraries” проекта с обязательным добавлением названия библиотеки (названия каталога в котором хранится библиотека, если исходные файлы библиотеки хранятся в каталоге “src”, то он не указывается) в файл “libraries_local.txt”, находящийся в корне проекта.
- В случае использования Arduino IDE разместить файлы в корневом каталоге проекта (без подкаталогов)
2. Библиотека работает и будет использована в ряде других проектов. Изначально все библиотеки внешних устройств, включенных в состав ядра ПАК Рудирон находятся в каталоге:
- для Windows «C:\Users\”имя_профиля”\AppData\Local\Arduino15\packages\Rudiron\hardware\MDR32F9Qx\”номер версии ядра”\libraries»
- для Linux «/”имя_профиля”/.arduino15/Rudiron/hardware/MDR32F9Qx/”номер версии ядра”/libraries»
Данный путь используется при сборке проекта и рабочий вариант библиотеки для многих проектов необходимо размещать именно там. В данном каталоге создается подкаталог с именем библиотеки и исходные файлы необходимо разместить в данном подкаталоге (допустимо использовать подкаталог “src” внутри, но необходимо будет учесть его при написании названия библиотеки в файле описания библиотек проекта). Файлы примеров (если они есть) можно разместить в подкаталоге “examples” внутри каталога библиотеки. Такое расположение каталогов и файлов позволит использовать примеры напрямую из среды разработки Arduino IDE, они становятся доступны к загрузке напрямую из оболочки Arduino IDE

При использовании VisualStudioCode не забываем прописать название каталога библиотеки в файл “libraries.txt”, находящийся в корне проекта. Если исходные файлы библиотеки находятся внутри подкаталога “src”, то не забываем в файле “libraries.txt” к названию каталога библиотеки добавить “/src”.
Классическое содержание библиотеки
Библиотека, в зависимости от кода, наличия времени и настроения программиста, может быть очень компактной, так и объемной, с различными дополнительными файлами и папками. В качестве примера рассмотрим состав библиотеки U8g2lib.

Все перечисленные ниже файлы являются обычными текстовыми файлами, открыть их можно даже обычным блокнотом. Рекомендуется использовать для Windows Notepad++ или файловый менеджер FAR (для Линукса – файловый менеджер MC), данные программы умеют подсвечивать синтаксис и в целом являются очень удобным инструментом разработчика. Еще один вариант – открыть эти файлы в среде разработки, например в Visual Studio Code.
Файл название_библиотеки.h - заголовочный файл, самый главный файл библиотеки. В принципе библиотека может состоять только из него одного, но правилом хорошего стиля программирования является оформления заголовочного файла и файла с методами реализации. Находится обычно в корне библиотеки, либо в папке src (от английского source, исходник). В этом файле обычно перечислены все классы/методы/функции/типы данных, размещена информация о библиотеке, встречается расширенное описание для каждого метода или функции. Часто заголовочный файл фактически является и документацией на библиотеку.
Файл с расширением .cpp - файл методов реализации, в котором находится основной исполнительный код программы. Обычно идёт парным к своему заголовочному .h файлу, т.е. имеет название “название_библиотеки.cpp”.
В принципе вышеперечисленные файлы уже являются самодостаточной библиотекой для применения в проектах. Остальные файлы и каталоги необязательны и могут отсутствовать.
Файл keywords.txt - файл, в котором перечислены названия функций, методов и прочих рабочих названий библиотеки.
Файл library.properties содержит информацию о библиотеке для менеджера библиотек (название, версия, автор, категория и проч.)
Каталог src - в этом каталоге могут находиться основные файлы библиотеки (.h, .cpp, .c). Но вполне допустимо, что основные файлы библиотеки будут находится в коневом каталоге самой библиотеки.
Каталог examples - каталог с примерами использования библиотеки.
Помимо перечисленных файлов и каталогов в каталоге с библиотекой могут находиться и другие служебные файлы и каталоги, иногда встречается документации в виде текстовых файлов или html страниц. Очень часто там размещают файлы с расширением .md, данные файлы необходимы для описания при размещении в репозитарии и при сборке проекта не используются.
Как работать с библиотеками внешних модулей:
1. Для модулей входящих в составы наборов с ПАК Рудирон имеются встроенные в ядро библиотеки. Необходимо их использовать.
Важное замечание: ПАК Рудирон не является аналогом Ардуино и сторонние внешние библиотеки, написанные под Ардуино необходимо дорабатывать. О возможностях написания собственных библиотек и доработке сторонних библиотек будут размещены дополнительные материалы.
2. Прочитали методические указания по работе с ПАК Рудирон, нашли статью с примером. Примеры обычно бывают простые, они показывают, как подключается и работает модуль. Загрузили пример из проектов, постарались разобраться, как он работает. Если есть примеры в каталоге “examples” в библиотекой, то рассмотрели и их работу.
3. Примеры обычно не раскрывают всех возможностей библиотеки, поэтому смотрим заголовочный файл, который называется “название_библиотеки.h”. В нем можно найти список доступных функций библиотеки (не забываем, что нам для вызова доступны только публичные функции), очень часто с описанием для каждой функции.
4. На основе изученной информации попробовали создать свой проект, можно в качестве основы брать проект из примеров для ПАК Рудирон.
В качестве примера давайте рассмотрим библиотеку rtc.h, это одна из первых библиотек расширяющих возможности ПАК Рудирон.
Работа с часами реального времени (библиотека Rudiron_RTClib)
В Рудироне, как в практически любом устройстве, есть модуль, на основе которого можно запустить измерение времени. Этот модуль называется часами реального времени (сокращенно ЧРВ или RTC). На этом уроке вы узнаете как их запустить, как считать из них текущее время или записать в них новое.
Часы реального времени в микроконтроллере Рудирона представляют собой счетчик, который увеличивается на единицу после каждого поступившего в него импульса. Чтобы этот счетчик стал часами, нужно сделать так, чтобы на его вход поступали импульсы с частотой 1 Гц (1 импульс в секунду).

Рис. Часы реального времени в микроконтроллере
Счетчик этот является двоичным, т.е. разряды в нем могут принимать только значение 0 или 1, в отличие от привычных нам десятичных, где каждый разряд может быть цифрой от 0 до 9. Если в двоичном счетчике прибавить 1 к разряду, в котором уже есть единица, то этот разряд становится 0, а более старший увеличивается на 1.
Если мы настроим поступление на вход счетчика импульсов с нужной частотой и разрешим начать отсчет, то счетчик начнет увеличиваться с каждым импульсом независимо от того, чем занимается дальше наша программа. Она может что-то считать, обмениваться через порт данными с компьютером, управлять двигателями или моргать диодами. Счет времени уже идет сам собой.
Это может быть удобно для подсчета времени между двумя событиями, скажем нажатиями кнопок, выдачи в порт времени возникновения какого-либо события, подсчета общего времени работы программы и тому подобных вещей.
Исходное время в часах реального времени Рудирона подобно часам в Unix-системах. UNIX-время (POSIX-время) — система описания моментов во времени, принятая в UNIX и других POSIX-совместимых операционных системах. Определяется как количество секунд, прошедших с полуночи (00:00:00 UTC) 1 января 1970 года.
UNIX-время представлено целым числом, которое увеличивается с каждой прошедшей секундой без необходимости вычислений для определения года, месяца, дня, часа или минуты для удобства восприятия человеком. Современное UNIX-время согласуется с UTC — отсчет происходит в секундах СИ.
Важный момент, на который необходимо обратить внимание, т.к. Рудирон не оснащен батарейкой, в отличие, например от материнской платы компьютера, то любое отключение питания приведет к сбросу часов реального времени к 00:00:00 1 января 1970 года.
Установка библиотеки
Рассмотрим вариант установки библиотеки в каталог проекта:
1. Скачиваем архив библиотеки с репозитория https://gitflic.ru/project/akvarius-rudiron/rudiron-libraries/release?sort=TIME&direction=DESC

Прямая ссылка на архив библиотеки версии 1.0.1 https://gitflic.ru/project/akvarius-rudiron/rudiron-libraries/release/bc8417b3-fee7-410f-af8a-f79a006e6e3f/121cf70e-764b-4968-b81b-cce9c216e0a5/download
2. Распаковываем скачанный архив в зависимости от используемой среды разработки:
- Для Arduino IDE необходимо разместить распакованные файлы в корневой каталог проекта, никаких подкаталогов в этом случае создавать не надо.
- Для Visual Studio Code необходимо создать каталог “Rudiron_RTClib” в «..\корневой_каталог_проекта\libraries» и перенести распакованные файлы и папки в этот каталог. Откорректировать файл libraries_local.txt, находящийся в корневом каталоге проекта, добавив в него строку «Rudiron_RTClib» (без кавычек).
- Все примеры находящиеся в библиотеке Rudiron_RTClib включают в себя исходный код самой библиотеки и эти примеры можно использовать в качестве отдельного проекта без установки библиотеки.
Использование библиотеки
Для начала научимся устанавливать время в часах реального времени Рудирон.
Алгоритм работы достаточно прост. В разделе программы setup() инициализируем и запускаем часы. Изначально в переменную date_time присваивается значение "1970-01-01 00:00:00", данное значение приведено исключительно в качестве примера и не участвует в настройке часов реального времени. При каждом аппаратном запуске Рудирона часы будут сбрасываться на данное значение. Далее в основной части программы контроллер анализирует наличие данных в буфере порта UART и если данные есть, то считывает их и проверяет на соответствие формату «ГГГГ-MM-ДД ЧЧ:ММ:CC». Эти данные можно передать через монитор порта. Если данные соответствуют формату, то происходит корректировка значения часов реального времени, если нет, то в порт выдается предупреждение о неправильном формате введенных данных.
#include "Arduino.h"
#include "time.h"
#include "rtc.h" //Подключаем библиотеку часов
RTClock clk; //Создаем переменную типа RTClock
String date_time; //Переменная для приема данных через порт
time_t t; //Переменная, в которую будем записывать время события или текущее время
void setup() {
date_time="1970-01-01 00:00:00"; // Пример строки дата/время
Serial.begin(115200);
clk.init(); //Инициализируем часы реального времени (частота сигналов - 1 Гц, начальные показания - 0, не запущены)
clk.startClock(); //Запускаем часы
delay (5000); //Ставим большую задержку, чтобы успеть включить монитор порта
Serial.println("Жду ввода времени..."); //Выдаем в порт сообщение, что ждем ввода времени
Serial.println("Ввод даты и времени в формате: ГГГГ-MM-ДД ЧЧ:ММ:CC"); //Или ввода текущего времени
}
void loop() {
int bytes_to_receive = Serial.available(); //Проверяем, есть ли в буфере порта непринятые данные
if (bytes_to_receive > 0) { //Если есть
date_time = Serial.readString(); //Читаем строку и проверяем ее на соответствие формату ГГГГ-ММ-ДД ЧЧ:ММ:СС
if (clk.Str_toUNIX_TimeStamp(date_time.c_str(), &t)) { //Если получилось перевести полученную строку в дату и время
clk.writeTimeRTC(t); //Записываем показания в ЧРВ
Serial.println(date_time); // Выдаем введенное значение в порт t = clk.readTimeRTC(); //Считываем счетчик секунд из часов
Serial.println(clk.UNIX_TimeStamp_toStr(&t)); //Преобразовываем его в удобочитаемую строку и выдаем в порт
}
else { //Если формат строки, полученной через порт не соответствует нужному
Serial.println("Дата/время имеют неправильный формат! Изменения не внесены!"); //выдаем сообщение
}
}
}
Для примера попробуем написать программу подсчета секунд между нажатием кнопки B1 и B2. При этом условимся, что нажатие на кнопку B1 запускает счет времени, а нажатие на B2 останавливает счет, выдает информацию о прошедшем периоде времени и обнуляет счетчик часов.
Таким образом, алгоритм программы может выглядеть следующим образом:

Попробуем реализовать этот алгоритм на практике. Будет необходимо дописать несколько функций, которые позволяют совершать отдельные операции с часами: настраивать, считывать время, устанавливать время, запускать, останавливать, проверять состояние. Все функции с пояснениями можно увидеть в листинге:
#include "Arduino.h"
#include "rtc.h" //Подключаем библиотеку часов
RTClock clk; //Создаем переменную типа RTClock
void setup() {
Serial.begin(115200);
clk.init(); //Инициализируем часы реального времени (частота сигналов - 1 Гц, начальные показания - 0, не запущены)
pinMode(BUTTON_BUILTIN_1, INPUT_PULLDOWN); //конфигурируем кнопки
pinMode(BUTTON_BUILTIN_2, INPUT_PULLDOWN);
Serial.println("Жду нажатия кнопки B1..."); //Выдаем в порт сообщение, что ждем нажатия кнопки В1
clk.stopClock(); //Останавливаем часы
clk.writeTimeRTC(0); //Обнуляем счетчик часов
}
void loop() {
if (!clk.isClockRunning()) { //Проверяем работают ли часы
if (digitalRead(BUTTON_BUILTIN_1)) { //Если Нет, проверяем нажата ли кнопка В1
clk.startClock(); //Если Да включаем часы и выдаем сообщения в порт
Serial.println("B1 нажата!");
Serial.println("Жду нажатия кнопки B2...");
}
}
else { //Если часы работают
if (digitalRead(BUTTON_BUILTIN_2)){ //Проверяем нажата ли кнопка В2
clk.stopClock(); //Если Да, то останавливаем часы
Serial.println("B2 нажата!"); //Выдаем сообщения
Serial.print("Время между нажатиями "); Serial.print(clk.readTimeRTC()); Serial.println(" секунд");
clk.writeTimeRTC(0); //Обнуляем счетчик часов
Serial.println("Жду нажатия на кнопку B1..."); //Сообщаем, что снова ждем нажатия на B1
}
}
}
Результат работы программы:

В мониторе порта видны отметки времени. Разница между сообщениями от Рудирона о нажатиях по меткам времени чуть больше 7 секунд. При этом контроллер сообщает, что по его данным между нажатиями тоже прошло 7 секунд. Результаты практически совпадают, что говорит о том, что все работает правильно.
Конечно часы реального времени можно использовать не только как секундомер, но и множеством других способов. Например, интересным является вариант, когда с их помощью можно фиксировать дату и время каких-то событий.
Попробуем реализовать вариант, когда при нажатии любой из кнопок B1, B2 или B3, программа выдает в серийный порт сообщение о том, что нажата определенная кнопка, а также дату время этого события.
Прежде чем мы начнем, обратите внимание на то, что счетчик времени в часах сразу после включения питания Рудирона будет равен нулю. Таким образом, если без предварительной настройки часов, мы будем нажимать на кнопку, то увидим не текущую дату и время, а сколько секунд назад мы запустили часы. Чтобы корректные дату и время события, нужно занести в часы начальные показания – текущую дату и время. Сделать это будет можно из строчки ввода в мониторе порта.
Общий алгоритм работы программы может выглядеть так:

Листинг программы, которая реализует это алгоритм:
#include "Arduino.h"
#include "time.h"
#include "rtc.h" //Подключаем библиотеку часов
RTClock clk; //Создаем переменную типа RTClock
String date_time; //Переменная для прима данных через порт
time_t t; //Переменная, в которую будем записывать время события или текущее время
void setup() {
date_time="";
Serial.begin(115200);
clk.init(); //Инициализируем часы реального времени (частота сигналов - 1 Гц, начальные показания - 0, не запущены)
clk.startClock(); //Запускаем часы
pinMode(BUTTON_BUILTIN_1, INPUT_PULLDOWN); //конфигурируем кнопки
pinMode(BUTTON_BUILTIN_2, INPUT_PULLDOWN);
pinMode(BUTTON_BUILTIN_3, INPUT_PULLDOWN);
delay (5000); //Ставим большую задержку, чтобы успеть включить монитор порта
Serial.println("Жду ввода времени или нажатия на кнопку B1...B3"); //Выдаем в порт сообщение, что ждем нажатия кнопок
Serial.println("Ввод даты и времени делай в формате: ГГГГ-MM-ДД ЧЧ:ММ:CC"); //Или ввода текущего времени
}
void loop() {
if (digitalRead(BUTTON_BUILTIN_1)) { //Если Нет, проверяем нажата ли кнопка В1
Serial.print("B1 нажата! "); //Если Да выдаем сообщение в порт
Serial.print("Время события: ");
t = clk.readTimeRTC(); //Считываем счетчик секунд из часов
Serial.print(clk.UNIX_TimeStamp_toStr(&t)); //Преобразовываем его в удобочитаемую строку и выдаем в порт
}
if (digitalRead(BUTTON_BUILTIN_2)) { //Если Нет, проверяем нажата ли кнопка В1
Serial.print("B2 нажата! "); //Если Да выдаем сообщение в порт
Serial.print("Время события: ");
t = clk.readTimeRTC(); //Считываем счетчик секунд из часов
Serial.print(clk.UNIX_TimeStamp_toStr(&t)); //Преобразовываем его в удобочитаемую строку и выдаем в порт
}
if (digitalRead(BUTTON_BUILTIN_3)) { //Если Нет, проверяем нажата ли кнопка В1
Serial.print("B3 нажата! "); //Если Да выдаем сообщение в порт
Serial.print("Время события: ");
t = clk.readTimeRTC(); //Считываем счетчик секунд из часов
Serial.print(clk.UNIX_TimeStamp_toStr(&t)); //Преобразовываем его в удобочитаемую строку и выдаем в порт
}
int bytes_to_receive = Serial.available(); //Проверяем, есть ли в буфере порта непринятые данные
if (bytes_to_receive > 0) { //Если есть
date_time = Serial.readString(); //Читаем строку и проверяем ее на соответствие формату ГГГГ-ММ-ДД ЧЧ:ММ:СС
if (clk.Str_toUNIX_TimeStamp(date_time.c_str(), &t)) { //Если получилось перевести полученную строку в дату и время
clk.writeTimeRTC(t); //Записываем показания в ЧРВ
}
else { //Если формат строки, полученной через порт не соответствует нужному
Serial.println("Дата/время имеют неправильный формат! Изменения не внесены!"); //выдаем сообщение
}
}
}
Посмотрим как работает программа. Сразу после прошивки и запуска переключаемся в монитор порта и видим следующее:

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

Мы видим, что контроллер считает, что сейчас – 1 января 1970 года. Нужно исправить эту ситуацию, для чего запишем в часы текущие дату и время. Делать это нужно, записывая строку в определенном формате: ГГГГ-ММ-ДД ЧЧ:ММ:СС, где ГГГГ – 4 цифры года, MM – две цифры месяца (01..12), ДД – две цифры дня месяца (01..31), ЧЧ – текущий час (00..23) и т.д. И очень важно между этими данными не забывать ставить указанные в строке формата разделители (тире, пробел, двоеточие). Пример ввода данных в таком формате можно видеть на картинке:

Попробуем теперь нажать на какую-либо кнопку. Видим следующее:

Теперь программа выдает в порт правильное время. Если не поставим задержку хотя бы в 50-100 мс, то будет выдаваться несколько одинаковых надписей потому, что даже за то короткое время, пока мы нажимаем кнопку, контроллер успевает совершить полный цикл по программе несколько десятков раз.
Библиотека для работы с датчиком DHT11 (Rudiron_DHT11)
Библиотека Rudiron_DHT11 предназначена для работы с датчиком температуры и влажности DHT11 на платах Rudiron. Она обеспечивает простой интерфейс для чтения данных, обрабатывая сложный однопроводной протокол связи и проверку контрольной суммы.
Описание библиотеки
Rudiron_DHT11 позволяет легко считывать температуру (в °C) и влажность (в %) с датчика DHT11. Библиотека управляет низкоуровневой связью, включая отправку стартового сигнала, чтение 40-битных данных и проверку их целостности. Она подходит для проектов, требующих мониторинга окружающей среды, таких как метеостанции, системы управления климатом или умный дом.
Особенности:
- Простота использования - настройка пина и чтение данных в несколько строк кода.
- Надёжность - проверка контрольной суммы исключает некорректные данные.
- Лёгкость - минимальное потребление памяти.
Текущая версия библиотеки: 1.0
Установка
Используем вариант установки библиотеки в каталог проекта:
3. Скачиваем архив библиотеки с репозитория https://gitflic.ru/project/akvarius-rudiron/rudiron-libraries/release?sort=TIME&direction=DESC

Прямая ссылка на архив библиотеки версии 1.0 https://gitflic.ru/project/akvarius-rudiron/rudiron-libraries/release/4639971e-5f6d-48ea-a17b-8cd6a14392f8
4. Распаковываем скачанный архив в зависимости от используемой среды разработки:
- Для Arduino IDE необходимо разместить распакованные файлы в корневой каталог проекта, никаких подкаталогов в этом случае создавать не надо.
- Для Visual Studio Code необходимо создать каталог “Rudiron_DHT11lib” в «..\корневой_каталог_проекта\libraries» и перенести распакованные файлы в этот каталог. Откорректировать файл libraries_local.txt, находящийся в корневом каталоге проекта, добавив в него строку «Rudiron_DHT11lib» (без кавычек).
Все примеры находящиеся в библиотеке Rudiron_DHT11lib включают в себя исходный код самой библиотеки и эти примеры можно использовать в качестве отдельного проекта без установки библиотеки.
Аппаратные требования
Датчик DHT11, подключённый к цифровому пину. Может потребоваться подтягивающий резистор 4.7–10 кОм между пином данных и VCC.
Схема подключения

Содержимое библиотеки
Библиотека предоставляет класс Rudiron_DHT11 с конструктором и четырьмя публичными методами для работы с датчиком.
Конструктор Rudiron_DHT11()
Описание: Создаёт объект для работы с датчиком DHT11.
Особенности: Инициализирует внутренний массив данных нулями, чтобы избежать неопределённых значений. Не требует параметров; пин настраивается позже через attach().
Пример: Rudiron_DHT11 dht;
Методы
void attach(uint8_t pin)
Описание: Задаёт цифровой пин для связи с датчиком.
Параметры: pin - номер цифрового пина (например, 2).
Особенности: Пин должен поддерживать вход и выход (большинство цифровых пинов). Не выполняет проверку на корректность пина, так как это зависит от аппаратной платформы.
Пример: dht.attach(2); // Подключение к пину 2
bool read()
Описание: Считывает данные с датчика DHT11, выполняя полный цикл протокола связи.
Возвращает: true при успешном чтении и проверке данных, false при ошибке (таймаут, сбой контрольной суммы).
Особенности: Отправляет стартовый сигнал (18 мс низкий, 20–40 мкс высокий). Считывает 40 бит (5 байт): влажность (2 байта), температура (2 байта), контрольная сумма (1 байт). Проверяет контрольную сумму для обеспечения целостности данных. Таймауты (100 мкс) предотвращают зависание при отсутствии ответа датчика.
Пример:
if (dht.read()) {
// Данные успешно считаны
}
float getHumidity() const
Описание: Возвращает значение влажности из последнего успешного чтения.
Возвращает: Влажность в процентах как число с плавающей точкой (например, 45.0).
Особенности: Объединяет целую (_data[0]) и дробную (_data[1]) части влажности. Для DHT11 дробная часть всегда 0, но метод возвращает float для совместимости с другими датчиками. Не вызывает чтение датчика; используйте read() перед вызовом.
Пример:
float humidity = dht.getHumidity(); // Например, 45.0
float getTemperature() const
Описание: Возвращает значение температуры из последнего успешного чтения.
Возвращает: Температура в градусах Цельсия как число с плавающей точкой (например, 23.0).
Особенности: Объединяет целую (_data[2]) и дробную (_data[3]) части температуры. Как и в getHumidity(), дробная часть для DHT11 равна 0. Требует предварительного вызова read().
Пример:
float temperature = dht.getTemperature(); // Например, 23.0
Примеры использования
Библиотека включает три примера скетчей в папке examples, демонстрирующих базовое использование. Все примеры используют пин 2 для подключения DHT11 и выводят данные в Serial Monitor (Скорость 9600 бод).
ReadHumidity.ino
Описание: Считывает влажность с датчика каждые 2 секунды и выводит её в Serial Monitor.
Код:
#include "Rudiron_DHT11.h"
Rudiron_DHT11 dht;
void setup() {
Serial.begin(9600);
while (!Serial);
dht.attach(2);
Serial.println("Чтение влажности с DHT11...");
}
void loop() {
if (dht.read()) {
Serial.print("Влажность: ");
Serial.print(dht.getHumidity(), 1);
Serial.println(" %");
} else {
Serial.println("Ошибка чтения данных с DHT11!");
}
delay(2000);
}
Особенности: Показывает, как использовать read() и getHumidity(). Выводит влажность с одним знаком после запятой для компактности. Интервал 2 секунды соответствует минимальной частоте опроса DHT11.
Применение: Мониторинг влажности в теплицах, складах или жилых помещениях.
ReadTemperature.ino
Описание: Считывает температуру каждые 2 секунды и выводит её в Serial Monitor.
Код: Аналогичен ReadHumidity.ino, но использует getTemperature() и выводит температуру в °C.
Особенности: Демонстрирует работу с температурой. Формат вывода удобен для чтения (например, “Температура: 23.0 °C”). Простая структура, подходящая для начинающих.
Применение: Температурный контроль в метеостанциях или системах умного дома.
ReadTemperatureAndHumidity.ino
Описание: Считывает и отображает одновременно температуру и влажность каждые 2 секунды.
Код:
#include "Rudiron_DHT11.h"
Rudiron_DHT11 dht;
void setup() {
Serial.begin(9600);
while (!Serial);
dht.attach(2);
Serial.println("Чтение температуры и влажности с DHT11...");
}
void loop() {
if (dht.read()) {
Serial.print("Влажность: ");
Serial.print(dht.getHumidity(), 1);
Serial.print(" %\t");
Serial.print("Температура: ");
Serial.print(dht.getTemperature(), 1);
Serial.println(" °C");
} else {
Serial.println("Ошибка чтения данных с DHT11!");
}
delay(2000);
}
Особенности: Комбинирует вызовы getHumidity() и getTemperature() в одном цикле. Выводит данные в одной строке с табуляцией для удобства чтения. Полезен для приложений, требующих оба параметра.
Применение: Комплексный мониторинг окружающей среды (например, в климат-контроле).
Инструкции для примеров:
- Подключите пин данных DHT11 к пину 2.
- Загрузите скетч через среду разработки.
- Откройте программу «Монитор порта».
- Наблюдайте за показаниями или сообщениями об ошибках.
Библиотека для работы с модулем DS1302 (Rudiron_DHT11)
Библиотека Rudiron_DHT11 предназначена для работы с датчиком температуры и влажности DHT11 на платах Rudiron. Она обеспечивает простой интерфейс для чтения данных, обрабатывая сложный однопроводной протокол связи и проверку контрольной суммы.
Библиотека Rudiron_DS1302 предназначена для работы с модулем реального времени DS1302 на платах Rudiron. Она предоставляет простой интерфейс для чтения и установки даты и времени, обрабатывая низкоуровневую связь и преобразование данных в формате BCD.
Описание библиотеки
Rudiron_DS1302 упрощает взаимодействие с модулем реального времени DS1302, который отсчитывает дату (год, месяц, день, день недели) и время (часы, минуты, секунды). Библиотека управляет трехпроводным интерфейсом (CE, SCLK, IO), преобразует данные между десятичным и BCD форматами и поддерживает операции остановки/запуска часов. Она подходит для проектов, требующих точного времени, таких как таймеры, логгеры данных или часы.
Особенности:
Простота использования: настройка пинов и доступ к данным в несколько строк кода.
Надёжность: управление защитой записи и корректная обработка данных.
Лёгкость: минимальное потребление ресурсов.
Версия: 1.0
Установка
Используем вариант установки библиотеки в каталог проекта:
5. Скачиваем архив библиотеки с репозитория https://gitflic.ru/project/akvarius-rudiron/rudiron-libraries/release?sort=TIME&direction=DESC

Прямая ссылка на архив библиотеки версии 1.0 https://gitflic.ru/project/akvarius-rudiron/rudiron-libraries/release/0b194fc3-53d6-4ca3-8191-bb655e6ddacc
6. Распаковываем скачанный архив в зависимости от используемой среды разработки:
- Для Arduino IDE необходимо разместить распакованные файлы в корневой каталог проекта, никаких подкаталогов в этом случае создавать не надо.
- Для Visual Studio Code необходимо создать каталог “ Rudiron_DS1302lib” в «..\корневой_каталог_проекта\libraries» и перенести распакованные файлы в этот каталог. Откорректировать файл libraries_local.txt, находящийся в корневом каталоге проекта, добавив в него строку «Rudiron_DS1302lib» (без кавычек).
Все примеры находящиеся в библиотеке Rudiron_DHT11lib включают в себя исходный код самой библиотеки и эти примеры можно использовать в качестве отдельного проекта без установки библиотеки.
Аппаратные требования: Модуль DS1302, подключённый к трём цифровым пинам (CE, SCLK, IO). Требуется резервная батарея (обычно CR2032) для сохранения времени при отключении питания.
Схема подключения

Содержимое библиотеки
Библиотека предоставляет класс Rudiron_DS1302 с конструктором и пятью публичными методами для работы с модулем. Также включает структуру RudironDateTime для хранения даты и времени, и перечисления MONTH и DOW для удобного задания месяцев и дней недели.
Конструктор Rudiron_DS1302()
Описание: Создаёт объект для работы с модулем DS1302.
Особенности: Инициализирует пины как неподключённые (0) и пин IO в режиме ввода. Не требует параметров; пины задаются через attach().
Пример: Rudiron_DS1302 rtc;
Методы
void attach(uint8_t pin_ce, uint8_t pin_sclk, uint8_t pin_io)
Описание: Настраивает пины для связи с модулем DS1302.
Параметры:
pin_ce: Пин Chip Enable (CE/RST).
pin_sclk: Пин Serial Clock (SCLK/CLK).
pin_io: Пин Input/Output (IO/DAT).
Особенности: Конфигурирует пины как выходы (CE, SCLK) или вход/выход (IO). Автоматически запускает осциллятор (метод start()).
Пины должны поддерживать цифровой ввод/вывод.
Пример:
rtc.attach(0, 1, 2); // CE/RST=0, SCLK/CLK=1, IO/DAT=2
bool isHalted()
Описание: Проверяет, остановлен ли осциллятор DS1302.
Возвращает: true, если осциллятор остановлен, false, если работает.
Особенности: Читает бит остановки в регистре секунд (бит 7). Возвращает false, если пины не назначены. Полезно для диагностики состояния модуля.
Пример:
if (rtc.isHalted()) {
// Осциллятор остановлен
}
void halt()
Описание: Останавливает осциллятор DS1302, приостанавливая отсчёт времени.
Особенности: Устанавливает бит остановки в регистре секунд. Сохраняет текущие данные в регистрах. Требует вызова start() для возобновления работы.
Пример: rtc.halt(); // Остановить часы
void start()
Описание: Запускает осциллятор DS1302, возобновляя отсчёт времени.
Особенности: Сбрасывает бит остановки в регистре секунд. Вызывается автоматически в attach() и после setDateTime(). Ничего не делает, если пины не назначены.
Пример:
rtc.start(); // Запустить часы
void getDateTime(RudironDateTime& dt)
Описание: Получает текущие дату и время из модуля.
Параметры: dt - ссылка на структуру RudironDateTime для хранения данных.
Особенности: Использует режим пакетного чтения (burst mode) для получения всех регистров. Преобразует данные из BCD в десятичный формат. Заполняет поля структуры: year (0-99, т.е. 2000-2099), month (1-12), day (1-31), hour (0-23), minute (0-59), second (0-59), dow (1-7). Ничего не делает, если пины не назначены.
Пример:
RudironDateTime dt;
rtc.getDateTime(dt);
void setDateTime(const RudironDateTime& dt)
Описание: Устанавливает дату и время в модуле.
Параметры: dt - константная ссылка на структуру RudironDateTime с новыми значениями.
Особенности: Отключает защиту записи перед операцией. Использует пакетный режим записи. Применяет модуль для ограничения значений (например, second % 60). Преобразует данные в BCD формат. Автоматически запускает осциллятор после установки.
Пример:
RudironDateTime dt = {25, MONTH_APR, 1, 12, 0, 0, DOW_TUE};
rtc.setDateTime(dt);
Примеры использования
Библиотека включает два примера скетчей в папке examples, демонстрирующих базовое использование. Оба примера используют пины CE=0, SCLK=1, IO=2 и выводят данные в Serial Monitor (скорость 9600 бод).
ReadDateTime.ino
Описание: Считывает текущую дату и время с модуля DS1302 каждые 2 секунды и выводит их в Serial Monitor в формате ГГГГ-ММ-ДД ЧЧ:ММ:СС.
Код:
#include <Rudiron_DS1302.h>
Rudiron_DS1302 rtc;
void setup() {
Serial.begin(9600);
while (!Serial);
rtc.attach(0, 1, 2);
Serial.println("Чтение даты и времени с DS1302...");
}
void loop() {
RudironDateTime dt;
rtc.getDateTime(dt);
Serial.print("Дата и время: ");
Serial.print(dt.year + 2000);
Serial.print("-");
if (dt.month < 10) Serial.print("0");
Serial.print(dt.month);
Serial.print("-");
if (dt.day < 10) Serial.print("0");
Serial.print(dt.day);
Serial.print(" ");
if (dt.hour < 10) Serial.print("0");
Serial.print(dt.hour);
Serial.print(":");
if (dt.minute < 10) Serial.print("0");
Serial.print(dt.minute);
Serial.print(":");
if (dt.second < 10) Serial.print("0");
Serial.println(dt.second);
delay(2000);
}
Особенности: Показывает, как использовать getDateTime() для получения данных. Форматирует вывод с ведущими нулями для удобства чтения. Подходит для проверки работы модуля без предварительной настройки времени.
Применение: Отображение времени в часах, логгерах или таймерах.
SetAndReadDateTime.ino
Описание: Устанавливает конкретную дату и время (например, 2025-04-01 12:00:00, вторник), затем считывает и отображает их каждые 2 секунды в Serial Monitor.
Код:
#include <Rudiron_DS1302.h>
Rudiron_DS1302 rtc;
void setup() {
Serial.begin(9600);
while (!Serial);
rtc.attach(0, 1, 2);
RudironDateTime dt;
dt.year = 25;
dt.month = MONTH_APR;
dt.day = 1;
dt.hour = 12;
dt.minute = 0;
dt.second = 0;
dt.dow = DOW_TUE;
rtc.setDateTime(dt);
Serial.println("Дата и время установлены. Чтение данных с DS1302...");
}
void loop() {
RudironDateTime dt;
rtc.getDateTime(dt);
Serial.print("Дата и время: ");
Serial.print(dt.year + 2000);
Serial.print("-");
if (dt.month < 10) Serial.print("0");
Serial.print(dt.month);
Serial.print("-");
if (dt.day < 10) Serial.print("0");
Serial.print(dt.day);
Serial.print(" ");
if (dt.hour < 10) Serial.print("0");
Serial.print(dt.hour);
Serial.print(":");
if (dt.minute < 10) Serial.print("0");
Serial.print(dt.minute);
Serial.print(":");
if (dt.second < 10) Serial.print("0");
Serial.println(dt.second);
delay(2000);
}
Особенности: Демонстрирует использование setDateTime() и getDateTime(). Использует перечисления MONTH и DOW для читаемости. Полезен для инициализации модуля с заданным временем.
Применение: Настройка часов или синхронизация времени в проектах.
Инструкции для примеров:
1. Подключите DS1302: CE/RST к пину 0, SCLK/CLK к пину 1, IO/DAT к пину 2.
2. Загрузите скетч при помощи среды разработки.
3. Откройте программу «Монитор порта» (скорость 9600 бод).
4. Наблюдайте за значениями даты и времени.
В статье рассмотрели вопросы связанные с использованием библиотек для ПАК "Рудирон". Теперь Вы знаете как можно с ними работать и создавать свои проекты на их основе.