РЕШЕНО Таймер на millis

Тема в разделе "Arduino & Shields", создана пользователем IlyaT, 19 июн 2020.

  1. IlyaT

    IlyaT Нерд

    Добрый день.
    Помогите пожалуйста. Видимо я что-то глобально не понимаю. Приведенный ниже код, по моей задумке должен раз в 10 секунд отправлять в последовательный порт тестовое сообщение и раз в 10 секунд значение с аналогового входа. Пару раз он та и делает, а потом начинает слать в порт постоянно. ЧТЯДНТ?
    Код (C++):
    int timing_welcome = millis();
    int timing_sensor  = millis();
    int SENSOR;
    int val=0;

    const int POT=0;


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


    void loop() {


    //Раз в 10с говорим в порт что мы готовы
    if (millis() - timing_welcome > 10000)
    {
      timing_welcome = millis();
      Serial.println("INFO:Ready");
    }


    //Раз в 10с проверяем значение датчика
    if (millis() - timing_sensor > 10000)
    {
      timing_sensor = millis();
      val = analogRead(POT);
      SENSOR = val;
      Serial.print("SENSOR1:");
      Serial.println(SENSOR);
    }

    delay(100);

    }
     
  2. AlexVS

    AlexVS Гик

    Код (C++):
    unsigned long timing_welcome = millis();
    unsigned long timing_sensor  = millis();
    Переполнение случается.
     
    IlyaT нравится это.
  3. IlyaT

    IlyaT Нерд

    Спасибо. Помогло.
     
  4. b707

    b707 Гуру

    главное тут - что надо добавить unsigned, а long при задержке в 10 сек не обязательно, все будет работать и с int, переполнение мешать не будет
     
  5. SergeiL

    SergeiL Оракул Модератор

    Не, с unsigned без long, на меге работать будет, но не долго.
    До седьмого срабатывания.
    millis() возвращает 32-х битное значение, переменная 16-ти битная.
    После превышения millis 65535 в переменную запишутся только младшие два байта.
    Соответственно, после сравнения - результат всегда будет более 10000.
     
  6. AlexVS

    AlexVS Гик

    .
    В данные переменные не задержка сохраняется, а текущее значение millis(). Ну и какое оно будет через сутки? Эх......
     
  7. b707

    b707 Гуру

    а вы попробуйте :) Программка на три строки, ждать не долго - всего чуть больше минуты.
    Тогда и обсудим :)
     
  8. SergeiL

    SergeiL Оракул Модератор

    Так а зачем пробовать, и так же очевидно.
     
  9. b707

    b707 Гуру

    а ну да, сорри :)
    Чуть условие отредактировать, тогда будет работать c int вместо long:
    Код (C++):
    if ( (unsigned int) millis() - timing_sensor > 10000)
     
  10. AlexVS

    AlexVS Гик

    Код (C++):
    timing_welcome = millis();
    Мы ведь говорим в контексте 8ми битной атмеги? unsigned int - верхнее значение какое?
    millis() - через 10 минут какое значение вернет?
     
  11. SergeiL

    SergeiL Оракул Модератор

    Код:
    Код (C++):
    unsigned timing_welcome = 0;

    void setup() {

      unsigned long prev_millis = millis();
      Serial.begin(115200);
      while (millis() - prev_millis < 5000 ) // 5 секунд ожидаем подключения порта (только Leonardo)  
      {
        if (Serial)
        {
          Serial.println("Serial Connected");
          break;
        }
      }
     
      Serial.println("------------- START -----------------");
    }

    void loop()
    {
        if (millis() - timing_welcome > 10000)
        {
            timing_welcome = millis();
            Serial.print("millis = ");
            Serial.println(millis());
        }

    }
    Результат:
    Код (Text):
    Serial Connected
    ------------- START -----------------
    millis = 10001
    millis = 20002
    millis = 30003
    millis = 40004
    millis = 50006
    millis = 60007
    millis = 70008
    millis = 70008
    millis = 70008
    millis = 70008
    millis = 70008
    millis = 70009
    millis = 70009
    millis = 70009
    millis = 70009
    millis = 70010
    millis = 70010
    millis = 70010
    millis = 70010
    millis = 70012
    millis = 70012
    millis = 70012
    millis = 70012
    millis = 70014
    millis = 70014
    millis = 70014
    millis = 70014
    millis = 70016
    millis = 70016
    millis = 70016
    millis = 70016
    millis = 70016
    millis = 70017
    millis = 70017
    millis = 70017
    millis = 70017
    millis = 70018
    millis = 70018
    millis = 70018
    millis = 70018
    millis = 70019
    millis = 70019
    millis = 70019
    millis = 70019
    millis = 70020
    millis = 70020
    millis = 70020
    millis = 70020
    Что и требовалось доказать ;)
     
    b707 нравится это.
  12. SergeiL

    SergeiL Оракул Модератор

    Ну если отредактировать, то, конечно будет :)
     
    b707 нравится это.
  13. b707

    b707 Гуру

    да я там уже переобулся на ходу:) , правильный код для int - #10
     
    SergeiL нравится это.
  14. SergeiL

    SergeiL Оракул Модератор

    Раньше тоже использовал:
    Код (C++):
    unsigned      val1;
    int           val2;
    unsigned char val3;
    unsigned long val4;
    После того как напоролся, что unsigned int на ESP8266 занимает 4 байта, теперь использую:
    Код (C++):
    uint16_t      val1;
    int16_t       val2;
    uint8_t       val3;
    uint32_t      val4;
    Так однозначно указывается размер переменной.
    Советую перейти на такое определение переменных, тогда они будут занимать одинаковый размер на разных процессорах.
     
    Daniil нравится это.
  15. AlexVS

    AlexVS Гик

    Абсолютно с вами согласен :)
    http://forum.amperka.ru/threads/Общий-размер-структуры.20911/