Тренировка началася. Скетч дописал.
//UNO
//max7219
//Загружаем библиотеку max7219
#include "LedControl.h"
//Рацветка шлейфов на индикацию:
//Vсс - красный
//GND - черный
//Din (dout) - пин 5 - желтый
//CS (load) - пин 6 - зеленый
//CLK - пин 7 - оранжевый
//создаём объект класса LedControl (din,clk,cs,X)
//четвертая цифра "X" - количество модулей
LedControl lc = LedControl(10, 8, 9, 0);
int DesH=0; //Десятки часов
int OneH=0; //Единицы часов
int DesM=0; //Десятки минут
int OneM=0; //Единицы минут
int DesS=0; //Десятки секунд
int OneS=0; //Единицы секунд
int Hours=0; //Часы
int Minutes=0; //Минуты
int Seconds=0; //Секунды
int period=1000; //Тик часов
unsigned long second_previous; //Время последнего переключения секунд
volatile int encoder_value=0; //Значение энкодера
volatile int button_value=0; //Значение кнопки
volatile boolean encoder_answer; //Ответ второй ножки энкодера
void setup()
{
//Инициализация модуля max7219
lc.shutdown(0, false); //Выводим из спящего режима
lc.setIntensity(0,2); //Яркость дисплея на 2. Всего возможных режимов яркости от 0 до 15
lc.clearDisplay(0); //Очистить дисплей
pinMode(2, INPUT_PULLUP); //Пин кнопки на прерывании на вход
pinMode(3, INPUT_PULLUP); //Пин энкодера на прерывании на вход
pinMode(5, INPUT_PULLUP); //Пин энкодера на вход для работы
Serial.begin (115200); //Активация порта
attachInterrupt(1, ENCODER_TURN,FALLING); //Прерывание энкодера
attachInterrupt(0, BUTTON_PRESS,FALLING); //Прерывание кнопки
// Пишем исходное состояние часов
lc.setDigit(0, 7, DesH, false);
lc.setDigit(0, 6, OneH, false);
// Пишем минуты
lc.setDigit(0, 4, DesM, false);
lc.setDigit(0, 3, OneM, false);
// Пишем секунды
lc.setDigit(0, 1, DesS, false);
lc.setDigit(0, 0, OneS, false);
// Пишем дефисы
lc.setChar(0, 5, '-', false);
lc.setChar(0, 2, '-', false);
}
void loop()
{
if (button_value==0) // Сброс часов на 0
{
lc.setDigit(0, 7, 0, false);
lc.setDigit(0, 6, 0, false);
// Пишем минуты
lc.setDigit(0, 4, 0, false);
lc.setDigit(0, 3, 0, false);
// Пишем секунды
lc.setDigit(0, 1, 0, false);
lc.setDigit(0, 0, 0, false);
}
if (button_value==1) // Установка часов
{
Hours=encoder_value;
if (Hours>24) {Hours=24;}
if (Hours<0) {Hours=0;}
OneH=Hours%10;
DesH=(Hours/10)%10;
lc.setDigit(0, 7, DesH, false);
lc.setDigit(0, 6, OneH, false);
}
if (button_value==2) // Установка минут
{
Minutes=encoder_value;
if (Minutes>59) {Minutes=59;}
if (Minutes<0) {Minutes=0;}
OneM=Minutes%10;
DesM=(Minutes/10)%10;
lc.setDigit(0, 4, DesM, false);
lc.setDigit(0, 3, OneM, false);
}
if (button_value==3) // Установка счекунд
{
Seconds=encoder_value;
if (Seconds>59) {Seconds=59;}
if (Seconds<0) {Seconds=0;}
OneS=Seconds%10;
DesS=(Seconds/10)%10;
lc.setDigit(0, 1, DesS, false);
lc.setDigit(0, 0, OneS, false);
}
if (button_value==4) // Запуск часов
{
if (millis()-second_previous>period) //По прошествии N миллисек
{
Seconds++;
if (Seconds>59) //Если секунд больше 59
{
Seconds=0;
Minutes++;
}
if (Minutes>59) //Если минут больше 59
{
Minutes=0;
Hours++;
}
if (Hours>23) //Если часов больше 23
{
Hours=0;
}
// Индикация времени
//Переводим в единицы/десятки
OneH=Hours%10;
DesH=(Hours/10)%10;
OneM=Minutes%10;
DesM=(Minutes/10)%10;
OneS=Seconds%10;
DesS=(Seconds/10)%10;
//Пишем часы
lc.setDigit(0, 7, DesH, false);
lc.setDigit(0, 6, OneH, false);
// Пишем минуты
lc.setDigit(0, 4, DesM, false);
lc.setDigit(0, 3, OneM, false);
// Пишем секунды
lc.setDigit(0, 1, DesS, false);
lc.setDigit(0, 0, OneS, false);
second_previous=millis();
}
}
}
void ENCODER_TURN ()//Обработка вращения энкодера
{
encoder_answer=digitalRead (5);
if (encoder_answer==0)
{
encoder_value--;
if (encoder_value<0) {encoder_value=0;}
Serial.println (encoder_value);
}
else
{
encoder_value++;
if (encoder_value<0) {encoder_value =0;}
Serial.println (encoder_value);
}
}
void BUTTON_PRESS () //Обработка нажатия кнопки
{
button_value++;
if (button_value>4)
{
button_value=0;
}
}
Пока для “тренировки” так. Сейчас просто установил показатели и в нужный момент дал старт. Посмотрим “точность”. Но есть вопрос: поставил “тик” часов (добавка секунд) как “int period=1000;”. Ну, дальше - как обычно: “if (millis()-second_previous>period) { }”
То ли мне кажется, то ли после пивка не соображаю. Может, надо было “int period>999;”?
Посмотрю, если будут отставать, то второе выражение верное…