Цикличная работа двух таймеров на TM1637

Тема в разделе "Arduino & Shields", создана пользователем MontiMonolitov, 25 окт 2017.

  1. MontiMonolitov

    MontiMonolitov Нерд

    Не получается добиться правильной работы модуля на TM1637
    Задача:
    Включаем, "timer_val" работает как обратный отсчет 2 мин, после того как будет нуль запускается "timer_val1", то же обратный отсчет и так поочереди.
    Но у меня после окончания счета "timer_val1" опять и опять запускается "timer_val1".
    Что-то я совсем запутался, как это исправить
    После исправления будет еще добавлена работа pin2
    при работе "timer_val" - pin2,HIGH
    при работе "timer_val1" - pin2,LOW

    Код (C++):
    #include "TM1637.h" // подключение библиотеки
    #define CLK A0
    #define DIO A1
    #define Pulse 2 // Выход для сигнализации
    int timer_val=2; // Обратный отсчет в минутах
    int timer_val1=1; // Обратный отсчет в минутах
    int timer_seconds=00; // Отображение секунд
    // Переменные для хранения индивидуальных номеров
    int firstnum=0;
    int secondnum=0;
    int thirdnum=0;
    int fournum=0;
    TM1637 tm1637(CLK,DIO); // Настройка индикатора
    void setup(){
       pinMode(Pulse, OUTPUT);
       digitalWrite(Pulse, LOW);
       tm1637.init(); // Сброс дисплея
       tm1637.set(BRIGHT_TYPICAL); // Уровень яркости
       // BRIGHT_DARKEST = 0,BRIGHTEST = 7 BRIGHT_TYPICAL = 2;
       tm1637.point(POINT_ON); // Активация точки посредине
       delay(1000); // Задержка 1 секунда
    }
    void loop() {
      // Проверка, запустился ли таймер
       while (timer_val == 0 && timer_seconds == 0) {
          // Распределяем минуты и сикунды по отдельным сегментам
       if (timer_val1 > 9) {
          firstnum = timer_val1/10%10;
          secondnum = timer_val1%10;
       }
       else {
          secondnum = timer_val1;
       }
       if (timer_seconds > 9) {
          thirdnum = timer_seconds/10%10;
          fournum = timer_seconds%10;
       }
       else {
          thirdnum = 0;
          fournum = timer_seconds;
       }
       // Отображаем обратный отсчет
       tm1637.clearDisplay(); // Очистка дисплея
       if (timer_val1 > 9) {
          tm1637.display(0,firstnum);
       }
       if (timer_val1 > 0) {
          tm1637.display(1,secondnum);
       }
       if (timer_seconds > 9 || timer_val1 > 0) {
          tm1637.display(2,thirdnum);
       }
       tm1637.display(3,fournum);
       // Decrease seconds
       timer_seconds=timer_seconds-1;
       delay(1000); // Delay of 1 second
       // Decrease timer
       if (timer_seconds == -1) {
          timer_val1=timer_val1-1;
          timer_seconds=59;
       }
       }
       
       // Распределяем минуты и сикунды по отдельным сегментам
       if (timer_val > 9) {
          firstnum = timer_val/10%10;
          secondnum = timer_val%10;
       }
       else {
          secondnum = timer_val;
       }
       if (timer_seconds > 9) {
          thirdnum = timer_seconds/10%10;
          fournum = timer_seconds%10;
       }
       else {
          thirdnum = 0;
          fournum = timer_seconds;
       }
       // Отображаем обратный отсчет
       tm1637.clearDisplay(); // Очистка дисплея
       if (timer_val > 9) {
          tm1637.display(0,firstnum);
       }
       if (timer_val > 0) {
          tm1637.display(1,secondnum);
       }
       if (timer_seconds > 9 || timer_val > 0) {
          tm1637.display(2,thirdnum);
       }
       tm1637.display(3,fournum);
       // Decrease seconds
       timer_seconds=timer_seconds-1;
       delay(1000); // Delay of 1 second
       // Decrease timer
       if (timer_seconds == -1) {
          timer_val=timer_val-1;
          timer_seconds=59;
       }
    }
     
  2. ORLENOK

    ORLENOK Гик

    Что-то в коде запутаться можно слишком просто...
    Я бы сделал так:
    1) Вывод на дисплей в виде отдельного метода
    2) Сделать переменную, которая отвечает за время начала интервала (вдумайтесь и поймите эту фразу), сделать переменную, которая отвечает за то, какой сейчас таймер запущен (может быть булевого типа, если два варианта работы таймера или enum, byte, int в других случаях, как удобно).
    3) Хранить массив, в котором будет указано время выполнения каждого периода в секундах.
    И по итогу получим:
    Запускаем, определяем через millis() время начала интервала, пока оно меньше продолжительности интервала - выводим время.
    Как только стало больше или равно, время начала интервала - текущее, счётчик

    Код (C++):
    int currentInterval = 0;
    int intervals[] = {120,60};
    ulong startInterval = 0;
    int currentTime = 0;
    void setup()
    {
       startInterval = millis(); //last line
    }
    void loop()
    {
       currentTime = (millis() - startInterval) / 1000;
       while(currentTime < intervals[currentInterval])
      {
        showTime(currentTime); //метод отображения времени
        delay(1000); //не уверен на счёт секунды
      }
      currentInterval = (currentInterval + 1 == intervals.length()) ? 0 : currentInterval + 1;
      startInterval = millis();
    }
    P.S. код писал на коленке
     
    Последнее редактирование: 25 окт 2017
  3. qwone

    qwone Гик

    Код (C++):
    unsigned long mill; // переменная под millis()
    //-----Cl_Manager---------------------------
    // класс менеджер задач
    struct task_t {
      void (*Do)();
      unsigned long past;
      unsigned int time;
      struct task_t (*next);
    };
    class Cl_Manager {
      protected:
        struct task_t (*start) = NULL;
      public:
        void run() {
          for (struct task_t (**i) = &start; (*i) != NULL; ) {
            if (mill - (**i).past >= (**i).time) {
              struct task_t (*_new) = (*i);
              (*i) = (**i).next;
              (*_new).Do();
              delete _new;
            }
            else i = &(**i).next;
          }
        }
        void Task(unsigned int time, void (*Do)()) {
          struct task_t (*_new) = new struct task_t;
          (*_new).Do = Do;
          (*_new).past = mill;
          (*_new).time = time;
          (*_new).next = start;
          start = _new;
        }
    };
    Cl_Manager Manager;
    //---Компоновка-----------------------
    // --serial
    void serial_1() {
      Manager.Task(/*через 0.5 сек*/ 500,/*сделать это*/&serial_2);
      Serial.println("1-one");
    }
    void serial_2() {
      Manager.Task(/*через 0.5 сек*/ 500,/*сделать это*/&serial_3);
      Serial.println("2-two");
    }
    void serial_3() {
      Manager.Task(/*через 0.5 сек*/ 500,/*сделать это*/&serial_4);
      Serial.println("3-three");
    }
    void serial_4() {
      Manager.Task(/*через 0.5 сек*/ 500,/*сделать это*/&serial_5);
      Serial.println("4-four");
    }
    void serial_5() {
      Manager.Task(/*через 0.5 сек*/ 500,/*сделать это*/&serial_1);
      Serial.println("5-five");
    }
    //---main-----------------------------
    void setup() {
      Serial.begin(9600);
      serial_1();
    }

    void loop() {
      mill = millis();
      Manager.run();
    }
    /*Скетч использует 2400 байт (7%) памяти устройства. Всего доступно 30720 байт.
      Глобальные переменные используют 236 байт (11%) динамической памяти, оставляя 1812 байт для локальных переменных. Максимум: 2048 байт.
    */
     
  4. MontiMonolitov

    MontiMonolitov Нерд

    Не совсем понял, как запустить два таймера, а так же значение в последней строке intervals.length()) ? 0 :
     
  5. MontiMonolitov

    MontiMonolitov Нерд

    попробовал с использованием библиотеки <Thread.h> , то же не корректная работа, здесь таймеры работают одновременно

    Код (C++):
    #include "TM1637.h" // подключение библиотеки
    #define CLK A0
    #define DIO A1
    #define Pulse 2 // Выход для сигнализации
    int timer_val=2; // Обратный отсчет в минутах
    int timer_val1=1; // Обратный отсчет в минутах
    int timer_seconds=00; // Отображение секунд
    // Переменные для хранения индивидуальных номеров
    int firstnum=0;
    int secondnum=0;
    int thirdnum=0;
    int fournum=0;
    TM1637 tm1637(CLK,DIO); // Настройка индикатора

    #include <Thread.h>  // подключение библиотеки ArduinoThread
    const int soundPin = 3;  // переменная с номером пина пьезоэлемента
    const int ledPin = 13;  // переменная с номером пина светодиода
    Thread valThread = Thread(); // создаём поток управления светодиодом
    Thread valThread1 = Thread(); // создаём поток управления сиреной


    void setup()
    {
        pinMode(soundPin, OUTPUT); // объявляем пин 3 как выход.
        pinMode(ledPin, OUTPUT);   // объявляем пин 13 как выход.
        valThread.onRun(RAD);  // назначаем потоку задачу
        valThread.setInterval(2000); // задаём интервал срабатывания, мсек
        valThread1.onRun(NoRAD);     // назначаем потоку задачу
        valThread1.setInterval(1000); // задаём интервал срабатывания, мсек
     
       tm1637.init(); // Сброс дисплея
       tm1637.set(BRIGHT_TYPICAL); // Уровень яркости
       // BRIGHT_DARKEST = 0,BRIGHTEST = 7 BRIGHT_TYPICAL = 2&#894;
       tm1637.point(POINT_ON); // Активация точки посредине
     
    }
    void loop()
    {
        // Проверим, пришло ли время переключиться светодиоду:
        if (valThread.shouldRun())
            valThread.run(); // запускаем поток
       
        // Проверим, пришло ли время сменить тональность сирены:
        if (valThread1.shouldRun())
            valThread1.run(); // запускаем поток
    }

    void RAD()
      {
        // Распределяем минуты и сикунды по отдельным сегментам
       if (timer_val > 9) {
          firstnum = timer_val/10%10;
          secondnum = timer_val%10;
       }
       else {
          secondnum = timer_val;
       }
       if (timer_seconds > 9) {
          thirdnum = timer_seconds/10%10;
          fournum = timer_seconds%10;
       }
       else {
          thirdnum = 0;
          fournum = timer_seconds;
       }
     
       // Отображаем обратный отсчет
       tm1637.clearDisplay(); // Очистка дисплея
       if (timer_val > 9) {
          tm1637.display(0,firstnum);
       }
       if (timer_val > 0) {
          tm1637.display(1,secondnum);
       }
       if (timer_seconds > 9 || timer_val > 0) {
          tm1637.display(2,thirdnum);
       }
       tm1637.display(3,fournum);
       // Decrease seconds
       timer_seconds=timer_seconds-1;
       delay(1000); // Delay of 1 second
       // Decrease timer
       if (timer_seconds == -1) {
          timer_val=timer_val-1;
          timer_seconds=59;
      }
      }
      void NoRAD()
      {
        // Распределяем минуты и сикунды по отдельным сегментам
       if (timer_val1 > 9) {
          firstnum = timer_val1/10%10;
          secondnum = timer_val1%10;
       }
       else {
          secondnum = timer_val1;
       }
       if (timer_seconds > 9) {
          thirdnum = timer_seconds/10%10;
          fournum = timer_seconds%10;
       }
       else {
          thirdnum = 0;
          fournum = timer_seconds;
       }
     
       // Отображаем обратный отсчет
       tm1637.clearDisplay(); // Очистка дисплея
       if (timer_val1 > 9) {
          tm1637.display(0,firstnum);
       }
       if (timer_val1 > 0) {
          tm1637.display(1,secondnum);
       }
       if (timer_seconds > 9 || timer_val1 > 0) {
          tm1637.display(2,thirdnum);
       }
       tm1637.display(3,fournum);
       // Decrease seconds
       timer_seconds=timer_seconds-1;
       delay(1000); // Delay of 1 second
       // Decrease timer
       if (timer_seconds == -1) {
          timer_val1=timer_val1-1;
          timer_seconds=59;
      }
      }
     
  6. qwone

    qwone Гик

    Вот код на 2 последовательно работающих таймера, разумеется с использованием менеджера.
    Код (C++):
    unsigned long mill; // переменная под millis()
    //-----Cl_Manager---------------------------
    // класс менеджер задач
    struct task_t {
      void (*Do)();
      unsigned long past;
      unsigned int time;
      struct task_t (*next);
    };
    class Cl_Manager {
      protected:
        struct task_t (*start) = NULL;
      public:
        void run() {
          for (struct task_t (**i) = &start; (*i) != NULL; ) {
            if (mill - (**i).past >= (**i).time) {
              struct task_t (*_new) = (*i);
              (*i) = (**i).next;
              (*_new).Do();
              delete _new;
            }
            else i = &(**i).next;
          }
        }
        void Task(unsigned int time, void (*Do)()) {
          struct task_t (*_new) = new struct task_t;
          (*_new).Do = Do;
          (*_new).past = mill;
          (*_new).time = time;
          (*_new).next = start;
          start = _new;
        }
    };
    Cl_Manager Manager;
    //---Компоновка-----------------------
    // --serial
    byte Timer1, Timer2;
    void Timer1Run() {
      Serial.print("Timer1:");
      Serial.print(Timer1);
      Serial.println();
      --Timer1;
      if (Timer1 > 0) {
        Manager.Task(/*через 0.5 сек*/ 500,/*сделать это*/&Timer1Run);
      }
      else {
        Timer2 = 10;
        Manager.Task(/*через 0.5 сек*/ 500,/*сделать это*/&Timer2Run);
      }
    }
    void Timer2Run() {
      Serial.print("Timer2:");
      Serial.print(Timer2);
      Serial.println();
      --Timer2;
      if (Timer2 > 0) Manager.Task(/*через 0.5 сек*/ 500,/*сделать это*/&Timer2Run);
      else {
        Timer1 = 10;
        Manager.Task(/*через 0.5 сек*/ 500,/*сделать это*/&Timer1Run);
      }
    }
    //---main-----------------------------
    void setup() {
      Serial.begin(9600);
      Timer1 = 10;
      Manager.Task(/*через 0.5 сек*/ 500,/*сделать это*/&Timer1Run);
    }

    void loop() {
      mill = millis();
      Manager.run();
    }
    /*Скетч использует 2610 байт (8%) памяти устройства. Всего доступно 30720 байт.
      Глобальные переменные используют 220 байт (10%) динамической памяти, оставляя 1828 байт для локальных переменных. Максимум: 2048 байт.
    */
     
  7. logomind

    logomind Нерд

    А зачем самому придумывать какие-то переменные для времени, почему не использовать функцию time? https://www.arduino.cc/en/Reference/Millis
    Запускаете таймер - записываете время запуска, а в цикле проверяете прошло ли нужное время.

    Точность этих строк очень сомнительна, будет явно больше секунды
    Код (C++):
     timer_seconds=timer_seconds-1;
       delay(1000);
     
  8. ORLENOK

    ORLENOK Гик

    У вас же два таймера работают последовательно? Сначала первый отрабатывает, потом второй, верно?
    Последняя строка - это тернарный оператор. Можно расписать, как if else.

    Код (C++):
    #include "TM1637.h" // подключение библиотеки
    #define CLK A0
    #define DIO A1
    #define Pulse 2 // Выход для сигнализации
    TM1637 tm1637(CLK,DIO); // Настройка индикатора

    int currentInterval =0; //номер текущего интервала
    int intervals[]={120,60}; //длина интервалов в секундах, в массиве
    ulong startInterval =0; //время начала текущего интервала
    int currentTime =0; // прошедшее время с начала текущего интервала в секундах

    void setup(){
       pinMode(Pulse, OUTPUT);
       digitalWrite(Pulse, LOW);
       tm1637.init(); // Сброс дисплея
       tm1637.set(BRIGHT_TYPICAL); // Уровень яркости
       // BRIGHT_DARKEST = 0,BRIGHTEST = 7 BRIGHT_TYPICAL = 2&#894;
       tm1637.point(POINT_ON); // Активация точки посредине
       delay(1000); // Задержка 1 секунда
    }
    void loop()
    {
       currentTime =(millis()- startInterval)/1000;
       while(currentTime < intervals[currentInterval])
       {
          showTime();//метод отображения времени
          delay(1000);//не уверен на счёт секунды
          currentTime =(millis()- startInterval)/1000;
       }
      currentInterval =(currentInterval +1== intervals.length())?0: currentInterval +1;
      startInterval = millis();
    }
    void showTime()
    {
       tm1637.clearDisplay();// Очистка дисплея
       int seconds = currentTime % 60; //количество секунд
       int mins = currentTime / 60; //количество минут

       tm1637.display(0,seconds%10); //не уверен на счёт индексов в самих модулях, возможно нужно использовать не 0, а 3. Ну и в других также
       if(seconds > 9)
          tm1637.display(1,seconds/10);
       if(mins > 0)
          tm1637.display(2,mins%10);
       if(mins > 9)
          tm1637.display(3,mins/10);
    }
     
     
  9. MontiMonolitov

    MontiMonolitov Нерд

    Код (C++):
      }
      currentInterval =(currentInterval +1== intervals.length())?0: currentInterval +1;
      startInterval = millis();
    }
    Ну вот как и в первый раз выдает ошибку


    sketch_oct27a.ino: In function 'void loop()':
    sketch_oct27a:30: error: request for member 'length' in 'intervals', which is of non-class type 'int [2]'
    request for member 'length' in 'intervals', which is of non-class type 'int [2]'
     
  10. b707

    b707 Гуру

    С чего вы взяли, что так можно вызывать - intervals.length() ? Что это за метод length() вдруг у массива появился? Вы с питоном или перлом не попутали случаем?

    И вообще, вся эта строка - это попытка исполнить тройной прыжок тем, кто вчера на коньки встал. Если вы не чувствуете кода - не лезте в дебри, пишите простыми операторами.

    И поправьте заголовк. Ваш вопрос к дисплею не имеет ни малейшего отношения.
     
  11. MontiMonolitov

    MontiMonolitov Нерд

    Да, не чувствовать кода это зло. Я не супер програмист переделал код как я его понимаю и он почти работает, но есть большое НО, при запуске светодиод включается и выключается по заданному времени как надо, на дисплее 2 мин отсчитываются как надо, потом идет пауза 10 сек на дисплее (11:11), и вот когда таймер запускается второй раз (он отсчитывает установленные 2 мин), но на дисплее горят только секунды (3-й и 4- сигменты). Где у меня ошибка в отображении на дисплее?
    Код (C++):
    #include "TM1637.h" // подключение библиотеки
    #define CLK 11
    #define DIO 12
    int ledPin = 13; // номер пина со светодиодом
    int ledState = LOW; // состояние светодиода
    int timer_val1=2; // Обратный отсчет в минутах
    int timer_seconds1=00; // Отображение секунд
    // Переменные для хранения индивидуальных номеров
    int firstnum=0;
    int secondnum=0;
    int thirdnum=0;
    int fournum=0;
    TM1637 tm1637(CLK,DIO); // Настройка индикатора
    unsigned long previousMillis = 0;
    long OnTime = 120000; // длительность свечения светодиода (в миллисекундах)
    long OffTime = 10000; // светодиод не горит (в миллисекундах)

    void setup(){
       pinMode(ledPin, OUTPUT);
       tm1637.init(); // Сброс дисплея
       tm1637.set(BRIGHT_TYPICAL); // Уровень яркости
       // BRIGHT_DARKEST = 0,BRIGHTEST = 7 BRIGHT_TYPICAL = 2&#894;
       tm1637.point(POINT_ON); // Активация точки посредине
       delay(1000); // Задержка 1 секунда
    }
    void loop() {
      Blinck();
      timer();
      clining();
      }

    void Blinck(){
      // выясняем не настал ли момент сменить состояние светодиода
      unsigned long currentMillis = millis(); // текущее время в миллисекундах
     
      // если светодиод включен и светится больше чем надо
      if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
      {
        ledState = LOW; // выключаем
        previousMillis = currentMillis; // запоминаем момент времени
        digitalWrite(ledPin, ledState); // реализуем новое состояние
      }
      else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
      {
        ledState = HIGH; // выключаем
        previousMillis = currentMillis ; // запоминаем момент времени
        digitalWrite(ledPin, ledState); // реализуем новое состояние
      }
    }
    void timer(){
       if (ledState == HIGH) {
            // Распределяем минуты и сикунды по отдельным сегментам
       if (timer_val1 > 9) {
          firstnum = timer_val1/10%10;
          secondnum = timer_val1%10;
       }
       else {
          secondnum = timer_val1;
       }
       if (timer_seconds1 > 9) {
          thirdnum = timer_seconds1/10%10;
          fournum = timer_seconds1%10;
       }
       else {
          thirdnum = 0;
          fournum = timer_seconds1;
       }
     
     
    // Отображаем обратный отсчет
       tm1637.clearDisplay(); // Очистка дисплея
       if (timer_val1 > 9) {
          tm1637.display(0,firstnum);
       }
       if (timer_val1 > 0) {
          tm1637.display(1,secondnum);
       }
       if (timer_seconds1 > 9 || timer_val1 > 0) {
          tm1637.display(2,thirdnum);
       }
       tm1637.display(3,fournum);
       // Decrease seconds
       timer_seconds1=timer_seconds1-1;
       delay(1000);
       // Decrease timer
       if (timer_seconds1 == -1) {
          timer_val1=timer_val1-1;
          timer_seconds1=59;
       }
    }
    }
    void clining(){
    // Проверка, запустился ли таймер
       if (ledState == LOW) {
          tm1637.clearDisplay(); // Очистка дисплея
          tm1637.display(0,1);
          tm1637.display(1,1);
          tm1637.display(2,1);
          tm1637.display(3,1);
           delay(300);
           tm1637.clearDisplay(); // Очистка дисплея
          delay(300);
       }
    }
    .
     
  12. ORLENOK

    ORLENOK Гик

    Что же такого гипер сложного в этой строке?
    Код (C++):
    currentInterval =(currentInterval +1== sizeof(intervals)/sizeof(int)) ? 0 : currentInterval +1;
    Окей, да, мой косяк, метода length нет. Писал не в arduinoIDE, а в браузере и не смогу проверить все ошибки.
    Если текущий интервал +1 = размеру массива, то текущий интервал 0, иначе текущий интервал +1.
    Если бы у меня были все необходимые модули, я бы обязательно проверил перед отправкой, а так это просто интерес.
    Код (C++):
    #include "TM1637.h" // подключение библиотеки
    #define CLK A0
    #define DIO A1
    #define Pulse 2 // Выход для сигнализации
    TM1637 tm1637(CLK,DIO); // Настройка индикатора

    int currentInterval =0; //номер текущего интервала
    int intervals[]={120,60}; //длина интервалов в секундах, в массиве
    ulong startInterval =0; //время начала текущего интервала
    int currentTime =0; // прошедшее время с начала текущего интервала в секундах

    void setup(){
       pinMode(Pulse, OUTPUT);
       digitalWrite(Pulse, LOW);
       tm1637.init(); // Сброс дисплея
       tm1637.set(BRIGHT_TYPICAL); // Уровень яркости
       // BRIGHT_DARKEST = 0,BRIGHTEST = 7 BRIGHT_TYPICAL = 2&#894;
       tm1637.point(POINT_ON); // Активация точки посредине
       delay(1000); // Задержка 1 секунда
    }
    void loop()
    {
       currentTime =(millis()- startInterval)/1000;
       while(currentTime < intervals[currentInterval])
       {
          if(currentInterval % 2 == 0)
          {
             showTime(); //метод отображения времени
          }
          currentTime =(millis()- startInterval)/1000;
          delay(200);
       }
      tm1637.clearDisplay(); // Очистка дисплея
      currentInterval =(currentInterval + 1 == sizeof(intervals)/sizeof(int)) ? 0 : currentInterval +1;
      startInterval = millis();
    }
    void showTime()
    {
       tm1637.clearDisplay();// Очистка дисплея
       int seconds = currentTime % 60; //количество секунд
       int mins = currentTime / 60; //количество минут

       tm1637.display(0,seconds%10); //не уверен на счёт индексов в самих модулях, возможно нужно использовать не 0, а 3. Ну и в других также
       if(seconds > 9)
          tm1637.display(1,seconds/10);
       if(mins > 0)
          tm1637.display(2,mins%10);
       if(mins > 9)
          tm1637.display(3,mins/10);
    }
     
     
  13. MontiMonolitov

    MontiMonolitov Нерд

    Таймер идет вперед, а не обратный отсчет ))

     
  14. ORLENOK

    ORLENOK Гик

    Тогда метод сделать такой:

    Код (C++):
    void showTime()
    {
       tm1637.clearDisplay();// Очистка дисплея
       int showingTime = intervals[currentInterval] - currentTime; //добавил эту строку. Берём время текущего интервала и вычитаем время прошедшее с начала интервала.
       int seconds = showingTime % 60; //количество секунд
       int mins = showingTime / 60; //количество минут

       tm1637.display(0,seconds%10); //не уверен на счёт индексов в самих модулях, возможно нужно использовать не 0, а 3. Ну и в других также
       if(seconds > 9)
          tm1637.display(1,seconds/10);
       if(mins > 0)
          tm1637.display(2,mins%10);
       if(mins > 9)
          tm1637.display(3,mins/10);
    }
    Вообще в код будет вести обратный отсчёт для каждого четного элемента в intervals и ничего не отображать для каждого нечетного. Т.е. если intervals = {60,30,120,60}; - то будет отсчёт с 60 до 0, потом 30 сек тишины, потом отсчёт с 120 до 0, потом 60 сек тишины и заново.
     
  15. MontiMonolitov

    MontiMonolitov Нерд

    В ответе №11 я описал что не корректно работает в моем коде, кто подскажет как исправить, буду благодарен.
    Код Орленка по работе дисплея после мелких исправление отлично работает, осталось только прицепить светодиод.
     
  16. MontiMonolitov

    MontiMonolitov Нерд

    Может быть криво-косо, но код работает, спасибо все кто помог словом-делом
    Код (C++):
    #include "TM1637.h" // подключение библиотеки
    #define CLK 11
    #define DIO 12
    int ledPin = 13; // номер пина со светодиодом
    int ledState = LOW; // состояние светодиода
    TM1637 tm1637(CLK,DIO); // Настройка индикатора

    int currentInterval =0; //номер текущего интервала
    int intervals[]={120,10,60,5}; //длина интервалов в секундах, в массиве
    long startInterval =0; //время начала текущего интервала
    int currentTime =0; // прошедшее время с начала текущего интервала в секундах

    unsigned long previousMillis = 0;
    long OnTime = 10; // длительность свечения светодиода (в миллисекундах)
    long OffTime = 10; // светодиод не горит (в миллисекундах)

    void setup(){
      pinMode(ledPin, OUTPUT);
       tm1637.init(); // Сброс дисплея
       tm1637.set(BRIGHT_TYPICAL); // Уровень яркости
       // BRIGHT_DARKEST = 0,BRIGHTEST = 7 BRIGHT_TYPICAL = 2&#894;
       tm1637.point(POINT_ON); // Активация точки посредине
       delay(1000); // Задержка 1 секунда
    }
    void loop()
    {
      Blinck();
       currentTime =(millis()- startInterval)/1000;
       while(currentTime < intervals[currentInterval])
       {
          if(currentInterval % 2 == 0)
          {
             showTime(); //метод отображения времени
           
          }
          currentTime =(millis()- startInterval)/1000;
          delay(200);
       }
      tm1637.clearDisplay(); // Очистка дисплея
      currentInterval =(currentInterval + 1 == sizeof(intervals)/sizeof(int)) ? 0 : currentInterval +1;
      startInterval = millis();
     
    }
    void showTime()
    {
       tm1637.clearDisplay();// Очистка дисплея
     
       int showingTime = intervals[currentInterval] - currentTime;
       int seconds = showingTime % 60; //количество секунд
       int mins = showingTime / 60; //количество минут

       tm1637.display(3,seconds%10);
       if(seconds > 9)
          tm1637.display(2,seconds/10);
       if(mins > 0)
          tm1637.display(1,mins%10);
       if(mins > 9)
          tm1637.display(0,mins/10);
    }
    void Blinck(){
      // выясняем не настал ли момент сменить состояние светодиода
      unsigned long currentMillis = millis(); // текущее время в миллисекундах
      // если светодиод включен и светится больше чем надо
      if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
      {
        ledState = LOW; // выключаем
        previousMillis = currentMillis; // запоминаем момент времени
        digitalWrite(ledPin, ledState); // реализуем новое состояние
      }
      else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
      {
        ledState = HIGH; // включаем
        previousMillis = currentMillis ; // запоминаем момент времени
        digitalWrite(ledPin, ledState); // реализуем новое состояние
      }
    }