РЕКЛАМА НА ФОРУМХАУС Вернемся к нашим "баранам" Из чего следует, что у Netbykи каждые 49 дней переполняется счетчик миллисекунд и циклы виснут, а у тебя есть некая проверка на переполнение, как лекарство от этого. Только у ламеров "раз в 49 дней переполняется счетчик миллисекунд и циклы виснут" и только ламеры делают проверку на переполнение счетчиков миллисекунд. Всему виной непонимание целочисленной арифметики. Для абдуринщиков это норма. Не стану тебя просить показать код и так всё понятно.
Прочитал всё. Расскажи ка мне, Netbyka, про переполнение счетчика миллисекунд, сдается мне ты не вкуриваешь суть происходящего, раз несешь этот бред в массы. А стало быть имеешь все основания гордо нести звание - ламер.
Рассказываю, специально для знатока целочисленной арифметики: - есть функция, возвращающая 32-битное unsigned long, которое соответствует количеству миллисекунд с момента запуска девайса. - есть стандартный подход "из примеров" к коду, который в общем-то работает как должен, первое время: Код: if(millis() > (timer + 10000)){ timer = millis(); do_something(); } - но когда с момента старта девайса проходит 2^32 миллисекунд - FFFFFFFF превращается в 00000000, а вот такой вот пример кода превращается в тыкву, потому что, скажем, 1000, 2000, 3000, 1231344 millis() - все это будет меньше чем (4294962296 + 10000), где 4294962296 - предыдущее состояние timer. Знаток целочисленной арифметики, вероятно, знает как это победить - но вот компилятор, похоже, не очень, и он честно пытается сравнить 1231344 с (4294962296 + 10000). По крайней мере конкретно компилятор для Ардуины. Конечно, можно просто (тут знаток знает что нужно делать) - но обычный среднестатистический ардуинщик не знает. О чем и была речь. Но читать буквы знаток целочисленной арифметики не умеет, видимо...
Наверное, имеется в виду, что если ваш код переписать примерно так: Код: if((millis()-timer) > 10000){ timer = millis(); do_something(); } То переполнение не страшно. Такая вот unsigned арифметика. P. S. Если по простому, то когда в результате вычитания unsigned чисел получаем отрицательное число, то к нему добавляется максимальное (для этого типа) число и опять получаем unsigned. 1. Например, для беззнакового восьмибитного числа: 5 -10 = - 5 2. Так как результат отрицательный, то добавляем 255: -5 + 255 = 250 3. Получаем в результате: 5-10=250 Получается, что для состояний (восьмибитного) счетчика от 10 до 5 проходит 250 "тиков". Что правильно. И не важно, что счетчик в процессе счета переполнился. Результат всё равно правильный. Главное, чтобы он переполнился не более одного раза. P. P. S. @Andy-B, можно было бы и повежливее объяснить такой нюанс!
Это не мой код В принципе решений есть несколько, оодно из них, например - приводить (timer + XXX) к unsigned long в явном виде и сравнивать, другое - добавлять к timer ХХХ сразу после millis(), но надо учитывать что в этих случаях при переходе timer + ХХХ через 0 функция будет выполняться сразу, т. к. millis() "до 0" заведомо больше В общем есть нюансы.
ESP 8266: uint8_t n=5,m=10, f; void setup() { Serial. begin (115200); Serial. setTimeout (5); delay (1000); f=n-m; Serial. print("f="); Serial. println (f); if (n-m>1) Serial. println("n-m>1"); else Serial. println("n-m<=1"); } void loop() {} Результат: 22:31:30.512 -> f=251 22:31:30.512 -> n-m<=1 Преобразование типов самая опасная штука. Код на Ардуино, с использованием конструкциЙ (float) на ESP не работает. Приходится по строчкам делить. При переносе на другие платформы создает кучу проблем. 5 в 2сс 101, 10 в 2сс 1010. 5-10=5+(-10). В 2 сс получаем (код дополнительный) 101 - 1010= 101 + 11110110=11110111 (251 в 10 сс.). А вот в операторе if происходит преобразование типов. Так, что не все так просто, как в справочниках.
Понятно, что в жизни всё не просто. Я только пытался понять, о чём "товарищ" пытался сказать. (Кроме того, что он Д'Артаньян, а остальные "Ардуинщики") Может быть, и не угадал...
Мне всё таки кажется в подобных случаях правильнее отработать в рамках "unsigned" арифметики. То есть, через дельту состояний счетчика. Разумеется, тщательно отслеживая преобразования типов. P. S. Кстати, в сообщении выше я ошибся. В восьмибитной арифметике надо считать по модулю 256. То есть, прибавлять к отрицательным разностям не 255, а 256.
С учетом неявного преобразования типов в операторе if Как то так должно работать. И переполнения не должны влиять. Код: unsigned long time, timer; time = millis()-timer; if(time > 10000){ timer = millis(); do_something(); }
Вот в операторе if и преобразовывалось все в другой тип. Но не факт, что на Ардуино будет также. Я стараюсь обходить такие вещи. Даже выражения a && b | c, записываю (a && b) | c). Где то уже один раз с этим попал. Поэтому переполнение millis() определяю по тому, что текущее значение меньше предыдущего. Так как то надежнее, везде работать будет.
Будет, будет! Поэтому сначала вычисляем явно unsigned разницу, а потом уже её проверяем в if. Там уже любые преобразования типов будут не важны. Дельта счетчика уже вычислена. Главное, чтобы тип переменных совпадал с типом millis() - unsigned long. IMHO, так должно работать везде. Во всяком случае, я сейчас не вижу причин для другого поведения.
Я как бы три раза намекал на непонимание "товарищами" целочисленной арифметики. Но "товарищи" не только арифметики не понимают, но и намеков. У горе-программеров я вижу несколько проблем: -пытаются прибавлять к счетчику; -используют знаковую арифметику; -боятся вычитать из меньшего большее. Если делать беззнаковое вычитание, тогда никакое переполнение на результат не влияет и никакие костыли с проверками переполнения не нужны.
Ох и ах...отобрали ардуинку от детей и изгаляются кто как может... Берите выше и к вам потянутся люди. А детское отдайте детям.
К сожалению некоторые так и остаются детьми не взирая на возраст. Однажды поморгав светодиодом считают что видели всё. Им и в голову не приходит провести хоть какой-то сравнительный анализ: среды разработки, программных/аппаратных/технических решений. Куда ткнут пальцем, то и применяют. Замуровывают километры витой пары в стены. На кой х@р нужен CAN в выключателе? А ведь чел найдет массу обоснований его применения: надежность, скорость, обнаружение коллизий. Выключатель генерит 20-30 бит информации в сутки. Какой CAN? Или комп на винде в автоматизации дома, решение из разряда "я умею прогать под винду"... Или WiFi в каждой дырке... ППЦ. Чел так и не понял смысл: И ведь он абсолютно уверен, что ардуино это надежное универсальное техническое решение, его говнокод не ниже SDK и API, а стандарты языка программирования это для лохов, главное уметь моргать светодиодом. Доводы типа "6 лет работает" умиляют. А послезавтра накроется медным тазом его контроллер, встанет всё, пока он будет в темноте искать ему замену. Не может быть в автоматизации дома таких решений: "все яйца в одну корзину", "баня, через дорогу раздевалка". Можно и дальше метать бисер, но что это изменит... Ардуино во веки веков. Аминь.