LED часы Arduino Nano 3.0, Ds3231,DHT11,MAX7219

Как по мне, так уже получше. Правда, хотел глянуть LedControl.h, но именно такую не нашёл.

Ну и, каков результат?

Подправил код библиотеки, теперь эти предупреждения не вылезут. Можете обновиться

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

Спасибо, обновлюсь. Хорошая скорость обработки нажатий, нажал и работает, не надо ждать секунду-две. Только не получалось одновременно задействовать быстрое и долгое нажатие на серию импульсов. Позже еще попробую.

Примерно так:

void setup()
{
  // настройка кнопки
  but.setLongClickMode(LCM_CLICKSERIES); // включение серии событий при удержании кнопки
  but.setTimeoutOfLongClick(1000) // установка времени удержания кнопки
  but.setIntervalOfSerial(50); // настройка интервала между событиями в сериии при удержании кнопки - каждые 50 милисекунд

  .......
}


void loop() {
  // обработка нажатия кнопки
  switch (but.getButtonState())
  {
  case BTN_DOWN:
  case BTN_LONGCLICK:
    // здесь код, выполняющийся при одинарном клике или при удержании кнопки 
    // код будет выполнен при нажатии кнопки и, если кнопку удерживать, то через 1 секунду будет выполняться через каждые 50 милисекунд
    break;
  }

  .........

}

Значит можна использовать два case одновременно? Когда я пробовал то устанавливал только LCM_CLICKSERIES и на кнопку установки режымов, а остальное закомментировал, и тогда режымы переключались как очереди с АК. Дисплей не успевал отображать переключения между настройками, непонятно было что настраивается: то ли время то ли дата… Я пробовал через if и или.

Переделаю по Вашему примеру, спасибо

Хоть три ))

LedControl - довольно медлительная. Здесь я вам дал ссылку на переработанную библиотеку ))

Работает, спасибо.

void ButtonSetControl() {
 switch (setButt.getButtonState()){
    case BTN_UP:
    mode++;
      if (mode >= 8){
        mode = 0;
      }
      break;
  }
   
if (mode) {
  switch (upButt.getButtonState()){
    case BTN_UP:
    case BTN_LONGCLICK:
    switch (mode) {
        /* сек */ case 1:
          myRTC.setSecond(0);
        break;
        /* мин */ case 2:
          myRTC.setMinute(minutes == 59 ? 0 : minutes +1);
          break;
        /* час */ case 3:
          myRTC.setHour(hours == 23 ? 0 : hours + 1);
          break;
        /* дни */ case 4:
          myRTC.setDate(date == 31 ? 1 : date +1);
          break;
        /* мес */ case 5:
          myRTC.setMonth(month == 12 ? 1 : month +1);
          break;
        /* год */ case 6:
          myRTC.setYear(year == 99 ? 0 : year + 1);
         break;
        /* д.н.*/ case 7:
          myRTC.setDoW(DoW == 7 ? 1 : DoW + 1);
          break;
    }
    break;
  }
  switch (downButt.getButtonState()) {
    case BTN_UP:
    case BTN_LONGCLICK:
       switch (mode) {
      /* сек */ case 1:
        myRTC.setSecond(0);
        break;
      /* мин */ case 2:
        myRTC.setMinute(minutes == 0 ? 59 : minutes - 1);
        break;
      /* час */ case 3:
        myRTC.setHour(hours == 0 ? 23 : hours - 1);
        break;
      /* дни */ case 4:
        myRTC.setDate(date == 1 ? 31 : hours - 1);
        break;
      /* мес */ case 5:
        myRTC.setMonth(month == 1 ? 12 : month - 1);
        break;
      /* год */ case 6:
        myRTC.setYear(year == 1 ? 99 : year - 1);
        break;
      /* д.н.*/ case 7:
        myRTC.setDoW(DoW == 1 ? 7 : DoW - 1);
        break;
    }
    break;
  }
}
ShowEmptyPlace();
}

Зачем так? Если нужно именно при отпускании, то лучше сделать так

void setup()
{
  setButt.setVirtualClickOn(); // включение режима виртуального клика
....................
}

 switch (setButt.getButtonState()){
    case BTN_ONECLICK:
    mode++;
      if (mode >= 8){
        mode = 0;
      }
      break;
  }

Тогда событие будет иметь место быть только при коротком клике после отпускания кнопки. А в вашем варианте оно будет при каждом отпускании, в том числе после удержания. А при двойном клике аж два раза ))

Я не включил setVirtualClickOn(), не понял сразу, сейчас работает

#include <LedControl.h>
#include <DHT11.h>
#include <Wire.h>
#include <DS3231.h>
#include <shButton.h>
#define CLINT 2
DS3231 myRTC;
LedControl LC = LedControl(12, 11, 10, 3);
DHT11 dht11(6);
bool century = false;
bool h12Flag;
bool pmFlag;
bool alarmDayIsDay;
bool alarmH12;
bool alarmPM;
byte alarmBits;
volatile byte tick = 1;
byte hours, minutes, seconds, DoW, date, month, year;
const int brightSetPin = A0;
byte mode = 0;
long previousMillis = 0;
unsigned long buttonTimer = 0;
unsigned long tempHumidityTimer = 0;
unsigned long emptyTimer = 0;
int temperature = 0;
int humidity    = 0;
shButton setButt(3);
shButton upButt(4);
shButton downButt(5);
void ButtonSetControl();
void ShowTime();
void CheckTime();
void ShowEmptyPlace();
void setup() {
  Serial.begin(9600);
  Wire.begin();
  for (int ledS = 0; ledS < 3; ledS++) {
    LC.shutdown(ledS, false);
    LC.clearDisplay(ledS);
  }
  myRTC.setClockMode(false);
   // настройка кнопки
  upButt.setLongClickMode(LCM_CLICKSERIES);
  downButt.setLongClickMode(LCM_CLICKSERIES); // включение серии событий при удержании кнопки
  upButt.setTimeoutOfLongClick(1000); // установка времени удержания кнопки
  downButt.setTimeoutOfLongClick(1000);
  upButt.setIntervalOfSerial(50); // настройка интервала между событиями в сериии при удержании кнопки - каждые 50 милисекунд
  downButt.setIntervalOfSerial(50);
  setButt.setVirtualClickOn(); // включение режима виртуального клика
  upButt.setVirtualClickOn();
  downButt.setVirtualClickOn();  
    alarmBits = 0b00001111; // Alarm 1 every second
    alarmDayIsDay = false;
    alarmH12 = false;
    alarmPM = false; 
   myRTC.turnOffAlarm(1);
   myRTC.setA1Time(0, 0, 0, 0, alarmBits, alarmDayIsDay, alarmH12, alarmPM); 
    myRTC.turnOnAlarm(1);         // enable Alarm 1 interrupts
    myRTC.checkIfAlarm(1);        // clear Alarm 1 flag

}
void loop() {
  static byte tik = 0;
  if (millis() - buttonTimer > 20) {
    buttonTimer = millis();
    ButtonSetControl();
    if (tik >= 25) {
      CheckTime();
      ShowTime();
      tik = 0;
    }
    tik++;
  }
  if (millis() - tempHumidityTimer > 30000) {
    tempHumidityTimer = millis();
    temperature = dht11.readTemperature();
    humidity = dht11.readHumidity();
  }
  Serial.println(mode);
}
void CheckTime() {
  hours = myRTC.getHour(h12Flag, pmFlag);
  minutes = myRTC.getMinute();
  seconds = myRTC.getSecond();
  DoW = myRTC.getDoW();
  date = myRTC.getDate();
  month = myRTC.getMonth(century);
  year = myRTC.getYear();
 }
void ShowTime() {
  int brightSetVol = analogRead(brightSetPin) / 50;
  if (brightSetVol < 0) { brightSetVol = 2; }
  for (int ledS = 0; ledS < 3; ledS++) {
    LC.setIntensity(ledS, brightSetVol);
  }
  LC.setDigit(0, 0, hours / 10, false);
  LC.setDigit(0, 1, hours % 10, true);
  LC.setDigit(0, 2, minutes / 10, false);
  LC.setDigit(0, 3, minutes % 10, true);
  LC.setDigit(0, 4, seconds / 10, false);
  LC.setDigit(0, 5, seconds % 10, false);
  switch (DoW) {
    case 1:  //  ПН
      LC.setRow(0, 6, 0b01110110);
      LC.setRow(0, 7, 0b00110111);
      break;
    case 2:  //  ВТ
      LC.setRow(0, 6, 0b01111111);
      LC.setRow(0, 7, 0b00001111);
      break;
    case 3:  //  СР
      LC.setRow(0, 6, 0b01001110);
      LC.setRow(0, 7, 0b01100111);
      break;
    case 4:  //  ЧТ
      LC.setRow(0, 6, 0b00110011);
      LC.setRow(0, 7, 0b00001111);
      break;
    case 5:  //  ПТ
      LC.setRow(0, 6, 0b01110110);
      LC.setRow(0, 7, 0b00001111);
      break;
    case 6:  //  СБ
      LC.setRow(0, 6, 0b01001110);
      LC.setRow(0, 7, 0b00011111);
      break;
    case 7:  //  НД
      LC.setRow(0, 6, 0b00110111);
      LC.setRow(0, 7, 0b00111101);
      break;
  }
  LC.setDigit(1, 0, date / 10, false);
  LC.setDigit(1, 1, date % 10, true);
  LC.setDigit(1, 2, month / 10, false);
  LC.setDigit(1, 3, month % 10, true);
  LC.setDigit(1, 4, 2, false);
  LC.setDigit(1, 5, 0, false);
  LC.setDigit(1, 6, year / 10, false);
  LC.setDigit(1, 7, year % 10, false);
  if (temperature < 0) {
    LC.setRow(2, 0, 0b0000001);
  }
  LC.setDigit(2, 1, temperature / 10, false);
  LC.setDigit(2, 2, temperature % 10, false);
  LC.setRow(2, 3, 0b01100011);
  LC.setRow(2, 4, 0b01001110);
  LC.setDigit(2, 5, humidity / 10, false);
  LC.setDigit(2, 6, humidity % 10, false);
  LC.setRow(2, 7, 0b00110111);
}
void ButtonSetControl() {
 switch (setButt.getButtonState()){
    case BTN_ONECLICK:
    mode++;
      if (mode >= 8){
        mode = 0;
      }
      break;
  }
   
if (mode) {
  switch (upButt.getButtonState()){
    case BTN_ONECLICK:
    case BTN_LONGCLICK:
    switch (mode) {
        /* сек */ case 1:
          myRTC.setSecond(0);
        break;
        /* мин */ case 2:
          myRTC.setMinute(minutes == 59 ? 0 : minutes +1);
          break;
        /* час */ case 3:
          myRTC.setHour(hours == 23 ? 0 : hours + 1);
          break;
        /* дни */ case 4:
          myRTC.setDate(date == 31 ? 1 : date +1);
          break;
        /* мес */ case 5:
          myRTC.setMonth(month == 12 ? 1 : month +1);
          break;
        /* год */ case 6:
          myRTC.setYear(year == 99 ? 0 : year + 1);
         break;
        /* д.н.*/ case 7:
          myRTC.setDoW(DoW == 7 ? 1 : DoW + 1);
          break;
    }
    break;
  }
  switch (downButt.getButtonState()) {
    case BTN_ONECLICK:
    case BTN_LONGCLICK:
       switch (mode) {
      /* сек */ case 1:
        myRTC.setSecond(0);
        break;
      /* мин */ case 2:
        myRTC.setMinute(minutes == 0 ? 59 : minutes - 1);
        break;
      /* час */ case 3:
        myRTC.setHour(hours == 0 ? 23 : hours - 1);
        break;
      /* дни */ case 4:
        myRTC.setDate(date == 1 ? 31 : hours - 1);
        break;
      /* мес */ case 5:
        myRTC.setMonth(month == 1 ? 12 : month - 1);
        break;
      /* год */ case 6:
        myRTC.setYear(year == 1 ? 99 : year - 1);
        break;
      /* д.н.*/ case 7:
        myRTC.setDoW(DoW == 1 ? 7 : DoW - 1);
        break;
    }
    break;
  }
}
ShowEmptyPlace();
}
void ShowEmptyPlace() {
  if (mode) {
    if (millis() - emptyTimer > 1000) {
      emptyTimer = millis();
      switch (mode) {
        case 1:
          LC.setChar(0, 5, 0b0100000, false);
          LC.setChar(0, 4, 0b0100000, false);
          break;
        case 2:
          LC.setChar(0, 2, 0b0100000, false);
          LC.setChar(0, 3, 0b0100000, true);
          break;
        case 3:
          LC.setChar(0, 0, 0b0100000, false);
          LC.setChar(0, 1, 0b0100000, true);
          break;
        case 4:
          LC.setChar(1, 0, 0b0100000, false);
          LC.setChar(1, 1, 0b0100000, true);
          break;
        case 5:
          LC.setChar(1, 2, 0b0100000, false);
          LC.setChar(1, 3, 0b0100000, true);
          break;
        case 6:
          LC.setChar(1, 6, 0b0100000, false);
          LC.setChar(1, 7, 0b0100000, false);
          break;
        case 7:
          LC.setChar(0, 6, 0b0100000, false);
          LC.setChar(0, 7, 0b0100000, false);
          break;
      }
    }
  }
}

Будильник 2 обязательно выставлять как в примере? Там есть настройка но также сказано что это делать не обязательно?

Пример:

/*
AlarmInterrupt.ino
Jacob Nuernberg
08/22

Example on using interrupts with DS3231 alarms.

Hardware setup:
  Connect DS3231 SQW pin to Arduino interrupt pin 2

Tested on:
- Arduino UNO
- Arduino nano

Added to this example:

1. Descriptively named variables to pass parameter values.

2. Modify AlarmBits for Alarm 1 to 0b00001111,
   for clarity, because Alarm 1 uses only bits 3:0.
   
3. Add code to prevent Alarm 2 from interfering with the interrupt,
   by setting A2Minute to a value that can never match the time
   and setting AlarmBits to 0b01100000: alarm "when minutes match".
   Also clear the A2 alarm flag.

David Sparks, September 2022
*/

#include <DS3231.h>
#include <Wire.h>

// myRTC interrupt pin
#define CLINT 2

// Setup clock
DS3231 myRTC;

// Variables for use in method parameter lists
byte alarmDay;
byte alarmHour;
byte alarmMinute;
byte alarmSecond;
byte alarmBits;
bool alarmDayIsDay;
bool alarmH12;
bool alarmPM;

// Interrupt signaling byte
volatile byte tick = 1;

void setup() {
    // Begin I2C communication
    Wire.begin();

    // Begin Serial communication
    Serial.begin(9600);
    while (!Serial);
    Serial.println();
    Serial.println("Starting Serial");

    // Assign parameter values for Alarm 1
    alarmDay = 0;
    alarmHour = 0;
    alarmMinute = 0;
    alarmSecond = 0;
    alarmBits = 0b00001111; // Alarm 1 every second
    alarmDayIsDay = false;
    alarmH12 = false;
    alarmPM = false;    

    // Set alarm 1 to fire at one-second intervals
    myRTC.turnOffAlarm(1);
    myRTC.setA1Time(
       alarmDay, alarmHour, alarmMinute, alarmSecond,
       alarmBits, alarmDayIsDay, alarmH12, alarmPM);
    // enable Alarm 1 interrupts
    myRTC.turnOnAlarm(1);
    // clear Alarm 1 flag
    myRTC.checkIfAlarm(1);

    // When using interrupt with only one of the DS3231 alarms, as in this example,
    // it may be advisable to prevent the other alarm entirely,
    // so it will not covertly block the outgoing interrupt signal.

    // Prevent Alarm 2 altogether by assigning a 
    // nonsensical alarm minute value that cannot match the clock time,
    // and an alarmBits value to activate "when minutes match".
    alarmMinute = 0xFF; // a value that will never match the time
    alarmBits = 0b01100000; // Alarm 2 when minutes match, i.e., never
    
    // Upload the parameters to prevent Alarm 2 entirely
    myRTC.setA2Time(
        alarmDay, alarmHour, alarmMinute,
        alarmBits, alarmDayIsDay, alarmH12, alarmPM);
    // disable Alarm 2 interrupt
    myRTC.turnOffAlarm(2);
    // clear Alarm 2 flag
    myRTC.checkIfAlarm(2);

    // NOTE: both of the alarm flags must be clear
    // to enable output of a FALLING interrupt

    // attach clock interrupt
    pinMode(CLINT, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(CLINT), isr_TickTock, FALLING);

    // Use builtin LED to blink
    pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
    // static variable to keep track of LED on/off state
    static byte state = false;

    // if alarm went of, do alarm stuff
    if (tick) {
        tick = 0;
        state = ~state;
        digitalWrite(LED_BUILTIN, state);

        // optional serial output
        Serial.print("Turning LED ");
        Serial.println((state ? "ON" : "OFF"));

        // Clear Alarm 1 flag
        myRTC.checkIfAlarm(1);
    }

    // Loop delay to emulate other running code
    delay(10);
}


void isr_TickTock() {
    // interrupt signals to loop
    tick = 1;
    return;
}

С этой библиотекой скетч меньше памяти занимает.
Ссылка на Ledcontrol с менеджера библиотек: LedControl

1 лайк

В смысле код с помощью DS3231.h меньше места занимает по сравнению с iarduino_rtc.
Так ответил, что сам не понял о чём речь…

На сегодня всё, завтра продолжу будильники с прерываниями :wink:

Глянул, тоже warning-ов полно…
Хорошую библиотеку посоветовать не могу, т.к. сам без них всегда обхожусь (при работе с RTC)

#include <LedControl.h>           // Подключение библиотеки   MAX7219  управление 8миразрядными дисплеями 
#include <DHT11.h>                // Подключение библиотеки   DHT11     работас  датчиком влажности/температуры
#include <Wire.h>                 // Подключение библиотеки   I2C         
#include <DS3231.h>               // Подключение библиотеки   RTC       работа с DS3231
#include <shButton.h>             // Подключение библиотеки   shButton  работа с тактовыми кнопками
#define CLINT 2                   // Пин для управления прерываниями
DS3231 myRTC;                     // Обьявления типа RTC - DS3231
LedControl LC = LedControl(12, 11, 10, 3);   // Пины для управления драйвером и количество подключенных модулей
DHT11 dht11(6);                   // Обьявления типа датчика влажности/температуры - DHT11
bool century = false;             // флаг столетия, не используется
bool h12Flag, pmFlag;                   
byte alarmDay, alarmHour, alarmMinute, alarmSecond, alarmBits; // переменные времени и даты будильника                  
bool alarmDayIsDay, alarmH12, alarmPM;                         // флаги будильника
byte hours, minutes, seconds, DoW, date, month, year;          // переменные времени и даты часов
const int brightSetPin = A0;                                   // пин для подключения датчика света
byte mode = 0;                                                 // переменная режыма настройки
unsigned long buttonTimer = 0;                                 // переменная хранения времени таймера запуска настройки кнопками
unsigned long tempHumidityTimer = 0;                           // переменная хранения времени таймера считывания с датчика влажности/температуры
unsigned long emptyTimer = 0;                                  // переменная хранения времени таймера вывода пустыг символов на дисплей
int temperature = 0;                                           // переменная хранения температуры
int humidity    = 0;                                           // переменная хранения влажности
shButton setButt(3);                                           // пин кнопки setButt  "Настройка"
shButton upButt(4);                                            // пин кнопки supButt  "Вверх"
shButton downButt(5);                                          // пин кнопки downButt "Вниз"
void ButtonSetControl();                                       // обьявление функции установки времени кнопками
void ShowTime();                                               // обьявление функции вывода времени на дисплей
void CheckTime();                                              // обьявление функции считывания времени с RTC
void ShowEmptyPlace();                                         // обьявление функции вывода пустыг символов на дисплей при настройке времени
void isr_oneSecond();                                          // обьявление функции обработки прерывания
void setup() {                                                  
  Serial.begin(9600);                                          // Запуск вывода в последовательный порт 9600 бод
  Wire.begin();                                                // запуск обмена по I2C
  for (int ledS = 0; ledS < 3; ledS++) {                       // очистка дисплеев
    LC.shutdown(ledS, false);
    LC.clearDisplay(ledS);
  }
  myRTC.setClockMode(false);                  // установка 24-часового формата времени
  upButt.setLongClickMode(LCM_CLICKSERIES);   // включение серии событий при удержании кнопки upButt
  downButt.setLongClickMode(LCM_CLICKSERIES); // включение серии событий при удержании кнопки downButt
  upButt.setTimeoutOfLongClick(1000);         // установка времени удержания кнопки upButt
  downButt.setTimeoutOfLongClick(1000);       // установка времени удержания кнопки downButt
  upButt.setIntervalOfSerial(50);             // настройка интервала между событиями в сериии при удержании кнопки upButt - каждые 50 милисекунд
  downButt.setIntervalOfSerial(50);           // настройка интервала между событиями в сериии при удержании кнопки downButt- каждые 50 милисекунд
  setButt.setVirtualClickOn();                // включение режима виртуального клика setButt
  upButt.setVirtualClickOn();                 // включение режима виртуального клика upButt
  downButt.setVirtualClickOn();               // включение режима виртуального клика downButt
    alarmDay = 0;                             // переменные установки будильника 
    alarmHour = 0;
    alarmMinute = 0;
    alarmSecond = 0;
    alarmBits = 0b00001111;                   // биты установки первого будильника раз в секунду
    alarmDayIsDay = false;
    alarmH12 = false;
    alarmPM = false; 
    myRTC.turnOffAlarm(1);                    // выключение первого будильника
    myRTC.setA1Time(alarmDay, alarmHour, alarmMinute, alarmSecond, alarmBits, alarmDayIsDay, alarmH12, alarmPM);  // установка первого будильника
    myRTC.turnOnAlarm(1);                     // включение прерываний первого будильника
    myRTC.checkIfAlarm(1);                    // сброс флага первого будильника
    //alarmMinute = 0xFF; // a value that will never match the time
    //alarmBits = 0b01100000;       // Alarm 2 when minutes match, i.e., never
    //myRTC.setA2Time(alarmDay, alarmHour, alarmMinute, alarmBits, alarmDayIsDay, alarmH12, alarmPM);  // disable Alarm 2 interrupt
    //myRTC.turnOffAlarm(2);        // clear Alarm 2 flag
    //myRTC.checkIfAlarm(2);
pinMode(CLINT, INPUT_PULLUP);                 // настройка пина прерывания
    attachInterrupt(digitalPinToInterrupt(CLINT), isr_oneSecond, FALLING);  // обьявление прерывания на пин
}
void loop() {
  static byte tik = 0;                        // таймеры запуска функций          
  if (millis() - buttonTimer > 20) {
    buttonTimer = millis();                   // buttonTimer = millis() и ButtonSetControl() раз в 20 мс
    ButtonSetControl();
    if (tik >= 25) {
      CheckTime();                            //  CheckTime() раз в 500 мс 
      tik = 0;
    }
    tik++;
  }
  if (millis() - tempHumidityTimer > 30000) { // запуск считывания данных с датчика влажности/температуры раз в пол секунды
    tempHumidityTimer = millis();
    temperature = dht11.readTemperature();
    humidity = dht11.readHumidity();
  }
  myRTC.checkIfAlarm(1);                      // сброс флага первого будильника
 }
void CheckTime() {
  hours = myRTC.getHour(h12Flag, pmFlag);     // считывание и запись в переменные значения времени и даты с RTC
  minutes = myRTC.getMinute();
  seconds = myRTC.getSecond();
  DoW = myRTC.getDoW();
  date = myRTC.getDate();
  month = myRTC.getMonth(century);
  year = myRTC.getYear();
 }
void ShowTime() {
  int brightSetVol = analogRead(brightSetPin) / 50;
  if (brightSetVol < 0) { brightSetVol = 2; }
  for (int ledS = 0; ledS < 3; ledS++) {
    LC.setIntensity(ledS, brightSetVol);
  }
  LC.setDigit(0, 0, hours / 10, false);
  LC.setDigit(0, 1, hours % 10, true);
  LC.setDigit(0, 2, minutes / 10, false);
  LC.setDigit(0, 3, minutes % 10, true);
  LC.setDigit(0, 4, seconds / 10, false);
  LC.setDigit(0, 5, seconds % 10, false);
  switch (DoW) {
    case 1:  //  ПН
      LC.setRow(0, 6, 0b01110110);
      LC.setRow(0, 7, 0b00110111);
      break;
    case 2:  //  ВТ
      LC.setRow(0, 6, 0b01111111);
      LC.setRow(0, 7, 0b00001111);
      break;
    case 3:  //  СР
      LC.setRow(0, 6, 0b01001110);
      LC.setRow(0, 7, 0b01100111);
      break;
    case 4:  //  ЧТ
      LC.setRow(0, 6, 0b00110011);
      LC.setRow(0, 7, 0b00001111);
      break;
    case 5:  //  ПТ
      LC.setRow(0, 6, 0b01110110);
      LC.setRow(0, 7, 0b00001111);
      break;
    case 6:  //  СБ
      LC.setRow(0, 6, 0b01001110);
      LC.setRow(0, 7, 0b00011111);
      break;
    case 7:  //  НД
      LC.setRow(0, 6, 0b00110111);
      LC.setRow(0, 7, 0b00111101);
      break;
  }
  LC.setDigit(1, 0, date / 10, false);
  LC.setDigit(1, 1, date % 10, true);
  LC.setDigit(1, 2, month / 10, false);
  LC.setDigit(1, 3, month % 10, true);
  LC.setDigit(1, 4, 2, false);
  LC.setDigit(1, 5, 0, false);
  LC.setDigit(1, 6, year / 10, false);
  LC.setDigit(1, 7, year % 10, false);
  if (temperature < 0) {
    LC.setRow(2, 0, 0b0000001);
  }
  LC.setDigit(2, 1, temperature / 10, false);
  LC.setDigit(2, 2, temperature % 10, false);
  LC.setRow(2, 3, 0b01100011);
  LC.setRow(2, 4, 0b01001110);
  LC.setDigit(2, 5, humidity / 10, false);
  LC.setDigit(2, 6, humidity % 10, false);
  LC.setRow(2, 7, 0b00110111);
}
void ButtonSetControl() {
 switch (setButt.getButtonState()){
    case BTN_ONECLICK:
    mode++;
      if (mode >= 8){
        mode = 0;
      }
      break;
  }
   
if (mode) {
  switch (upButt.getButtonState()){
    case BTN_ONECLICK:
    case BTN_LONGCLICK:
    switch (mode) {
        /* сек */ case 1:
          myRTC.setSecond(0);
        break;
        /* мин */ case 2:
          myRTC.setMinute(minutes == 59 ? 0 : minutes +1);
          break;
        /* час */ case 3:
          myRTC.setHour(hours == 23 ? 0 : hours + 1);
          break;
        /* дни */ case 4:
          myRTC.setDate(date == 31 ? 1 : date +1);
          break;
        /* мес */ case 5:
          myRTC.setMonth(month == 12 ? 1 : month +1);
          break;
        /* год */ case 6:
          myRTC.setYear(year == 99 ? 0 : year + 1);
         break;
        /* д.н.*/ case 7:
          myRTC.setDoW(DoW == 7 ? 1 : DoW + 1);
          break;
    }
    break;
  }
  switch (downButt.getButtonState()) {
    case BTN_ONECLICK:
    case BTN_LONGCLICK:
       switch (mode) {
      /* сек */ case 1:
        myRTC.setSecond(0);
        break;
      /* мин */ case 2:
        myRTC.setMinute(minutes == 0 ? 59 : minutes - 1);
        break;
      /* час */ case 3:
        myRTC.setHour(hours == 0 ? 23 : hours - 1);
        break;
      /* дни */ case 4:
        myRTC.setDate(date == 1 ? 31 : hours - 1);
        break;
      /* мес */ case 5:
        myRTC.setMonth(month == 1 ? 12 : month - 1);
        break;
      /* год */ case 6:
        myRTC.setYear(year == 1 ? 99 : year - 1);
        break;
      /* д.н.*/ case 7:
        myRTC.setDoW(DoW == 1 ? 7 : DoW - 1);
        break;
    }
    break;
  }
}
ShowEmptyPlace();
}
void ShowEmptyPlace() {
  if (mode) {
    if (millis() - emptyTimer > 1000) {
      emptyTimer = millis();
      switch (mode) {
        case 1:
          LC.setChar(0, 5, 0b0100000, false);
          LC.setChar(0, 4, 0b0100000, false);
          break;
        case 2:
          LC.setChar(0, 2, 0b0100000, false);
          LC.setChar(0, 3, 0b0100000, true);
          break;
        case 3:
          LC.setChar(0, 0, 0b0100000, false);
          LC.setChar(0, 1, 0b0100000, true);
          break;
        case 4:
          LC.setChar(1, 0, 0b0100000, false);
          LC.setChar(1, 1, 0b0100000, true);
          break;
        case 5:
          LC.setChar(1, 2, 0b0100000, false);
          LC.setChar(1, 3, 0b0100000, true);
          break;
        case 6:
          LC.setChar(1, 6, 0b0100000, false);
          LC.setChar(1, 7, 0b0100000, false);
          break;
        case 7:
          LC.setChar(0, 6, 0b0100000, false);
          LC.setChar(0, 7, 0b0100000, false);
          break;
      }
    }
  }
}
void isr_oneSecond(){
  ShowTime();
  return;
}

Вроде работает, потроху снабжаю комментариями