Остановка по времени.

Тема в разделе "Arduino & Shields", создана пользователем tekasijimo, 31 июл 2015.

  1. tekasijimo

    tekasijimo Нуб

    Всем привет! Уже два дня Ломаю голову и интернет в поисках информации по Простому таймеру.
    Пока все что удалось нарыть переделал под свои нужды но оно работает не так как нужно мне.
    Код (Text):
    unsigned long time;
    char ar = 0;
    int t;
    int s;
    int m;
    void setup()
    {
      Serial.begin(9600);
    }

    void loop()
    {
      if (Serial.available() > 0) {
        ar = Serial.read();
      }
      if (ar == 's') {
        time = 1440000;
        byte s = ((time - millis()) / 1000ul) % 60;
        byte m  = (((time - millis()) / 1000ul) / 60ul) % 60;
        Serial.print(m);
        Serial.print(":");
        Serial.print(s);
        Serial.print("\n");
        delay(1000);
      }
      else if (ar=='b'){
        Serial.print("Stop time");
        ar = ' '
      }

    }
    Тут возникло три вопроса.
    Как начинать отсчет только после: if (ar == 's').
    Как сделать чтоб по окончании заданного времени программа переходила в ожидание новой команды.
    И почему происходит такая фигня:
    [​IMG]

    Если что-то похожее уже было на форуме ткните ссылку пожалуйста.
     
  2. Alex19

    Alex19 Гуру

    Код (Text):
    ar = ' '
    Исправьте на
    Код (Text):
    ar = ' ';
    Вы отнимаете от time = 1440000, значение millis(), которое всегда растет.

    Если можно напишите, что Вы хотите сделать. Просто не могу понять, вопросов.

    В идеале, примерно так:
    Если передали s начинаем отсчет от 10 и не прекращаем, пока не получили команду и т.д.
     
  3. tekasijimo

    tekasijimo Нуб

    Я хочу сделать таймер с выводом на OLED дисплей времени, дисплей пока не приехал хочу накидать макет через ком-порт. Время должно начинать считаться от получения сигнала с компа через ком. Как это реализовать не понимаю...

    На скрине видно что время идет до 23:27 а потом становится 24:32. От чего это происходит?
     
  4. Alex19

    Alex19 Гуру

    С данным кодом такой проблемы не будет.

    Код (Text):
    unsigned long time;
    int t;
    int s;
    int m;

    // Номер команды
    byte comand;

    // Предыдущее значение millis
    unsigned long previousMillis = 0;

    // Интервал в мс.
    const long interval = 1000;      

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

    void loop()
    {
      char ar = 0;

      if (Serial.available() > 0)
      {
        ar = Serial.read();
      }

      if (ar == 's')
      {
        comand = 1;
      }
      else if (ar=='b')
      {
        comand = 2;
      }

      if (comand == 1)
      {
        // Текущее значение millis
        unsigned long currentMillis = millis();
        // Из текущего вычитаем предыдущее и проверяем больше или равно интервалу.
        if(currentMillis - previousMillis >= interval)
        {
          // Присваиваем предыдущему значению текущее.
          previousMillis = currentMillis;
       
          // Ваш код.
          time = 1440000;
          byte s = ((time - millis()) / 1000ul) % 60;
          byte m  = (((time - millis()) / 1000ul) / 60ul) % 60;
          Serial.print(m);
          Serial.print(":");
          Serial.print(s);
          Serial.print("\n");
        }

      }
      else if(comand == 2)
      {
        Serial.print("Stop time");
     
        comand = 0;
      }
    }
    У Вас как я понял, переда команда, начинается отсчет от какого-то значения, затем команда стоп.

    После повторной команды старт, время начинает отсчитываться от чего?

    UPD.
    Отсчет начинается, с 24 минут, каждый раз после следующей команды s.
    Код (Text):
    unsigned long time;
    int t;
    int s;
    int m;

    // Номер команды
    byte comand;

    // Предыдущее значение millis
    unsigned long previousMillis = 0;

    // Интервал в мс.
    const long interval = 1000;        

    // Сохраняем начальное значение Millis для отсчета от него.
    unsigned long beginCountMillis = 0;

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

    void loop()
    {
      char ar = 0;
     
      if (Serial.available() > 0)
      {
        ar = Serial.read();
      }
     
      if (ar == 's')
      {
        comand = 1;
       
        beginCountMillis = 0;
      }
      else if (ar=='b')
      {
        comand = 2;
      }
     
      if (comand == 1)
      {
        // Текущее значение millis
        unsigned long currentMillis = millis();
        // Из текущего вычитаем предыдущее и проверяем больше или равно интервалу.
        if(currentMillis - previousMillis >= interval)
        {
          // Присваиваем предыдущему значению текущее.
          previousMillis = currentMillis;
         
          // Ваш код.
          time = 1440000;
         
          // Если начальное значение равно 0.
          if (beginCountMillis == 0)
          {
            // Задаем начальное значение счетчика.
            beginCountMillis = previousMillis;
          }
         
          // Прибавляем начальное значение и time.
          time += beginCountMillis;
         
          byte s = ((time - previousMillis) / 1000ul) % 60;
          byte m  = (((time - previousMillis) / 1000ul) / 60ul) % 60;
          Serial.print(m);
          Serial.print(":");
          Serial.print(s);
          Serial.print("\n");
        }
      }
      else if(comand == 2)
      {
        Serial.println("Stop time");
       
        comand = 0;
      }
    }
    Да и не забываем о проверке данного значения на 0.
    Код (Text):
    (time - previousMillis)
    Если дойдет до 0, дальше будут одни нули.

    Можно остановить таймер, при достижении 0.
    Код (Text):
    unsigned long time;
    int t;
    int s;
    int m;

    // Номер команды
    byte comand;

    // Предыдущее значение millis
    unsigned long previousMillis = 0;

    // Интервал в мс.
    const long interval = 1000;        

    // Сохраняем начальное значение Millis для отсчета от него.
    unsigned long beginCountMillis = 0;

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

    void loop()
    {
      char ar = 0;
     
      if (Serial.available() > 0)
      {
        ar = Serial.read();
      }
     
      if (ar == 's')
      {
        comand = 1;
       
        beginCountMillis = 0;
      }
      else if (ar=='b')
      {
        comand = 2;
      }
     
      if (comand == 1)
      {
        // Текущее значение millis
        unsigned long currentMillis = millis();
        // Из текущего вычитаем предыдущее и проверяем больше или равно интервалу.
        if(currentMillis - previousMillis >= interval)
        {
          // Присваиваем предыдущему значению текущее.
          previousMillis = currentMillis;
         
          // Ваш код.
          time = 1440000;
         
          // Если начальное значение равно 0.
          if (beginCountMillis == 0)
          {
            // Задаем начальное значение счетчика.
            beginCountMillis = previousMillis;
          }
         
          // Прибавляем начальное значение и time.
          time += beginCountMillis;
         
          byte s = ((time - previousMillis) / 1000ul) % 60;
          byte m  = (((time - previousMillis) / 1000ul) / 60ul) % 60;
          if (s>0 || m>0)
          {
            //byte s = ((time - previousMillis) / 1000ul) % 60;
            //byte m  = (((time - previousMillis) / 1000ul) / 60ul) % 60;
            Serial.print(m);
            Serial.print(":");
            Serial.print(s);
            Serial.print("\n");
          }
          else
          {
            Serial.println("Finish");
       
            comand = 0;
          }
        }
      }
      else if(comand == 2)
      {
        Serial.println("Stop time");
       
        comand = 0;
      }
    }
    Код не оптимальный, но тут главное понять.
     
    Последнее редактирование: 31 июл 2015
    tekasijimo нравится это.
  5. tekasijimo

    tekasijimo Нуб

    Там по факту команд несколько но с разным стартовым временем.
    Спасибо огромное! Теперь буду разбираться во всем этом.
    И у меня сразу возникает вопрос по скечу:
    Почему этот кусочек
    Код (Text):
     if (ar == 's')
      {
        comand = 1;

        beginCountMillis = 0;
      }
    отделяют от этого?
    Код (Text):
     if (comand == 1)
      {
        // Текущее значение millis
        unsigned long currentMillis = millis();
        // Из текущего вычитаем предыдущее и проверяем больше или равно интервалу.
        if(currentMillis - previousMillis >= interval)
        {
          // Присваиваем предыдущему значению текущее.
          previousMillis = currentMillis;
     
          // Ваш код.
          time = 1440000;
     
          // Если начальное значение равно 0.
          if (beginCountMillis == 0)
          {
            // Задаем начальное значение счетчика.
            beginCountMillis = previousMillis;
          }
     
          // Прибавляем начальное значение и time.
          time += beginCountMillis;
     
          byte s = ((time - previousMillis) / 1000ul) % 60;
          byte m  = (((time - previousMillis) / 1000ul) / 60ul) % 60;
          if (s>0 || m>0)
          {
            //byte s = ((time - previousMillis) / 1000ul) % 60;
            //byte m  = (((time - previousMillis) / 1000ul) / 60ul) % 60;
            Serial.print(m);
            Serial.print(":");
            Serial.print(s);
            Serial.print("\n");
          }
          else
          {
            Serial.println("Finish");

            comand = 0;
          }
        }
      }
    И можно ли их объединить для удобства чтения?

    Ведь по факту они являются одним целым но разнесенными в разные места.
     
  6. Alex19

    Alex19 Гуру

    Объединить нет, beginCountMillis = 0; ее надо взводить именно при получении данных.

    1. Блок - if (ar == 's') срабатывает только при получении данных.
    2. Блок if (comand == 1) крутится всегда, после получения команды 1.

    UPD. Но Вы можете, вставить этот код, так.

    Код (Text):
    if (Serial.available() > 0)
      {
        ar = Serial.read();
        if (ar == 's')
        {
            beginCountMillis = 0;
        }
      }
     
    И тогда можно будет сделать 1 блоком. А дальше убрать comand, заменив ее на ar, и вынести ar за пределы функций, как у Вас было.
     
    Последнее редактирование: 1 авг 2015
    tekasijimo нравится это.
  7. tekasijimo

    tekasijimo Нуб

    Спасибо большое. Вроде пока все понятно)))