Обработка переполнения счетчика миллисекунд

Alex-GK
Offline
Зарегистрирован: 10.04.2012

Добрый день, уважаемые специалисты!

Возникла у меня достаточно дурацкая проблема.

Я достаточно долго искал, много читал, но, к сожалению так и не понял, как сделать правильно?

У меня в скетче есть следующий код:

started_waiting_at = millis();
timeout = false;
while ( ! radio.available() && ! timeout )
  if (millis() - started_waiting_at > 500 )
    timeout = true; 

И он в общем-то прекрасно работает, но терзает меня мысль, что может так случится, что совпадет переполнение значения millis() с соответственным сбросом на 0 и не получения данных тем самым radio.available() в результате чего цикл while будет тупо крутится почти 50 дней.

Я понимаю, что нужно об этом позаботится, но неужели не существует более красивого способа чем предварительная проверка есть ли 500 миллисекунд между started_waiting_at и максимальным значением millis() ?

step962
Offline
Зарегистрирован: 23.05.2011

Вместо

  if (millis() - started_waiting_at > 500 )

можно попробовать написать

  long delta;  // signed!!!
[...]
  delta = millis() - started_waiting_at;
  if (delta > 500)

 Результат вас, возможно, успокоит.

PS: Впрочем, для unsigned long  результат тоже обнадеживающий:

long delta;
unsigned long started_waiting_at,_millis;

void test(unsigned long a, unsigned long b) {
  long res;
  res=a-b;
  Serial.print(a);Serial.print("-");
  Serial.print(b);Serial.print("=");
  Serial.print(a-b);Serial.print(" / ");
  Serial.println(res);
}
void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT);
  test(90000,89500);
  test(290000,289500);
  test(4294967290,4294966790);
  test(394,4294967290);
  test(484,4294967290);
  test(494,4294967290);
}

void loop() {
}

На выходе имеем:

90000-89500=500 / 500
290000-289500=500 / 500
4294967290-4294966790=500 / 500
394-4294967290=400 / 400
484-4294967290=490 / 490
494-4294967290=500 / 500

 Так что можете спать спокойно - проверка продолжит работу и на границе переполнения