Часы.как добавить обработчик нажатия кнопок

Тема в разделе "Arduino & Shields", создана пользователем blackflash2009, 8 фев 2025.

  1. Не могу объединить 2 скется : 1 это часы ( считывается время с ртс DS3231 модуля время и выводит его на дисплей TM1637) , 2 это обработчик нажатия кнопок ( тоже работает через сериал проверял ). При объединении этих скетчей ртс модуль обнуляет время а кнопки не работают. Может кто помочь ?
    Код (C++):
    #include <Wire.h>
    #include "Sodaq_DS3231.h"
    #include "GyverTM1637.h"
    #define CLK PD6
    #define DIO PC4
    GyverTM1637 disp(CLK, DIO);
    // DateTime dt(2025, 2, 8, 21, 23, 0, 5); // год, месяц, день, час, минута, ....
    //Раскоментировать для первой прошивки для записи времени в модуль ртс
    unsigned long timing; // Переменная для хранения точки отсчета для работы милис
    boolean flag; //флаг для работы двоеточия
    void setup ()
    {
        Wire.begin();
        rtc.begin();
    //  rtc.setDateTime(dt); //Раскоментировать для первой прошивки для записи времени в модуль ртс
        disp.clear();
        disp.brightness(5);  // яркость, 0 - 7 (минимум - максимум)
    }
    void loop ()
    {
    DateTime now = rtc.now(); // Читае время
    // часы
    disp.displayClockTwist(now.hour(), now.minute(), 35);    // выводим время now.hour() переменная часы , now.minute() переменная для минут
       //функция мегания светодиодом
       if (millis() - timing > 500){ // 500 значение паузы
          timing = millis();
          flag = !flag;
          disp.point(flag);   // выкл/выкл точки
    }
    }
     
  2. Код (C++):
    #define BTN1 PD4   // кнопка подключена сюда (BTN_PIN --- КНОПКА --- GND)
    #define BTN2 PD3
    #include "GyverButton.h"
    GButton butt1(BTN1);
    GButton butt2(BTN2);
    int8_t hour ;
    int8_t minute ;

    //
    void setup() {
     
      Serial.begin(9600);
    }

    void loop() {
      butt1.tick();  // обязательная функция отработки. Должна постоянно опрашиваться
        butt2.tick();  // обязательная функция отработки. Должна постоянно опрашиваться
    // Установка часов
    if (butt1.isPress()) {  // Если кнопка нажата
        hour++;                               // пребавляем единицу к часу
        if (hour > 23) hour = 0;  // если вылезли за границы присваеваем 0
         Serial.println(hour);
       
       
        }
    // Установка часов работае

            if (butt2.isPress()){           // Если кнопка нажата
             minute++;                       // прибавляем минуту
             if (minute > 59) minute = 0;    // проверяем
             Serial.println(minute);        
                 
          }

       
         }        
     
     
  3. parovoZZ

    parovoZZ Гуру

    верхний код ничего не знает про
    Код (C++):
    int8_t hour ;
    int8_t minute ;
    А нижний не знает ничего
    Код (C++):
    DateTime now
    Не удивительно, что ничего не работает.

    Вообще, начинать надо с алгоритма, т.к. любое программирование для процессора - это последовательный алгоритм.
     
  4. Проблема в том что не получается прописать новые значения времени в ртс. По отдельности все работает а вот вместе нет
    Код (C++):
    #include <Wire.h>
    #include "Sodaq_DS3231.h"
    #include "GyverTM1637.h"
    #include "GyverButton.h"
    #define BTN1 PD4   // кнопка подключена сюда (BTN_PIN --- КНОПКА --- GND)
    #define BTN2 PD3
    #define CLK PD6
    #define DIO PC4
            //
    GButton butt1(BTN1);
    GButton butt2(BTN2);
    uint8_t hour ;
    uint8_t minute ;


             //
    GyverTM1637 disp(CLK, DIO);
    //DateTime dt(2025, 2, 4, 21, 38, 0, 5); // год, месяц, день, час, минута, ....
    //Раскоментировать для первой прошивки для записи времени в модуль ртс
    unsigned long timing; // Переменная для хранения точки отсчета для работы милис
    boolean flag; //флаг для работы двоеточия
    void setup ()
    {
        Wire.begin();
        rtc.begin();
    //   rtc.setDateTime(dt); //Раскоментировать для первой прошивки для записи времени в модуль ртс
        disp.clear();
        disp.brightness(5);  // яркость, 0 - 7 (минимум - максимум)
    }

    void loop ()
    {
    DateTime now = rtc.now(); // Читае время
    butt1.tick();  // обязательная функция отработки. Должна постоянно опрашиваться
        butt2.tick();  // обязательная функция отработки. Должна постоянно опрашиваться
    // Установка часов
    if (butt1.isPress()) {  // Если кнопка нажата
        hour++;                               // пребавляем единицу к часу
        if (hour > 23) hour = 0;  // если вылезли за границы присваеваем 0
         DateTime dt(2025, 2, 4, hour, minute, 0, 5); // год, месяц, день, час, минута, ....

          Wire.begin();
        rtc.begin();
      rtc.setDateTime(dt); //Раскоментировать для первой прошивки для записи времени в модуль ртс
    }
    // Установка минут
            if (butt2.isPress()){           // Если кнопка нажата
             minute++;                       // прибавляем минуту
             if (minute > 59) minute = 0;    // проверяем
                 
    DateTime dt(2025, 2, 4, hour, minute, 0, 5); // год, месяц, день, час, минута, ....
    Wire.begin();
        rtc.begin();
      rtc.setDateTime(dt); //Раскоментировать для первой прошивки для записи времени в модуль ртс
    }
            // часы
         
    disp.displayClockTwist(now.hour(), now.minute(), 35);    // выводим время now.hour() переменная часы , now.minute() переменная для минут
       //функция мегания светодиодом
       if (millis() - timing > 500){ // 500 значение паузы
          timing = millis();
          flag = !flag;
          disp.point(flag);   // выкл/выкл точки
    }
    }
     
  5. parovoZZ

    parovoZZ Гуру

    так наверное надо сперва выставить время, а только потом однократно записать в модуль. А если постоянно лупить записью в модуль, то он сойдёт с ума. Наверное.
     
    DetSimen нравится это.
  6. Разве он входит в цикл установки времени без нажатой кнопки ? Мне кажет в модуль не пишется вообще ничего
     
  7. parovoZZ

    parovoZZ Гуру

    а где-то в коде спрятан ещё один цикл? Я вижу только один:
     
    Ariadna-on-Line нравится это.
  8. Возможно я не прав
    Код (C++):
    if (butt1.isPress()) {  // Если кнопка нажата
    Цикл фор если кнопка нажата то выполняем действие, если не нажато то пропускаем. Разве это не так работает ?
    Я понимаю что каждое нажатие кнопки вызывает запись значения в ртс попробовал исправить это. При нажатии кнопке загорается " : " а дальше сам по себе выходит из цикла установки времени хотя должен находится в нем бесконечно пока не нажму кнопку выхода
    Код (C++):
    butt1.tick();
       
       if (butt1.isPress()){               // Если надавили сет
         butt2.tick();
         second = 0;                           // сбрасываем секунды
         disp.point(1);                      // включаем ":"
          do{   /// Крутим цикл! /// часы
         
         
            if (butt2.isPress()){           // если в цикле надавили на "+"
               hour++;                               // пребавляем единицу к часу
               if (hour > 23) hour = 0;              // если вылезли за границы присваеваем 0
                   
            }
            disp.displayClockTwist(hour, minute, 10);            // в цикле также показываем что получилось
          butt1.tick();
           butt2.tick();
         }while(butt1.isPress());          // крутимся пока не надавили сет    
          butt1.tick();
           butt2.tick();
       
         do{     // снова крутимся, но уже для минут.
            butt1.tick();
           butt2.tick();
     
            if (butt2.isPress()){           // также смотрим не нажато ли "+"
               minute++;                       // прибавляем минуту
               if (minute > 59) minute = 0;    // проверяем
            disp.displayClockTwist(hour, minute, 10);   // отправляем массив на экран  
               delay(200);    
            }
            butt1.tick();
           butt2.tick();
         }while(butt1.isPress());          // крутимся пока не надавили сет    
          delay(200);                          // задумываемся перед выходом
          Wire.begin();
                 rtc.begin();
                   DateTime dt(2025, 2, 4, hour, minute, 0, 5); // год, месяц, день, час, минута, ....
                   rtc.setDateTime(dt);
                   DateTime now = rtc.now(); // Читае время
      }
           
            // часы
       
    disp.displayClockTwist(now.hour(), now.minute(), 35);    // выводим время now.hour() переменная часы , now.minute() переменная для минут
       //функция мегания светодиодом
     
      if ((millis() - timing) > 500){ // 500 значение паузы
         butt1.tick();
           butt2.tick();
        timing = millis();
          flag = !flag;
          disp.point(flag);   // выкл/выкл точки
         
    }
     
  9. parovoZZ

    parovoZZ Гуру

    Я уже показывал, как работать с кнопкой. Кнопка одна - функций много.
    https://forum.amperka.ru/threads/Одна-кнопка-один-диммер.21207/

    Проще всего - на машине состояний. Ещё проще - с применением ОС.
    При работе с кнопкой обязательно необходим таймер реального времени, т.к. сам МК работает очень быстро и все процессы внутри него также происходят очень быстро.
     
  10. Думаете успевает переключится за 1 нажатия несколько раз ? В библиотеке
    GyverButton уже учтен дребезг контактов. Я думаю что мк считает что я кнопки нажал. Возможно нужно конфигурировать выходы мк ch32v003j4m6. В общем проект и тема закрыта. Буду ждать когда кто поумней возьмется
     
    Последнее редактирование: 13 фев 2025
  11. Asper Daffy

    Asper Daffy Иксперд

    :D
     
    Feofan, parovoZZ и DetSimen нравится это.
  12. parovoZZ

    parovoZZ Гуру

    а где в коде цикл FOR(){}?
    Кнопку достаточно опрашивать с периодом не менее 20-50 мс, чтобы не попасть на дребезг контактов. Да и речь вовсе не про дребезг, а про алгоритмическую ошибку в алгоритме.

    его библиотеки здесь не любят, т.к. название метода
    хрен пойми вообще о чём. Дословно это переводится
    Кому нажать, зачем нажать...
     
  13. Asper Daffy

    Asper Daffy Иксперд

    Ну, как где, ТС же ясно показал:

    upload_2025-2-13_17-50-18.png

    Ты, чё, не знаешь как цикл for выглядит, что ли?

    :)
     
  14. parovoZZ

    parovoZZ Гуру

    а, я понял, белый шрифт.
     
  15. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Может и не так. А так как заложил разработчик. Функция может работать либо на состояние "нажатости", либо на процесс "нажимания", а может и на процесс "отпускания". Так что тут надо читать комментарии разработчика. Например работа на состоянии "нажатости" - чревата проблемами при "заклинивании" кнопки. У Гайвера видел вполне подробные описания функций его библиотек. Так что - читайте.

    ПС. Вот кусок кода для PIC - процессора. Здесь защита от запуска с подачей питания при залипшей клавиатуре, и защита запуска от случайного кратковременного нажатия. Код для "неторопливого" девайса (массажная подушка), поэтому работает на delay-ях. А вот код остановки по кнопке - работает без делаев, для безопасности пользователя. Выложить текстом не могу, тк руско-язычные комментарии Протона здесь выходят "кракозябрами".
     

    Вложения:

    • Кн1.png
      Кн1.png
      Размер файла:
      37,4 КБ
      Просмотров:
      10
    • Кн2.png
      Кн2.png
      Размер файла:
      11,9 КБ
      Просмотров:
      10
    Последнее редактирование: 14 фев 2025