ARDUINO переполнение Millis() и Micros()
- Войдите на сайт для отправки комментариев
Пнд, 08/02/2016 - 12:35
Добрый день! Наткнулся на идею, хочу обсудить.
Millis() и Micros() обнуляются. Поэтому хоть и не критично, но возможен глюк работы ардуино при переполнении счетчика во время выполнения цикла в моей программе:
#define INTERVAL2 5*60*1000UL <...> if (digitalRead(SENSORPIN)==1) // если сработал датчик движения { timeoff=millis(); // засекаем время когда он сработал ledstate=1; // свет включить } else { if (millis()-timeoff>INTERVAL2) // если с момента включения по датчику движения прошло более 20 секунд { ledstate=0; // свет выключить }
Пришла идея, как красиво устранить этот глюк.
Для этого нужно условие
millis()-timeoff
заменить на значение по модулю:
abs(millis()-timeoff)
Таким образом, если обнуления millis() не произошло, то все в порядке - число и так положительное.
А если обнуление произошло, то Millis()-timeoff будет огромным отрицательным числом.
Как вам такая реализация?
Если сделать вычитание двух беззнаковых чисел, отрицательное значение не может получиться (разумеется если не привести принудительно). Посмотрите, что возвращает millis().
Поищите на форуме, эта тема уже обсуждалась неоднократно.
unsigned long вам в руки :)
Если сделать вычитание двух беззнаковых чисел, отрицательное значение не может получиться (разумеется если не привести принудительно). Посмотрите, что возвращает millis().
Поищите на форуме, эта тема уже обсуждалась неоднократно.
Поясню, откуда берется по моему мнению отрицательное число и собственно сам глюк:
Рассмотрим последовательность работы программы на 49 день от сотворения Мира :)
1) MILLIS близко к переполнению. оно равно, скажем 4294967000
2) присваиваем timeoff=4294967000
3) при значении 4294967295 происходит переполнение MILLIS и оно обнуляется.
4) если из небольшого значения MILLIS вычесть большое значение timeoff, образуется отрицательное число, которое и глючит программу, так как условие не выполняется никогда!
Unsigned long variables are extended size variables for number storage, and store 32 bits (4 bytes). Unlike standard longs unsigned longs won't store negative numbers, making their range from 0 to 4,294,967,295 (2^32 - 1).
Unsigned long variables are extended size variables for number storage, and store 32 bits (4 bytes). Unlike standard longs unsigned longs won't store negative numbers, making their range from 0 to 4,294,967,295 (2^32 - 1).
Валера, что Вы хотите сказать этим?
сделайте unsigned long timeoff = 0;
конец millis чему равен, и конец uint32_t (unsigned long) поэтому никогда не будет при вычитании отрицательного значения
timeoff и так unsigned long (обратите внимание на буквы UL в описании #DEFINE)
вопрос в другом.
когда Unsigned long заканчивается, то есть переполняется, то MILLIS() обнуляется и начинает бежать заново. и нужно в коде предусмотреть, чтобы это обнуление не приводило к сбою.
прочитайте логику выполнения (я ее расписал под цифрами последовательностью).
на мой взгляд, отрицательные числа действительно должны образоваться при обнулении MILLIS. Разве нет?
leshak
http://arduino.ru/forum/programmirovanie/eshche-raz-migaem-svetodiodom-b...
leshak
http://arduino.ru/forum/programmirovanie/eshche-raz-migaem-svetodiodom-b...
проверил. отрицательных чисел действительно нет.
верно ли я понимаю, что даже при обнулении на 50й день значения MILLIS() ошибки в условии timeoff-MILIS()>interval не будет?
на micros проверьте, там 70 минут ждать
Давно всё проверено.
Читайте посты дальше.
Но только когда именно так:
millis() - prevTime >= interval
возможен глюк работы ардуино при переполнении счетчика во время выполнения цикла в моей программе:
спасибо! Я понял! :)
спасибо! Я понял! :)
чисто для себя писал, что бы от верю-не верю теории практически убедиться - перепиши для Сериала и медитируй на результат.