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

Всем привет! Я новичок в Arduino и хотел бы получить оценку своего кода от более опытных пользователей с точки зрения оптимальности. В реализации часов я использовал всё на millis(). Однако слышал, что использование millis() может быть не самым лучшим решением для дисплея и работы с линией данных модуля DS3231. Привожу свой код ниже:  
<br/> 
<pre><code class="cpp">#include &lt;microDS3231.h&gt;
MicroDS3231 rtc;
// остальная часть кода...
</code></pre>
  • 5 ноября 2024 г. 21:53
Ответы на вопрос 2
Привет! Давайте посмотрим на ваш код и подумем, как его можно оптимизировать с использованием таймеров вместо `millis()`. 

Использование `millis()`—хороший вариант для создания программ с несколькими задачами, однако для работы с часы и дисплеем может быть полезно использовать аппаратные таймеры, так как они обеспечивают более высокую точность и менее чувствительны к задержкам в коде.

Ниже приведены некоторые рекомендации по улучшению кода:

1. **Использование таймеров**: Вместо того, чтобы проверять время в цикле с помощью `millis()`, вы можете использовать таймеры (например, Timer1 или Timer2). Эти таймеры имеют возможность генерировать прерывания, что позволяет вашему коду реагировать на события в реальном времени.

2. **Периодическое обновление дисплея**: Вместо того чтобы постоянно обновлять дисплей, вы можете установить таймер, который будет обновлять дисплей только через определённые интервалы времени (например, каждую секунду).

3. **Оптимизация управления 74HC595**: Убедитесь, что вы минимизируете количество обновлений данных в сдвиговом регистре. Вы можете хранить текущее состояние дисплея и обновлять его только тогда, когда изменяются данные.

4. **Кодирование стиля**: Убедитесь, что ваш код организован и разделен на функции. Это сделает его более читаемым и облегчает сопровождение.

Вот пример того, как вы могли бы переписать ваш код для работы с таймерами:

```cpp
#include <microDS3231.h>
#include <TimerOne.h> // библиотека для работы с таймером 1

MicroDS3231 rtc;

volatile bool updateDisplay = false;

void setup() {
  // Инициализация RTC
  rtc.begin();
  
  // Настройка таймера на 1 секунду
  Timer1.initialize(1000000); // 1000000 микросекунд = 1 секунда
  Timer1.attachInterrupt(updateTime);
}

void loop() {
  if (updateDisplay) {
    updateDisplay = false;
    displayTime(); // Функция для отображения времени
  }
}

void updateTime() {
  updateDisplay = true;
}

void displayTime() {
  // Здесь добавьте ваш код для обновления дисплея,
  // используя 74HC595, только когда это действительно необходимо
  // например, считывая данные с RTC и обновляя ваш сдвиговый регистр.
}
```

В этом примере `updateTime` вызывается каждую секунду, устанавливая флаг `updateDisplay`, который затем проверяется в функции `loop()`. Это дает вам возможность обновлять дисплей только тогда, когда это необходимо.

### Заключение
Использование таймеров может значительно улучшить производительность вашей программы, особенно для задач, связанных с временем. Если вам нужно больше контроля над частотой обновления или необходимо использовать несколько сигналов, рассмотрите возможность использования различных таймеров и их прерываний.
Примеров же полно в интернете. Я в гугле набрал "Ардуино динамическая индикация" и первая же ссылка https://3d-diy.ru/wiki/components/dinamicheskaya-i... подробный разбор с примерами, с миллисами, с таймерами, с чем угодно. 
Естественно, к любой подобной статье надо относится критически. В упомянутой статье, например, коряво работают с миллис (у Вас правильнее). Но принципы вполне понятны.
В Вашем коде глаз зацепился за блок if (mns > 59) ... Он лишний. Вы минуты и часы от библиотеки часов получаете - неуж она может вернуть более 59 минут или более 24 часов?
Похожие вопросы