Проект 11. Часы
Устройство часы в представлении не требуется. Устройство показывает текущее время.
Описание работы:
Для начала работы подключите питание к Arduino. На индикаторе появится текущее время. Для настройки времени, нажмите любую кнопку, либо зеленую, либо красную. Уменьшится яркость индикатора, значит можно настраивать время. При нажатии или удержании зеленой кнопки будут увеличиваться минуты до 59. При нажатии или удержании красной кнопки будут уменьшаться минуты до 0. При достижении минут 59, увеличивается количество часов, а значение минут установится в 0. При достижении минут 0, уменьшится количество часов, а значение минут установится в 59. При достижении часов 23, значение часов сбросится в 0, а при достижении часов 0, значение часов установится в 23. После установки нужного времени, необходимо подождать две секунды. Тогда выбранное время сохранится, индикатор увеличит свою яркость, а время пойдет как прежде.
Нам понадобится:
- Arduino Uno х 1шт.
- Trema Set Shield х 1шт.
- Trema-модуль красная кнопка х 1шт.
- Trema-модуль зеленая кнопка х 1шт.
- Trema-модуль часы реального времени, RTC х 1шт.
- Trema-модуль четырехразрядный LED индикатор х 1шт.
Для реализации проекта нам необходимо установить следующие библиотеки:
О том как устанавливать библиотеки, Вы можете ознакомиться на странице Wiki — Установка библиотек в Arduino IDE .
Схема сборки:
- Устанавливаем Trema Set Shield в Arduino Uno.
- Устанавливаем Trema-модуль Четырехразрядный LED индикатор во 2 посадочную площадку.
- Устанавливаем Trema-модуль часы реального времени, RTC в 3 посадочную площадку, в верхнюю I2C колодку.
- Полученные результат представлен ниже на рисунке.
Код программы:
Алгоритм работы:
В начале скетча (до кода setup) выполняются следующие действия:
- Подключаем библиотеку iarduino_4LED для работы с Trema-модуль Четырехразрядным LED индикатором.
- Объявляем объект dispLED, с указанием выводов дисплея.
- Подключаем библиотеку iarduino_RTC для работы с Trema-модуль часами реального времени, RTC.
- Объявляем объект time для модуля на базе чипа DS3231.
- Объявляем пины для работы с Trema-модуль красной кнопкой и Trema-модуль зеленой кнопкой.
- Объявляем переменные и функции задействованные в скетче.
В коде setup выполняются следующие действия:
- Переводим выводы pinKeyGreen для зеленой кнопки и pinKeyRed для красной кнопки в режим выхода.
- Инициируем LED дисплей.
- Инициируем RTC модуль.
- Задаем событие 1.
В коде loop выполняются следующие действия:
- Читаем время, с модуля часов реального времени.
- Устанавливаем максимальную яркость свечения индикатора.
- Событию 1.
- Проверяем нажата зеленая или красная кнопка. Если одна из кнопок нажата, то сохраняем текущее значение времени в переменные времени и разрешаем переход к событию 2.
- Каждую секунду включаем и выключаем вторую точку на индикаторе. Для этого проверяем четность/нечетность приходящих секунд с модуля реального времени. Если нечетное, включаем вторую точку на индикаторе и гасим двоеточие на индикаторе, если оно присутствует на индикаторе. Если четное, то выводим на индикатор текущее время.
- Событие 2.
- Уменьшаем яркость свечения индикатора.
- Включаем вторую точку на индикаторе.
- Проверяем нажата зеленая кнопка. Если нажата, то заходим в цикл нажатия зеленой кнопки. Там фиксируем, как долго удерживается зеленая кнопка: если дольше 2 секунд , то увеличиваем быстро минуты и выводим изменение на индикатор. Как только кнопка отжата, увеличение прекратится. Если же нажата один раз зеленая кнопка, то увеличение минут произойдет один раз. Обнуляем переменную счета.
- Проверяем нажата красная кнопка. Если нажата, то заходим в цикл нажатия красной кнопки. Там фиксируем, как долго удерживается красная кнопка: если дольше 2 секунд , то уменьшаем быстро минуты и выводим изменение на индикатор. Как только кнопка отжата, уменьшение прекратится. Если же нажата один раз красная кнопка, то уменьшение минут произойдет один раз. Обнуляем переменную счета.
- Проверяем совершалось изменение минут. Если предыдущее значение минут совпадает с нынешним значением минут, то увеличиваем переменную счета, иначе обнуляем переменную счета.
- Если переменная счета больше 150, то разрешаем переход к событию 1. Обнуляем переменную счета.
- Сохраняем нынешнее значение минут в переменную предыдущего значения минут.
Arduino
Работа со временем
Функция millis()
Описание
Возвращает время в миллисекундах, прошедшее с начала выполнения программы на плате Arduino. Это число будет переполнено и сброситься до 0 примерно через 50 дней выполнения.
Синтаксис
Параметры
Возвращаемое значение
Количество миллисекунд, прошедших с момента запуска программы
Пример
Выводим значение, возвращаемое функцией millis() и ждем 1 секунду:
Функция micros()
Описание
Возвращает время в микросекундах, прошедшее с начала выполнения программы на плате Arduino. Это число будет переполнено и сброситься до 0 примерно через 70 минут выполнения.
Синтаксис
Параметры
Возвращаемое значение
Количество микросекунд, прошедших с момента запуска программы
Пример
Выводим значение, возвращаемое функцией micros() и ждем 1 секунду:
Примечания
На платах Arduino 16 МГц (например Uno и Nano) эта функция имеет разрешение в четыре микросекунды, поэтому значение всегда кратно четырем. На платах Arduino 8 МГц (например, LilyPad) эта функция имеет разрешение восемь микросекунд.
Функция delay()
Описание
Приостанавливает выполнение программы на заданноое время в миллисекундах.
Синтаксис
Параметры
ms — время в миллисекундах, на которое нужно приостановить программу
Возвращаемое значение
Пример
Мигаем встроенным светодиодом:
Примечания
Несмотря на то, что с помощью функции delay() легко создать мигающий светодиод и многие другие простые скетчи, использование функции имеет существенные недостатки. Во время приостановки программы невозможны любые манипуляции с пинами, например опрос датчиков. Также не будут работать многие математические функции. Поэтому рекомендуется в качестве альтернативы использовать функцию millis() .
Однако некоторые функции во вовремя выполнение delay() все же продолжают работать. Например, прерывания.
Функция delayMicroseconds()
Описание
Приостанавливает выполнение программы на заданное время в микросекундах.
Синтаксис
Параметры
us — время в микросекундах, на которое нужно приостановить программу
Возвращаемое значение
Пример
Посылаем последовательность импульсов с периодом раз в 100 микросекунд:
Функции времени
Задержки
Простейшей с точки зрения использования функцией времени является задержка: программа “зависает” внутри функции задержки и ожидает указанное время. Задержка позволяет очень удобно и наглядно организовать работу простой “однозадачной” программы, у нас есть два варианта задержек:
- delay(time)
- Задержка на указанное количество миллисекунд (мс). 1 секунда = 1’000 мс.
- time принимает тип данных unsigned long и может приостановить выполнение на срок от 1 до 4 294 967 295 мс (
50 суток) с разрешением 1 мс.
- Работает на системном таймере, поэтому не работает внутри прерывания и при отключенных прерываниях.
- Задержка на указанное количество микросекунд (мкс). 1 секунда = 1’000’000 мкс.
- time принимает тип данных unsigned int и может приостановить выполнение на срок от 4 до 16383 мкс (да, меньше чем максимум для этого типа данных) с разрешением 4 мкс.
- Работает не на таймере, а на пропуске тактов процессора, поэтому может работать в прерывании и при отключенных прерываниях.
- Иногда не совсем корректно работает с переменными, поэтому нужно стараться использовать константы ( const или просто число).
- Часто используется в библиотеках для эмуляции цифровых интерфейсов связи.
Задержки использовать очень просто:
Мышление “задержками” – главная проблема новичков. Организовать работу сложной программы при помощи задержки – невозможно, поэтому дальше рассмотрим более полезные инструменты.
Функция yield()
Разработчики Arduino позаботились о том, чтобы функция delay() не просто блокировала выполнение кода, но и позволяла выполнять другой код во время этой задержки. Данный “костыль” получил название yield() и работает следующим образом: если объявить функцию
то расположенный внутри неё код будет выполняться во время работы любой задержки delay() в программе! Это решение хоть и кажется нелепым, но в то же время позволяет быстро и без написания лишних костылей и таймеров реализовать пару параллельно выполняющихся задач. Это вполне соответствует идеологии Arduino – максимально простая и быстрая разработка прототипа. Рассмотрим простой пример: стандартный мигающий светодиод, но с опросом кнопки:
Функции счёта времени
Данные функции возвращают время, прошедшее с момента запуска программы, так называемый аптайм (англ. uptime). Таких функций у нас две:
- millis() – миллисекунды, тип unsigned long , от 1 до 4 294 967 295 мс (
50 суток), разрешение 1 мс. После “переполнения” отсчёт начинается с нуля.
micros() – микросекунды, тип unsigned long , от 4 до 4 294 967 295 мкс (
70 минут), разрешение 4 мкс. После “переполнения” отсчёт начинается с нуля.
Эти функции позволяют организовать программу практически любой сложности с любым количеством параллельно выполняющихся по таймеру задач. Подробнее об этом поговорим в уроке про многозадачность.
millis() в часы и секунды
Миллисекунды – не самый удобный способ оценить время работы программы. Можно перевести его в более человеческие часы, минуты и секунды при помощи нехитрых математических операций:
Видео
OLED часы на arduino
На днях я решил создать часы на arduino с отображением времени, текущей даты, дня недели и температуры воздуха на OLED дисплее. Что из этого получилось смотрите на видео.
Список необходимых компонентов:
и загружаем первый пробный скетч для проверки работоспособности дисплея и часового модуля
после загрузки скетча у нас на дисплее отобразятся часы как на фото
Как видим все отображается нормально, но что бы добавить русские названия дней недели нам потребуется инициализировать русские шрифты добавив строку в скетч
и еще добавить строки которые помогут нам определить порядковый номер дня недели и отобразить название дня на русском языке.
и еще закомментируем строки
что бы при повторной загрузке скетча не устанавливать заново время. После этого день недели на нашем дисплее отобразится на русском языке.
теперь изменим отображения месяца, добавив в скетч строки
Почему надписи в скетче отображаются непонятным набором символов читайте в этой статье Русские и украинские шрифты для OLED I2C дисплея
Теперь наши часики будут выглядеть как на фото.
Для тех, кому было лень править скетч, ниже есть готовый скетч.
Ну а теперь, еще более усовершенствуем наши OLED часы и добавим к ним отображение температуры, которую мы будем считывать с датчика температуры DS18B20.
Для отображения рисунка с градусником на OLED дисплее и значка градуса выберем картинку с рисунком градусника и с помощью графического редактора сохраним ее в формате GIF с именем term.gif, и тоже самое проделаем с картинкой с значком градуса — сохраним ее как grad.gif.
картинки должны быть двухцветными (белый и черный), доступные форматы картинок png, jpg, gif
У меня картинка term.bmp имеет размеры 19×40 пикселей, а картинка grad.bmp 13×12 пикселей. Потом нам потребуется конвертировать две картинки с помощью онлайн-сервиса www.rinkydinkelectronics.com
выбираем наш файл изображения и жмем Make File
Жмем на Click here to download your file и сохраняем файл grad.c в папку с нашим скетчем, тоже самое проделываем с другим изображением. Сохраняем и закрываем скетч. При повторном открытии он будет иметь еще две вкладки с файлами изображений.
После этого добавим две строки в скетч, которые инициализируют наши файлы изображений
а потом отобразим наши изображения на экране OLED дисплея, добавив строки
Добавим в наш скетч на два цикла. В первом цикле у нас будет отображаться время – назовем его void watch(); Второй цикл будет считывать и отображать температуру void temp();
А в основном цикле void loop(); пропишем для ротации циклов несколько строчек кода
В цикле void temp(); пропишем кусочек кода для считывания и отображения температуры
В цикле void watch(); пропишем наш код, который отвечает за отображение времени
После заливки скетча, наши OLED часы сначала должны отображать время, а потом температуру как на видео в начале статьи.