millis()

mutabor

✩✩✩✩✩✩✩
13 Дек 2024
3
0
добрый день.
подскажите пожалуйста в чем может быть связана следующая проблема:
есть функция, которую нужно вызывать раз в сутки. задан интервал в количестве миллисекунд в сутках (86 400 000), идет сравнение с ним.
всё работает нормально, но иногда почему то таймер слетает, и функция начинает выполняться хаотично, то через несколько минут, то несколько часов.
связано ли это непосредственно с millis, или это сама железка глючит?
 

Сотнег

★★★★★★★
15 Янв 2020
4,463
1,524
@mutabor,
если глюк не через 50 дней нормальной работы, то, скорее всего, просто плата перезагружается (сбой по питанию, или в программе какое-нибудь деление на ноль выполняется).
 

mutabor

✩✩✩✩✩✩✩
13 Дек 2024
3
0
@Сотнег,
если бы плата перезагружалась, отрабатывал бы setup()?
он не отрабатывает
 

LazyDev

✩✩✩✩✩✩✩
16 Ноя 2020
8
1
1. Тип для хранения unsigned long?
2. Сравнение как происходит?

Безопасный вариант:
C++:
unsigned long prevIterationTs = 0;

void loop() {
  // какой-то код

  if (millis() - prevIterationTs > 86400000ul) {
    prevIterationTs = millis();

    // какой-то код, выполняющийся раз в сутки
  }
}
 
Изменено:

mutabor

✩✩✩✩✩✩✩
13 Дек 2024
3
0
@LazyDev,
C++:
#define DAILY_INTERVAL    86400000
unsigned long time = 0;
void loop() {
    
      time = millis();
      if (time >= dailyTime) {
          dailyTime = time + DAILY_INTERVAL;
          blablabla(param); }
}
 

SlavaZagaynov

✩✩✩✩✩✩✩
27 Ноя 2019
34
7
мой говнокод обработки временных интервалов, если конечно это вообще кому-то нужно :
uint32_t next_millis_1_sek =         1*1000;
uint32_t next_millis_10_sek =        10*1000;
uint32_t next_millis_1_min =     1*60*1000;
uint32_t next_millis_10_min =   60*10*1000;
uint32_t next_millis_30_min =   60*30*1000;
uint32_t next_millis_1_h =      60*60*1000;


//---------------------------------------------------------
void loop() {


    if ( millis()                     >= next_millis_1_sek )     { next_millis_1_sek = millis() + 1000;             _1_sek();
        //if ( millis()             >= next_millis_10_sek ) { next_millis_10_sek = millis() + 10000;         _10_sek();
            if ( millis()             >= next_millis_1_min )     { next_millis_1_min = millis() + 60000;         _1_min();
                if ( millis()         >= next_millis_10_min ) { next_millis_10_min = millis() + 60000*10;        _10_min();
                    if ( millis()         >= next_millis_30_min ) { next_millis_30_min = millis() + 60000*30;    _30_min();
                        if ( millis()     >= next_millis_1_h )     { next_millis_1_h = millis() + 3600000;     _1_h(); }  
                    }
                }
            }
        //}
    }


}
 

Сотнег

★★★★★★★
15 Янв 2020
4,463
1,524
@SlavaZagaynov,
10 раз подряд запрашивать millis() - это всё-таки перебор.
Это ведь не переменная. Там приличный машинный код каждый раз выполняется.
 

SlavaZagaynov

✩✩✩✩✩✩✩
27 Ноя 2019
34
7
@Сотнег,да, пожалуй стоит это оптимизировать, не так давно у меня было только пара сравнений на 1 сек и 1 минуту, в последнем проекте добавил другие варианты
 

viktor1703

★★★✩✩✩✩
9 Дек 2021
646
153
@mutabor, откройте и повторите уроки по mills(). Правильнее будет
C++:
#define DAILY_INTERVAL    86400000
unsigned long time = mills();

void loop()
      if (millis() - time >= DAILY_INTERVAL) {
          time = mills();
          blablabla(param); }
}
 
Изменено:

НикитаТангер

✩✩✩✩✩✩✩
22 Июл 2024
9
0
@viktor1703,

C++:
#define DAILY_INTERVAL    86400000  // 24 часа в миллисекундах
unsigned long time = millis();      // MILLIS!

void setup() {
    //инициализация
}

void loop() { //можно добавить проверку перед ...if (millis() - time >= DAILY_INTERVAL).... и запускать таймер по кнопке
    if (millis() - time >= DAILY_INTERVAL) {
        time = millis();                     
        blablabla(param);                     
    }
}
 

viktor1703

★★★✩✩✩✩
9 Дек 2021
646
153
@НикитаТангер, ну и что вы хотели этим сказать? Сказали "А", говорите тогда уже и "Б". Вот, например, написано
По вашему, компилятор на это ругаться не будет? Почему здесь не исправили, не объявили переменную, нет функции, которую вызываете? У меня, согласно правилам форума, был приведен только кусок кода, который исправлял бы ошибку у ТС. Это не значит, что его нужно пытаться тупо прошивать в камень. Кому нужно, тот понял, что там нет setup'а, и что делать с этим куском, кому не нужно нефиг здесь душнить и строить умного.
 

LazyDev

✩✩✩✩✩✩✩
16 Ноя 2020
8
1
мой говнокод обработки временных интервалов, если конечно это вообще кому-то нужно :
uint32_t next_millis_1_sek =         1*1000;
uint32_t next_millis_10_sek =        10*1000;
uint32_t next_millis_1_min =     1*60*1000;
uint32_t next_millis_10_min =   60*10*1000;
uint32_t next_millis_30_min =   60*30*1000;
uint32_t next_millis_1_h =      60*60*1000;


//---------------------------------------------------------
void loop() {


    if ( millis()                     >= next_millis_1_sek )     { next_millis_1_sek = millis() + 1000;             _1_sek();
        //if ( millis()             >= next_millis_10_sek ) { next_millis_10_sek = millis() + 10000;         _10_sek();
            if ( millis()             >= next_millis_1_min )     { next_millis_1_min = millis() + 60000;         _1_min();
                if ( millis()         >= next_millis_10_min ) { next_millis_10_min = millis() + 60000*10;        _10_min();
                    if ( millis()         >= next_millis_30_min ) { next_millis_30_min = millis() + 60000*30;    _30_min();
                        if ( millis()     >= next_millis_1_h )     { next_millis_1_h = millis() + 3600000;     _1_h(); }
                    }
                }
            }
        //}
    }


}
Когда переменные uint32_t переполнятся, код в условиях будет выполняться каждую итерацию. Поэтому корректнее использовать вычитание предыдущего времени из millis() в условиях, как я написал в сообщении #4. Да и нет смысла каждый раз millis() дергать, создайте
unsigned long currentTs = millis(); в loop() и сравнивайте с ней внутри ф-ии.
Это и к вопросу ТС актуально.
 

НикитаТангер

✩✩✩✩✩✩✩
22 Июл 2024
9
0
@viktor1703, я исправил ошибку и добавил комментарий с доп условием, какой код будет крутиться в цикле зависит от человека, который будет проект делать.
 
  • Вау +0
Реакции: viktor1703

SlavaZagaynov

✩✩✩✩✩✩✩
27 Ноя 2019
34
7
@LazyDev,на счет "переполнятся" я понял, в моих устройствах этот момент не наступает, они раз в неделю сохраняются на фтп, перезагружаются и присылают сообщения типа "хозяин, мы ещё живы". Периодическая перезагрузка больше хорошо, чем плохо, когда почемуто отваливается вайфай, а устройство труднодоступно. Ну и в целом, если раз в неделю говорят что живы - значит работают и на душе спокойно.
 

SlavaZagaynov

✩✩✩✩✩✩✩
27 Ноя 2019
34
7
@Старик Похабыч, "что то не так" - вариант только один: есп32 потеряла вайфай и не может переподключиться к сети, не может принимать-отправлять команды и сообщения, пропадает возможность ею управлять, обновить и перезагрузить удаленно. Некоторые мои устройства над потолком, некоторые ограниченно доступны физически. В этом случае их самостоятельная перезагрузка раз в неделю и восстановление полного функционала спасает меня от необходимости "снимать люстру и тыкать в ресет есп32". Явление это - потеря связи с есп, конечно редкое, но бывает раз в полгода. Вообще практика периодических перезагрузок применяется в камерах видеонаблюдения и регистраторах, для решения проблемы утечки памяти и возможно такой же проблемы как у меня с потерей связи.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,279
1,304
Москва
@SlavaZagaynov,Ну а может все таки стоит изучить потерю связи ? и как то это лечить нормальными способами ?У меня на столе стоят часы на esp32 , в них есть и модуль часов и синхронизация по сети. Причем сделано это так, что основная работа происходит без сети, а вот если нужная сеть появляется , то происходит подключение и синхронизация времени (так надо было заказчику - вифи включается на телефоне и достаточно просто пройти по местам где часы стоят)
Подскажу. Следить надо за статусом соединения. Кратковременный обрыв лечится силами библиотеки, а вот если повторное соединение не проходит. то тогда стоит уже переподключить WiFi соединение. Или хотя бы в этом случае перегружать. И вот тогда вылезут косяки с кучей условий и переполнением.

В целом решение перегружать работающее устройство выглядит по меньшей мере странным.

А что делают устройства, если настал час Х перезагрузки, а соединения нет ?
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,975
635
45
Вообще практика периодических перезагрузок применяется в камерах видеонаблюдения и регистраторах, для решения проблемы утечки памяти и возможно такой же проблемы как у меня с потерей связи.
Ну да, зачем дебажить и выяснять почему происходит утечка памяти или обрывается связь с вайфай, лучше решить по-топорному - перезагрузкой. (сарказм)
 

SlavaZagaynov

✩✩✩✩✩✩✩
27 Ноя 2019
34
7
@Старик Похабыч, Проверки на потерю сигнала есть в моём коде, попытки восстановления тоже есть, при невозможности подключиться к роутеру - поднимаю точку доступа и периодически пытаюсь подключиться к роутеру. Функционал связи с роутером или включением точки доступа у меня отлажен, перезагрузка esp32 это как последний вариант тоже есть.
Так исторически сложилось, что я решил их перезагружать раз в неделю пока писал код и отлаживал, на текущий момент времени в этом смысла уже нет, есп работают стабильно, можно отключить перезагрузку, но это вообще ничего не изменит, перезарузка esp происходит за 3-4 секунды и не сказывается на работе подключенной периферии.
Но есть у меня странное чувство, что как только отключу - оно сразу и заглючит. :cry: Поэтому оставлю всё как есть с перезагрузкой раз в неделю.
 

SlavaZagaynov

✩✩✩✩✩✩✩
27 Ноя 2019
34
7
@Геннадий П, это вы всё правильно пишете, но если разумные сроки изучения проблемы и её решения давно прошли, что делать-то?
Вариант потратить еще сто тыщь пясот часов на выяснения и эксперименты - "так себе" вариант.
 

SlavaZagaynov

✩✩✩✩✩✩✩
27 Ноя 2019
34
7
@bort707, авр - это ардуино уно и похожие 8 битные?
Ну я таким не пользуюсь и вам не советую. (ну только не говорите, что они дешевле, или меньше, или вам не нужно много возможностей)