Повторяющийся таймер

Привет! Новый в Arduino))
Написал код, по которому таймер устанавливается двумя кнопками: секунды и десятые секунды. Затем отрабатывает шаговый двигатель. Все работает прекрасно, но: мне нужен цикличный таймер. Т.е., чтобы после того как закончилось время таймер и двигатель отработал, таймер вставал на поставленные значения и, при нажатии кнопки, повторил цикл. Пока что, получается одноразовый таймер. Не могу перенести переменную из цикла. Подставляет 1.1 каждый раз. Вот код:

#include "Wire.h"                              // библиотека для протокола I2C
#include "LiquidCrystal_I2C.h"        // библиотека для LCD 1602 
LiquidCrystal_I2C LCD(0x27, 20, 2);  // присваиваем имя дисплею

boolean button1WasUp = true;      // переменные для считывания нажатий кнопок
boolean button2WasUp = true;
boolean button3WasUp = true;
boolean button4WasUp = true;

byte w = 0;

int SEC=button1WasUp;   // переменные для отсчета секунд и десятых секунд
int DSEC=button2WasUp;

unsigned long timer;

// Перменные движка!!!

//Пины управления шаговиком
#define STEP_PIN         9
#define DIR_PIN          10
#define ENABLE_PIN       11

//Пин кнопки
#define start_button 12

//

> Впишите сюда текст цитаты

время поворота и паузы
#define move_forward_time 200    //время прямого хода в мсек
#define move_back_time 200       //время обратного хода в мсек
#define pause_time 500           //время паузы в мсек
#define frequency 200            //Время между импульсами в мксек. 1000 мксек = 1 мсек = 0.001 сек. Частота следования импульсов 1/0.001 = 1 кГц, 

//Логический флаг для рабочего режима
bool flag = 0;



void setup() {
//тактовые кнопки
   pinMode(2, INPUT_PULLUP);  //+секунда
   pinMode(4, INPUT_PULLUP);  //+десек
   pinMode(6, INPUT_PULLUP);  //start-stop
   
  

   LCD.init();                        // инициализация дисплея
   LCD.backlight();              // включение подсветки

   LCD.setCursor(3, 0);
   LCD.print("SET TIMER");
   LCD.setCursor(5, 1);
   LCD.print(SEC);
   LCD.print(" . ");
   LCD.print(DSEC);


  //Engine setup

  pinMode(start_button, INPUT_PULLUP);  //Подтягиваем кнопку к питанию

  pinMode(STEP_PIN   , OUTPUT);       //Настраиваем пины управления
  pinMode(DIR_PIN    , OUTPUT);
  pinMode(ENABLE_PIN , OUTPUT);

  digitalWrite(ENABLE_PIN , HIGH);    //Выключаем мотор, чтобы не грелся
}

void loop() {
   boolean button1IsUp = digitalRead(2);   // узнаем текущее состояние кнопок
   boolean button2IsUp = digitalRead(4);
   boolean button3IsUp = digitalRead(6);

// при нажатии на 2 прибавляем сек и выводим на дисплей
if (button2WasUp && !button2IsUp) {
      delay(10); 
      button2IsUp = digitalRead(4); 
      if (!button2IsUp) { 
         SEC = SEC + 1; //DSEC = 0; 
           if (SEC>10){SEC=0;}
         LCD.clear(); 
         LCD.setCursor(3, 0); 
         LCD.print("SET TIMER"); 
         LCD.setCursor(5, 1); 
         LCD.print(SEC); 
         LCD.print(" . "); 
         LCD.print(DSEC);
      }
   } 
 button2WasUp = button2IsUp; // запоминаем состояние 2 
 
// при нажатии на 1 прибавляем десек и выводим на дисплей
   if (button1WasUp && !button1IsUp) {
      delay(10);
      button1IsUp = digitalRead(2);
      if (!button1IsUp) {
         DSEC = DSEC + 1; //SEC = 0;
         if (DSEC>9){DSEC=0;}
         LCD.clear(); 
         LCD.setCursor(3, 0); 
         LCD.print("SET TIMER"); 
         LCD.setCursor(5, 1); 
         LCD.print(SEC); 
         LCD.print(" . "); 
         LCD.print(DSEC);
      }
   } 
   button1WasUp = button1IsUp; // запоминаем состояние кнопки 1 
    


// при нажатии на третью кнопку переходим в цикл while
   if (button3WasUp && !button3IsUp && SEC > 0) {
      delay(10);
      button3IsUp = digitalRead(6);
      if (!button3IsUp) {
         if (DSEC == 0) { DSEC = 10; SEC = SEC - 1; }
         if (SEC < 0 ) { SEC = 0; }
        
         w = 1;
      }
   }
button3WasUp = button3IsUp; // запоминаем состояние кнопки 3


while (w == 1 ) {
      // если прошло 100 мс - вычитаем одну секунду от переменной DSEC
      if (millis() - timer > 100) {
         timer = millis();
         DSEC = DSEC - 1;

         // если отсчет закончился - включаем сигнал и выходим из цикла
         if (DSEC == 0 && SEC == 0) {
            LCD.clear();
            LCD.setCursor(2, 0);
            LCD.print("TIMER  STOP");
            LCD.setCursor(5, 1);
            LCD.print(button1IsUp);
            LCD.print(" . ");
            LCD.print(button2IsUp);
            
                    //Работа двигателя
                            digitalWrite(ENABLE_PIN , LOW);        //Включаем двигатель
                            flag = 1;                             //Активируем флаг рабочего режима
                            timer = millis(); 
                            if (flag) {                                 //Если флаг активирован
                            digitalWrite(DIR_PIN    , HIGH);         //Задаем направление вращения

                            //    for (int i = 0; i < 200; i++) {          //Выполняем нужное число шагов 200*16 = 3200 шагов оборот
                            //      digitalWrite(STEP_PIN    , HIGH);
                            //      delayMicroseconds(frequency);
                            //      digitalWrite(STEP_PIN    , LOW);
                            //    }
                            //    flag = 0;

                            do {                                      //Крутим движок move_forward_time мсек
                              digitalWrite(STEP_PIN    , HIGH);
                              delayMicroseconds(frequency);
                              digitalWrite(STEP_PIN    , LOW);
                            } while (millis() - timer < move_forward_time);

                            delay(pause_time);                        //Пауза pause_time мсек
                            timer = millis();                         //Снова запускаем таймер
                            digitalWrite(DIR_PIN    , LOW);        //Крутим движок move_back_time мсек
                            do {
                              digitalWrite(STEP_PIN    , HIGH);
                              delayMicroseconds(frequency);
                              digitalWrite(STEP_PIN    , LOW);
                            } while (millis() - timer < move_back_time);
                            flag = 0;                                 //Гасим флаг
                            digitalWrite(ENABLE_PIN , HIGH);        //Выключаем движок, чтобы не грелся
                          }
                    // Конец работы двигателя

               w = 0;
         }

         // если децисекунды дошли до нуля - вычитаем одну секунду
         if (DSEC == 0) {
            DSEC = 9; SEC = SEC - 1;
            if (SEC < 0 ) { SEC = 0; }
         }

         // если из цикла while еще не вышли - выводим информацию на дисплей
         if (w == 1) {
            LCD.clear();
            LCD.setCursor(2, 0);
            LCD.print("TIMER START");
            LCD.setCursor(5, 1);
            LCD.print(SEC);
            LCD.print(" . ");
            LCD.print(DSEC);
         }
     }
}
}

При старте секундомера запоминайте текущую установку и после завершения отсчета восстанавливайте его

Совет прекрасный - только как его воплотить в коде? )))

Взять и написать. У вас есть переменные SEC и DSEC - вот их значения запоминайте и восстанавливайте.

не запоминает. int SEC=button1WasUp;
Возвращает 1, на обе переменные. даже если было 10, а не 1

int DSEC_work, SEC_work: // <<<<<<<<<

...
void loop() {
...

      if (!button3IsUp) {
         if (DSEC == 0) { DSEC = 10; SEC = SEC - 1; }
         if (SEC < 0 ) { SEC = 0; }

        DSEC_work=DSEC; SEC_work = SEC; // <<<<<<<

         w = 1;
      }
...

И в цикле своём вычитайте из DSEC_work и SEC_work скоко хотите.

Но скетч все равно нужно перерабатывать, чтобы блокировки не было.

А что вы ожидали? Что делаете, то и получаете. Я вам совсем не это говорил

Возвращает 1.1 все равно. Я так примерно уже пытался

Вы непонятно что говорите. Вернее, понятно, но общими словами.

Вы ведь сами это написали в 12 и 13 строках скетча.
Так чему теперь удивляться?

Ну, покажите как пытались. Явно уменьшаете одну переменную, а печатаете другую.

Я и так и так делал. И нули ставлю и 1, и присваиваю переменную и пусто. Все равно, возвращает 1.1. Вот, пожалуйста, будет 1.1))):

#include "Wire.h"                              // библиотека для протокола I2C
#include "LiquidCrystal_I2C.h"        // библиотека для LCD 1602 
LiquidCrystal_I2C LCD(0x27, 20, 2);  // присваиваем имя дисплею

boolean button1WasUp = true;      // переменные для считывания нажатий кнопок
boolean button2WasUp = true;
boolean button3WasUp = true;
boolean button4WasUp = true;

byte w = 0;
int DSEC_work, SEC_work;
int SEC;   // переменные для отсчета секунд и десятых секунд
int DSEC;

unsigned long timer;

// Перменные движка!!!

//Пины управления шаговиком
#define STEP_PIN         9
#define DIR_PIN          10
#define ENABLE_PIN       11

//Пин кнопки
#define start_button 12

//Здесь можно настроить время поворота и паузы
#define move_forward_time 200    //время прямого хода в мсек
#define move_back_time 200       //время обратного хода в мсек
#define pause_time 500           //время паузы в мсек
#define frequency 200            //Время между импульсами в мксек. 1000 мксек = 1 мсек = 0.001 сек. Частота следования импульсов 1/0.001 = 1 кГц, 

//Логический флаг для рабочего режима
bool flag = 0;



void setup() {// подключаем тактовые кнопки
   pinMode(2, INPUT_PULLUP);  //+секунда
   pinMode(4, INPUT_PULLUP);  //+десек
   pinMode(6, INPUT_PULLUP);  //start-stop
   
  

   LCD.init();                        // инициализация дисплея
   LCD.backlight();              // включение подсветки

   LCD.setCursor(3, 0);
   LCD.print("SET TIMER");
   LCD.setCursor(5, 1);
   LCD.print(SEC);
   LCD.print(" . ");
   LCD.print(DSEC);


  //Engine setup

  pinMode(start_button, INPUT_PULLUP);  //Подтягиваем кнопку к питанию

  pinMode(STEP_PIN   , OUTPUT);       //Настраиваем пины управления
  pinMode(DIR_PIN    , OUTPUT);
  pinMode(ENABLE_PIN , OUTPUT);

  digitalWrite(ENABLE_PIN , HIGH);    //Выключаем мотор, чтобы не грелся
}

void loop() {
   boolean button1IsUp = digitalRead(2);   // узнаем текущее состояние кнопок
   boolean button2IsUp = digitalRead(4);
   boolean button3IsUp = digitalRead(6);

// при нажатии на 2 прибавляем сек и выводим на дисплей
if (button2WasUp && !button2IsUp) {
      delay(10); 
      button2IsUp = digitalRead(4); 
      if (!button2IsUp) { 
         SEC = SEC + 1; //DSEC = 0; 
           if (SEC>10){SEC=0;}
         LCD.clear(); 
         LCD.setCursor(3, 0); 
         LCD.print("SET TIMER"); 
         LCD.setCursor(5, 1); 
         LCD.print(SEC); 
         LCD.print(" . "); 
         LCD.print(DSEC);
      }
   } 
 button2WasUp = button2IsUp; // запоминаем состояние 2 
 
// при нажатии на 1 прибавляем десек и выводим на дисплей
   if (button1WasUp && !button1IsUp) {
      delay(10);
      button1IsUp = digitalRead(2);
      if (!button1IsUp) {
         DSEC = DSEC + 1; //SEC = 0;
         if (DSEC>9){DSEC=0;}
         LCD.clear(); 
         LCD.setCursor(3, 0); 
         LCD.print("SET TIMER"); 
         LCD.setCursor(5, 1); 
         LCD.print(SEC); 
         LCD.print(" . "); 
         LCD.print(DSEC);
      }
   } 
   button1WasUp = button1IsUp; // запоминаем состояние кнопки 1 
    


// при нажатии на третью кнопку переходим в цикл while
   if (button3WasUp && !button3IsUp && SEC > 0) {
      delay(10);
      button3IsUp = digitalRead(6);
      if (!button3IsUp) {
         if (DSEC == 0) { DSEC = 10; SEC = SEC - 1; }
         if (SEC < 0 ) { SEC = 0; }
        
       
         w = 1;
      }
   }
button3WasUp = button3IsUp; // запоминаем состояние кнопки 3

while (w == 1 ) {
      // если прошло 1000 мс - вычитаем одну секунду от переменной DSEC
      if (millis() - timer > 100) {
         timer = millis();
         DSEC = DSEC - 1;

         // если отсчет закончился - включаем сигнал и выходим из цикла
         if (DSEC == 0 && SEC == 0) {
            LCD.clear();
            LCD.setCursor(2, 0);
            LCD.print("TIMER  STOP");
            LCD.setCursor(5, 1);
            LCD.print(button1IsUp);
            LCD.print(" . ");
            LCD.print(button2IsUp);
            
                    //Работа двигателя
                            digitalWrite(ENABLE_PIN , LOW);        //Включаем двигатель
                            flag = 1;                             //Активируем флаг рабочего режима
                            timer = millis(); 
                            if (flag) {                                 //Если флаг активирован
                            digitalWrite(DIR_PIN    , HIGH);         //Задаем направление вращения

                            //    for (int i = 0; i < 200; i++) {          //Выполняем нужное число шагов 200*16 = 3200 шагов оборот
                            //      digitalWrite(STEP_PIN    , HIGH);
                            //      delayMicroseconds(frequency);
                            //      digitalWrite(STEP_PIN    , LOW);
                            //    }
                            //    flag = 0;

                            do {                                      //Крутим движок move_forward_time мсек
                              digitalWrite(STEP_PIN    , HIGH);
                              delayMicroseconds(frequency);
                              digitalWrite(STEP_PIN    , LOW);
                            } while (millis() - timer < move_forward_time);

                            delay(pause_time);                        //Пауза pause_time мсек
                            timer = millis();                         //Снова запускаем таймер
                            digitalWrite(DIR_PIN    , LOW);        //Крутим движок move_back_time мсек
                            do {
                              digitalWrite(STEP_PIN    , HIGH);
                              delayMicroseconds(frequency);
                              digitalWrite(STEP_PIN    , LOW);
                            } while (millis() - timer < move_back_time);
                            flag = 0;                                 //Гасим флаг
                            digitalWrite(ENABLE_PIN , HIGH);        //Выключаем движок, чтобы не грелся
                          }
                    // Конец работы двигателя

               w = 1;
         }

         // если децисекунды дошли до нуля - вычитаем одну секунду
         if (DSEC == 0) {
            DSEC = 9; SEC = SEC - 1;
            if (SEC < 0 ) { SEC = 0; }
         }

         // если из цикла while еще не вышли - выводим информацию на дисплей
         if (w == 1) {
            LCD.clear();
            LCD.setCursor(2, 0);
            LCD.print("TIMER START");
            LCD.setCursor(5, 1);
            LCD.print(SEC);
            LCD.print(" . ");
            LCD.print(DSEC);
         }
     }
}
}

int DSEC_work, SEC_work; можно убрать. Не помогает. Все равно - 1.1

Вопрос в том - как перенести в глобальную переменную выставленное значение, по сути. Мне пока не удается.

У вас какая профессия?

Не программист))

Есть определенна задача - пытаюсь решить)) Потому, в песочнице, а не среди богов )))

Вы хоть какое значение присваивайте этим переменным, они в любом случае будут равны либо нулю, либо единице. Тип данных такой.

Хотя почему boolean, а не bool? Не паскаль же

Все. Я врубился. Не поменял ваши DSEC_work в цикле. Заработало. Спасибо))

Нажмите под постом, который вам помог, кнопку Решено