_isTimer нежданчики

В данный форум Вы можете заносить найденные Вами ошибки.При добавления ошибки пожалуйста приложите файлик error.log который находится в папке с установленной программой
Ответить
Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25 дек 2015, 17:32
Откуда: Ярославль.
Имя: Александр
Поблагодарили: 5 раз
Контактная информация:

_isTimer нежданчики

Сообщение Sancho »

И вновь о функции

Код: Выделить всё

bool _isTimer(unsigned long startTime, unsigned long period )
  {
  unsigned long currentTime;
currentTime = millis();
if (currentTime>= startTime) {return (currentTime>=(startTime + period));} else {return (currentTime >=(4294967295-startTime+period));}
  }
Вновь возвращаюсь к многократно обсуждаемой теме, а именно функции таймера.
Для начала давайте отойдём от 4 байтных значений, и уменьшим до одного байта. Смысла это не меняет, от слова совсем.
Допустим, сейчас функция вернула нам значение 253, а мы вызвали таймер с параметрами 250 и 20, т.е еще 17 милс осталось.
Что происходит в нашем случае?
Ответ для : if (currentTime>= startTime) {return (currentTime>=(startTime + period));}
Подставляем: if (253>= 250) {return (253>=(250 + 20));}, а т.к. 250 + 20 = 14, 253>=14, то мы получим истину!!! хотя время ещё не прошло!!!!
Вот именно здесь и происходит злая шутка с переходом через максимум!!!!
Ну нельзя прибавлять в ситуациях, когда число не бесконечно.
Как проверяют пройденное расстояние по простому одометру ? правильно, от того, сколько сейчас,
отнять сколько было при старте. даже если перед этим были все 9, кроме последней!
Просто единицу, которая "невидима" в "старшем" разряде мы игнорируем при подведении итога!
Возьмём альтернативу, которой я всегда заменяю штатную функцию.

Код: Выделить всё

 bool _isTimer(unsigned long startTime, unsigned long period )
  {
	unsigned long currentTime = millis();
	return (period <=(currentTime - startTime));
  }
пробуем для байта: 20 <= 253 - 250 - false
далее, через некоторое время, когда прошло "переполнение"
20 <= 10 - 250 - false, т.к. 10-250= 16!!!!
для неверующих приводил примеры, даже для ардуино скетч. попробуйте на win каркуляторе в режиме програмист, наконец.
Неужели я долбоящер? Если да, то нечего мне тут делать, наверное...
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.
Аватара пользователя
rw6cm
Полковник
Сообщения: 2372
Зарегистрирован: 06 сен 2015, 20:25
Имя: Владимир
Поблагодарили: 41 раз

_isTimer нежданчики

Сообщение rw6cm »

Нам без граблей ни как :smile390: иначе мы теряем бдительность )))
Win10-64, FLProg (portable)
ecoins
Полковник
Сообщения: 4012
Зарегистрирован: 12 фев 2016, 11:40
Откуда: Шатура
Имя: Энвер
Благодарил (а): 137 раз
Поблагодарили: 158 раз

_isTimer нежданчики

Сообщение ecoins »

Поднятый вопрос интересен... Пока без комментариев...
А как Вы оцениваете проблему - при переполнении возможен один пропуск события?
Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25 дек 2015, 17:32
Откуда: Ярославль.
Имя: Александр
Поблагодарили: 5 раз
Контактная информация:

_isTimer нежданчики

Сообщение Sancho »

ecoins писал(а): 12 июн 2021, 13:40 А как Вы оцениваете проблему - при переполнении возможен один пропуск события?
всё зависит от момента вызова.
повторяемость редкая, для мс, и не очень для мкс. при подходе к макс значениям.
данный момент легко повторить, удалив старшие три байта у millis() и создав простой проект для теста.
Это не фишка, это баг.
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.
ecoins
Полковник
Сообщения: 4012
Зарегистрирован: 12 фев 2016, 11:40
Откуда: Шатура
Имя: Энвер
Благодарил (а): 137 раз
Поблагодарили: 158 раз

_isTimer нежданчики

Сообщение ecoins »

Уточню вопрос - при переполнении и уже прошедшего времени = period, функция может не вернуть значение равно 1?
А в следующем периоде уже вернёт 1?
То есть возможен пропуск одного события при переполнении (46 дней для ms)?
Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25 дек 2015, 17:32
Откуда: Ярославль.
Имя: Александр
Поблагодарили: 5 раз
Контактная информация:

_isTimer нежданчики

Сообщение Sancho »

при достижении момента, когда Ваши данные, а именно сумма периода и запомненного времени превышают значение переполнения, Вы будете получать 1 при каждом вызове функции при недостижении этого времени пока значение millis не переполнится

Отправлено спустя 1 минуту 55 секунд:
это редко для мс, но это имеет место быть!
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.
ecoins
Полковник
Сообщения: 4012
Зарегистрирован: 12 фев 2016, 11:40
Откуда: Шатура
Имя: Энвер
Благодарил (а): 137 раз
Поблагодарили: 158 раз

_isTimer нежданчики

Сообщение ecoins »

Строка unsigned long currentTime = millis() с некоторым смыслом?
Или можно проще ?
bool _isTimer(unsigned long startTime, unsigned long period ) {return (period <=(millis() - startTime));}
Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25 дек 2015, 17:32
Откуда: Ярославль.
Имя: Александр
Поблагодарили: 5 раз
Контактная информация:

_isTimer нежданчики

Сообщение Sancho »

ecoins писал(а): 13 июн 2021, 13:02 Строка unsigned long currentTime = millis() с некоторым смыслом?
Или можно проще ?
bool _isTimer(unsigned long startTime, unsigned long period ) {return (period <=(millis() - startTime));}
Конечно можно.
Просто, как мне кажется, всё равно создаётся временная переменная под то, что возвращает функция.
А в приведённом примере именно для наглядности.
Но, надеюсь, Вы уловили суть нежданчика.
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.
Labu559
Лейтенант
Сообщения: 359
Зарегистрирован: 25 янв 2018, 22:23
Откуда: Bukovyna
Имя: Василий

_isTimer нежданчики

Сообщение Labu559 »

Sancho писал(а): 14 июн 2021, 09:30 ... надеюсь, Вы уловили суть нежданчика...
...для неверующих приводил примеры, даже для ардуино скетч. попробуйте на win каркуляторе в режиме програмист, наконец...
Да, [ref=#ff8000]Sancho[/ref], ув. Александр уловили и шишки набили! Я минимум 2 года как ощутил и говорю об ущербности _isTimer() на millis() и micros() :) . Увидеть один раз лучше чем 100 раз услышать? Тогда [spoiler title= умеющий смотреть узрит:]
16bitOverflow_02_2.ino
16b_OverflowMicrosErrors.pdf
32bitOverflow_02_2b.ino
32b_OverflowMicrosErrors.pdf
Изучения функций проводили онлайн совмесно с ув.Sancho для , 16-, 32- битых значений и 8-бит для ресурсоограниченных ATTiny для 3-х и 2-х значений времени старта функций с основным циклом длительностью 11 мкс с отслеживанием временных интервалов в 41 мкс. [/spoiler]
Это скетчи демонстрации отрабатывания базовой isTimer() функций в реализациях FLProg, Sancho и моей, а также логи вывода в терминал. Смотрите, сравнивайте, опровергайте, или продолжайте при каждом вызове функции суммировать и сравнивать 32-битные переменные, особенно с micros(), который почему-то не ждёт даже пока его скопируют в другую переменную и кратен 4-м и получать гарантированные сбои при каждом переполнении аппаратного таймера с разной степенью "тяжести". Всем удачи!
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Последний раз редактировалось Labu559 04 авг 2021, 16:17, всего редактировалось 3 раза.
Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25 дек 2015, 17:32
Откуда: Ярославль.
Имя: Александр
Поблагодарили: 5 раз
Контактная информация:

_isTimer нежданчики

Сообщение Sancho »

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

Вернуться в «Новые»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя