Вычесть из меньшего большее или как обрабатывать warp таймеров

mal333
Offline
Зарегистрирован: 23.04.2014

Доброго времени суток, уважаемые.

Есть переменная таймера, которой мы присваиваем текущее значения счетчика времени в mills() или

timer=mills();

Предположим для простоты, что это 16-битовый счетчик и на момент присвоения там было 0xFFAE. Прошло время, и значение счетчика перевалило за максимум и стало 0x0015, когда мы в программе стали выяснять, а не прошел ли нужный нам интервал путем:
if (mills()-timer>100)  и тут нас ждет засада с правильным вычислением прошедшего времени.
Я уверен, что эта ситуация уже как-то решалась, но не могу представить как правильно ее искать. Да даже посчитать, чтобы алгоритм действий составить никак, ибо все калькуляторы охотно вычисляют отрицательные числа, что никак не отражает нужную действительность.
Помогите, а, кто чем может?

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

А давайте почитаем, что millis() это  unsignet long с 32-мя битами.

Ну а если Вы такой терпеливый, что дождетесь переполнения, то никто Вам не мешает проверить, что было переполнение.

Хотя, если переполнение было несколько раз...тогда Вы воистину терпеливый и программируйте на PIC - там можно тактовую частоту 36кГц задать.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Или проверяйте на  переполнение или модуль реального времени воткните. Да вариантов туева хуча - от задачи зависит

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

операция вычитания нечувствительна к переполнению в любом контроллере. просто проверь и не трать время на диспуты. тут уже стопицот тем было. поищи "великое переполнение millis()"

Logik
Offline
Зарегистрирован: 05.08.2014

//Ну а если Вы такой терпеливый,

а если  не терпиливый, но хотябы не конченый олигофрен (в чем лично я сомниваюсь т.к. это много раз обсуждалось на форуме и не найти это могут токо лауреаты конкурса по минимуму IQ) то хотяб сделайте так.

void setup() {
  // put your setup code here, to run once:
 Serial.begin(9600);
 pinMode(13, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
 uint8_t t= millis();
 static uint8_t p;
 static uint8_t a;

  if((uint8_t)(t-p)>=100)
  {
    if(p>t)     Serial.println("!");
    digitalWrite(13,a);
    a=!a;
    p+=100;
  }
}

И переполнения будут раза 4 в секунду. О каждом таком "ждет засада с правильным вычислением" информирует  мигание ТХ. А на светодиоде 13 будет мигание заданного периода.  Найди сбой! Твои мозги мы уже проверили, их суко не обнаружено. Теперь глаза проверим , узри сбои при переполнении.

Делись впечатлениями, классно быть дебилом? Ты на форуме с 14-го года и так нихера не понял. Значить и не поймешь уже. Вали нахер, это не твое.

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

ПС. Предлагаю с каждого свежего брать расписку что тему про переполнение миллиса он здесь никогда не создаст.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

бить нельзя их,  а не вникнут - абиснять. (с)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

бить низзя абиснять

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Не оскорбляйте религиозные чувства ТС! :)

 

rkit
Offline
Зарегистрирован: 23.11.2016

mal333 пишет:

if (mills()-timer>100)  и тут нас ждет засада с правильным вычислением прошедшего времени

Точно? А стандарт языка привести можешь?

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

rkit пишет:

Точно? А стандарт языка привести можешь?

Зачем? Так написано в уроках у самого гивера! Также переполнение специальным образом обрабатывается в FLProg. А это такие профи, которым мы - сирые и убогие, ... ну, ты понял.

mal333
Offline
Зарегистрирован: 23.04.2014

wdrakula пишет:
операция вычитания нечувствительна к переполнению в любом контроллере. просто проверь и не трать время на диспуты. тут уже стопицот тем было. поищи "великое переполнение millis()"

Спасибо, уважаемый, за направление поиска, все нашел. Я сомневался с беззнаковым вычислением разницы, но камрады тут успокоили.  if( current - last > interval) будет работать полюбому 

Logik
Offline
Зарегистрирован: 05.08.2014

В FLProg вобще забористо

if (currentTime>= startTime) {return (currentTime>=(startTime + period));} else {return (currentTime >=(4294967295-startTime+period));}

хотя и гувер не отстает, у него с циклом!

uint32_t timer = 0;
void loop() {
  if (millis() - timer >= PERIOD) {
    // ваше действие
    do {
      timer += PERIOD;
      if (timer < PERIOD) break;  // переполнение uint32_t
    } while (timer < millis() - PERIOD); // защита от пропуска шага
  }