Задать вопрос
@Vlad0ss_Sh

Прошу оценить, прокритиковать код часов с динамической индикацией на 74HC595. Как можно улучшить код с помощью timer 1 или timer 2?

Всем привет. Я в ардуино новичок. Прошу знающих людей оценить мой код с точки зрения оптимальности. Сделал часы, написал все периоды на millis(). Слышал, что millis() не очень хорош для ДИ и работы линии данных модуля DS3231. Код прилагаю:
#include <microDS3231.h>
MicroDS3231 rtc;

const uint8_t DOT = 2; //пин для мигания точками

//пины модуля часов
const int SD = 18;
const int SC = 19;

//инициализируем пины для передачи данных
const int SER = 8; //пин передачи данных
const int RCLK = 9; //пин для управления защелкой (LATCH)
const int SRCLK = 10; //пин подключения вывода CLOCK

//настройка динамической индикации
const int per = 3; //период горения индикатора, мс
uint32_t last = 0; //динамической индикации
uint32_t lastsec = 0; //для мигания точками
int dig = 0;

//настройка цифр
uint8_t nums[] = {0x3F, 0x6, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x7, 0x7F, 0x6F}; //0, 1, 2, 3, 4, 5, 6, 7, 8, 9 - цифры в соотв. порядке
uint8_t mask[] = {0b01111111, 0b10111111, 0b11011111, 0b11101111}; //маска разряда
//uint8_t dot = 0x80; //байт для вызова 


//флажок мигания точками
bool dotFlag = false;

void setup() {
  pinMode(SER, OUTPUT);
  pinMode(RCLK, OUTPUT);
  pinMode(SRCLK, OUTPUT);
  pinMode(DOT, OUTPUT);
}

void loop()
{
  int mns = rtc.getMinutes();
  int hrs = rtc.getHours();

  int hrs0 = hrs / 10;
  int hrs1 = hrs % 10;
  int mns2 = mns / 10;
  int mns3 = mns % 10;

  if (mns > 59)
  {
    mns = 0;
    hrs++;
    if (hrs > 24)
    {
      hrs = 0;
    }
  }

  if (millis() - lastsec >= 1000) //мигаем точкой с периодом 1 с
  {
    lastsec = millis();
    dotFlag =! dotFlag;
  }

  if (millis() - last >= per) //динамическая индикация
  {
    last = millis();
    switch(dig)
    {
      case 0:
      digitalWrite(RCLK, LOW); //открываем защелку
      shiftOut(SER, SRCLK, LSBFIRST, mask[0]);
      shiftOut(SER, SRCLK, MSBFIRST, nums[hrs0]);
      digitalWrite(RCLK, HIGH); //закрываем защелку, пишем данные
      dig = 1;
      break;

      case 1:
      digitalWrite(RCLK, LOW); //открываем защелку
      shiftOut(SER, SRCLK, LSBFIRST, mask[1]);
      shiftOut(SER, SRCLK, MSBFIRST, nums[hrs1]);
      digitalWrite(RCLK, HIGH); //закрываем защелку, пишем данные
      dig = 2;
      break;
      
      case 2:
      digitalWrite(RCLK, LOW); //открываем защелку
      shiftOut(SER, SRCLK, LSBFIRST, mask[2]);
      shiftOut(SER, SRCLK, MSBFIRST, nums[mns2]);
      digitalWrite(RCLK, HIGH); //закрываем защелку, пишем данные
      dig = 3;
      break;

      case 3:
      digitalWrite(RCLK, LOW); //открываем защелку
      shiftOut(SER, SRCLK, LSBFIRST, mask[3]);
      shiftOut(SER, SRCLK, MSBFIRST, nums[mns3]);
      digitalWrite(RCLK, HIGH); //закрываем защелку, пишем данные
      dig = 4;
      break;

      case 4:
      digitalWrite(DOT, dotFlag);
      dig = 0;
      break;
    }
  }
}


672a91b357765425217776.jpeg
  • Вопрос задан
  • 190 просмотров
Подписаться 2 Средний 1 комментарий
Пригласить эксперта
Ответы на вопрос 1
@kalapanga
Примеров же полно в интернете. Я в гугле набрал "Ардуино динамическая индикация" и первая же ссылка https://3d-diy.ru/wiki/components/dinamicheskaya-i... подробный разбор с примерами, с миллисами, с таймерами, с чем угодно.
Естественно, к любой подобной статье надо относится критически. В упомянутой статье, например, коряво работают с миллис (у Вас правильнее). Но принципы вполне понятны.
В Вашем коде глаз зацепился за блок if (mns > 59) ... Он лишний. Вы минуты и часы от библиотеки часов получаете - неуж она может вернуть более 59 минут или более 24 часов?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы