На этом этапе построения часов, будет реализован вывод на дисплей MAX7219 форматированной строки, которая содержит значение текущего времени.

        Время в этой строке будет отображено как Часы-Минуты-Секунды. Как и предыдущем шаге, будут задействованы  десятичные точки для визуального разделения временных величин. Но с одной небольшой поправкой - для разделения величин даты было задействовано статичное свечение десятичных точек, для разделения величин времени, уже удобнее будет задействовать динамичное включение/выключение десятичных точек.

        Для того чтобы реализовать задуманное, используем библиотеку TimerOne. Вкратце - функционал библиотеки содержит функцию программного прерывания, инициировав её, мы можем выполнять какую нибудь операцию в программе с определённой частотой(ну, к примеру, раз в секунду). В нашем же случае, прерывание будет управлять зажиганием/гашением десятичной точки, которая разделяет временные величины. Визуально это будет своего рода удобным "морганием" точек.

        Итак, если у вас всё уже подключено,то остаётся только загрузить готовый скетч в плату Arduino и проверить его работу. Если же вы до этого, не ознакомились с примерами вывода на дисплей MAX7219 различных значений и символов, то добро пожаловать в прочтение следующих статей:

         Листинг скетча, выводим текущее время на дисплей MAX7219, используем библиотеку TimerOne.h для анимирования десятичных точек разделяющих временные величины. Подробнее о библиотеке TimerOne вы можете почитать в отдельной статье

/*Подключаем все необходимые библиотеки*/
#include "iarduino_RTC.h"
#include "LedControl.h"
#include "TimerOne.h"

/*Константы для пинов подключения дисплея MAX7219*/
#define DATA_IN 13
#define CLK 12
#define LOAD_CS 11
#define NUM_DEV 1
#define DISP_ADDR 0

/*Константы для пинов подключения модуля DS1302*/
#define RTC_DAT 8
#define RTC_CLK 7
#define RTC_RST 6

/*Для работы с библиотекой TimerOne*/
#define ON 1
#define OFF 0
unsigned char ClockPoint = 1;
unsigned char Update;

/*
  Создаём объект time класса iarduino_RTC для
  работы с модулем часов реального времени DS1302
  с указанием пинов подключения
*/
iarduino_RTC time(RTC_DS1302, 6, 7, 8);

LedControl Display = LedControl(DATA_IN, CLK, LOAD_CS, NUM_DEV);

/*Закодированные цифры для вывода на дисплей функцией setRow()*/
byte Digits[10] = {0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70, 0x7F, 0x7B};
/*Выводимая на дисплей строка*/
byte StrMessage[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

void setup()
{
  /*Выводим дисплей из спящего режима*/
  Display.shutdown(DISP_ADDR, false);
  /*Устанавливаем яркость свечения сегментов*/
  /*Доступные значения от 0 до 15*/
  Display.setIntensity(DISP_ADDR,8);
  /*Очищаем дисплей*/
  Display.clearDisplay(DISP_ADDR);

  /*Подключаем программное прерывание на 500 мс*/
  Timer1.initialize(500000);
  Timer1.attachInterrupt(TickTockISR);
}

void loop()
{
  if(Update == ON)
    TimeUpdate();
}

void TickTockISR()
{
  Update = ON;
  ClockPoint = (~ClockPoint) & 0x01;
}

void TimeUpdate(void)
{
  /*Запрашиваем текущее время у модуля DS1302*/
  time.begin();

  /*Размещаем значение в выводимой строке*/
  StrMessage[0] = Digits[time.seconds % 10];
  StrMessage[1] = Digits[time.seconds / 10];

  if(ClockPoint)
    StrMessage[2] = Digits[time.minutes % 10] ^ 0x80;
  else
    StrMessage[2] = Digits[time.minutes % 10];
  StrMessage[3] = Digits[time.minutes / 10];

  if(ClockPoint)
    StrMessage[4] = Digits[time.Hours % 10] ^ 0x80;
  else
    StrMessage[4] = Digits[time.Hours % 10];
  StrMessage[5] = Digits[time.Hours / 10];

  StrMessage[6] = 0x00;
  StrMessage[7] = 0x00;

  /*Выводим строку на дисплей*/
  for(int Rank = 0; Rank < 8; Rank ++)
    Display.setRow(DISP_ADDR, Rank, StrMessage[Rank]);

  Update = OFF;
}

        Результат работы скетча можно видеть на фото:

 

       

        Ну что же, следующим нашим шагом будет подключение модуля поворотного энкодера(KY-040) к плате Arduino. Для чего он нам нужен? Да всё очень просто - при помощи этого модуля мы будем управлять настройкой наших часов и скроллить меню с конфигурацией устройства. И пусть наше меню будет во многом ограничено(ведь символьный запас для семисегментных дисплеев очень скуден), мы всё равно постараемся выжать максимум для того чтобы оно получилось как можно более читабельным и понятным, и главное удобным для управления настройками. Но прежде чем начать построение меню, нужно хорошо освоить модуль поворотного энкодера с связке с семисегментным дисплеем на базе драйвера MAX7219. Также, в рамках следующего шага, будет изучено такое свойство контактных датчиков(модуль KY-040 в некотором роде и есть такой датчик) как дребезг контактов. Но, обо всём как говорится по порядку...