Задержка без Delay и переполнения счетчиков.
- Войдите на сайт для отправки комментариев
Втр, 19/01/2016 - 13:49
В теме http://arduino.ru/forum/programmirovanie/mertsaet-displei-128kh64 прошло бурное обсуждение кода задержек без Delay.
Мною предлагалось использовать код
unsigned long CTime01;
unsigned long LTime01;
void setup()
{;}
void loop()
{
CTime01 = millis();
if (CTime01 >= (LTime01 +1000)) //задержка 1с
{
//Тут обновляем
LTime01 = CTime01;
}
}
На что пошли возражения про переполнение переменной LTime01. Предлагалось использовать код
if( millis() - t > interval )
{
{ action; }
t = millis();
}
Но этот код не учитывает время выполнения функции { action; }
Мои эксперименты подтвердили переплнение http://arduino.ru/forum/programmirovanie/mertsaet-displei-128kh64#comment-162410
Сейчас запустил с проверкой
i = millis() if( max(i,t)-min(i,t) > interval )
Жду...
Жду...
красавчик... ждёт он.
всё уже
украденопроверено до вас// тест переполнения unsigned long millis(). // проверка корректности условия if (nm - m > 10) когда m считано до переполнения millis(), nm - после переполнения. // результат проверки - корректно переползаем переполнение из "до" в "после": // 4294967294 - 4294967284 = 10 // 4294967295 - 4294967285 = 10 // 0 - 4294967286 = 10 // 1 - 4294967287 = 10 // 2 - 4294967288 = 10 // 3 - 4294967289 = 10 // 4 - 4294967290 = 10 // 5 - 4294967291 = 10 // 6 - 4294967292 = 10 // 7 - 4294967293 = 10 // 8 - 4294967294 = 10 // 9 - 4294967295 = 10 // 10 - 0 = 10 // 11 - 1 = 10 #include <DigiUSB.h> // unsigned long 0 - 4294967295 unsigned long m = 4294967283; // 10 миллисекунд до переполнения. unsigned long nm = 4294967293; // 1 миллисекунд до переполнения. void setup() { DigiUSB.begin(); int n = 0; while(n < 14){ if (DigiUSB.tx_remaining() > 40) { // проверка места в буфере USB. ++n; ++m; ++nm; DigiUSB.print(nm); DigiUSB.print(" - "); DigiUSB.print(m); DigiUSB.print(" = "); DigiUSB.println(nm - m); // здесь предполагаем получить 10, если условие отрабатывается корректно. DigiUSB.delay(1); } DigiUSB.delay(1); } } void loop() {DigiUSB.delay(1);}Следующие исправления предложенные ЕвгенийП отработали коректно.
unsigned long CTime01; unsigned long LTime01; unsigned long CurM; unsigned long PriorM; void setup() { Serial.begin(9600); ;} void loop() { CTime01 = micros(); if( max(CTime01,LTime01)-min(CTime01,LTime01) > 1000000 ) { //*********************Тут что то делаем************************** CurM = millis(); Serial.println("LTlong= "+String((long)LTime01)+" LT= "+String(LTime01)+" millis()= "+String(CurM)+ " Delay="+String(CurM-PriorM)); PriorM = CurM; //*********************Тут что то делаем************************** LTime01 = CTime01; } }И конечный вариант:
unsigned long CTime01; unsigned long LTime01; void setup() { Serial.begin(9600); ;} void loop() { CTime01 = micros(); if( max(CTime01,LTime01)-min(CTime01,LTime01) > 1000000 ) { Serial.println("OK"); LTime01 = CTime01; } }Правильней было бы инициализировать LTime01 не нулем, а, хотя бы в конце setup LTime01 = micros(). Впрочем это всего лишь рекомендация, поскольку задача абстрактная и требуемые точности к первому интервалу не описаны.
Следующие исправления предложенные ЕвгенийП отработали коректно.
при чём тут Евгений, если тебе достаточно понять в теории и убедиться на практике, что 0 - 4294967286 = 10 когда 0 и 4294967286 имеют тип unsigned long.
Okmor, правильный вариант (a-b)>c, ты утверждаешь, что правильно a>(b+c). С точки зрения высшей математики оба неравенства верны. Но мы имеем дело с программированием МК и с ограничением количества разрядов. Раз уж ты инженер-механик, давай в понятиях близких к механике рассмотрим в чем твоя ошибка. Допустим 'a' и 'b' это расстояния от 0 до 99, 'с' это интервал. Возьмем:
a=5 b=2 c=10 5-2<10 и 5<2+10 оба неравенства верны
a=95 b=92 c=10 95-92<10 и 95<92+10 во втором случае переход через ноль 92+10=2, твое неравенство ложно.
На что пошли возражения про переполнение переменной LTime01. Предлагалось использовать код
if( millis() - t > interval ) { { action; } t = millis(); }Но этот код не учитывает время выполнения функции { action; }
ну, не учитывает - Лешак так видит.
не нужно считывать два раза millis() там, где это не требуется.
unsigned long nt = millis(); if( nt - t > interval ) {t = nt; {action;} }Следующие исправления предложенные ЕвгенийП
Я предлагал использовать min и max? Это гнусная клевета! Я никогда не предлагал такой глупости! Требую извинений!
Я в отличе от Вас знаю как устроена арифметика, и знаю, что достаточно просто вычитать длинные числа (хоть они unsigned, хоть нет - это всё равно) и сравнивать разность с заданным интервалом. При этом всё будет отлично работать и плевать на переполнение. Собственно, так и устроен пример "блинк без делэй" на этом сайте, который Вы никак понять не можете. Как там учитывать время исполнения я тоже знаю.
И не приписывайте мне чужие глупости, я и своих достаточно совершаю!
Требую извинений!
Рамзан Кадыров одобряет этот пост. :D
Как там учитывать время исполнения я тоже знаю.
блин. я не могу въехать в каком месте блинка без делау вылазит проблема времени исполнения кода?
и так и эдак смотрел - в упор не вижу проблемы.
Следующие исправления предложенные ЕвгенийП
Я предлагал использовать min и max? Это гнусная клевета! Я никогда не предлагал такой глупости! Требую извинений!
Я в отличе от Вас знаю как устроена арифметика, и знаю, что достаточно просто вычитать длинные числа (хоть они unsigned, хоть нет - это всё равно) и сравнивать разность с заданным интервалом. При этом всё будет отлично работать и плевать на переполнение. Собственно, так и устроен пример "блинк без делэй" на этом сайте, который Вы никак понять не можете. Как там учитывать время исполнения я тоже знаю.
И не приписывайте мне чужие глупости, я и своих достаточно совершаю!
Извините ЕвгенийП. -Вы цитировали пост vde69. Думаю так будет правильней.
Следующие исправления предложенные ЕвгенийП отработали коректно.
при чём тут Евгений, если тебе достаточно понять в теории и убедиться на практике, что 0 - 4294967286 = 10 когда 0 и 4294967286 имеют тип unsigned long.
10 плюсов не получается поставить Клапауций 322 за упрорство и сдержанность ;)
10 плюсов не получается поставить Клапауций 322 за упрорство и сдержанность ;)
достаточно сделать 10 аккаунтов tremboХХХ... и, ты личный читер Клапауция.
*кстати, почему я сам себя любимого могу плюсовать и минусовать? блин - я самокритичный и скромный.
Извините ЕвгенийП. -Вы цитировали пост vde69. Думаю так будет правильней.
Я цитировал со словами что "это не имеет отношения к теме", а Вы приписали мне его идею - явную глупость - нехорошо. Так не дискутируют.
10 плюсов не получается поставить Клапауций 322 за упрорство и сдержанность ;)
достаточно сделать 10 аккаунтов tremboХХХ... и, ты личный читер Клапауция.
*кстати, почему я сам себя любимого могу плюсовать и минусовать? блин - я самокритичный и скромный.
Просто мне напомнило тему про то, на что делить показания АЦП при вычислении напряжения: на 1023 или на 1024
Мой прадед говорил:
«Имею желание купить дом, но не имею возможности.
Имею возможность купить козу, но не имею желания».
Так выпьем за то, чтобы наши желания всегда совпадали с нашими возможностями.
Тоже иногда хочется плюсовать себя ( когда другие с этим не справляются)
Просто мне напомнило тему про то, на что делить показания АЦП при вычислении напряжения: на 1023 или на 1024
да. есть такой тупняк.
писал себе как-то часы на стрелочных головках амперметра
обрати внимание на 3600 и 3599 :D
Ух-ты! А такого я ещё не видел!
Ух-ты! А такого я ещё не видел!
ну, дарю - пользуйся: t - это секунды RTC, стрелки движутся плавно с дискретностью юстировки.