Спасибо, не придавал значения таким тонкостям, а теперь буду! хотя в нашей деревне электричество вырубают регулярно, заботятся видимо, чтоб не было переполнения))
Статья на хабре недавно выходила. Как в самолетах боинг борются с переполнением? Решение очень "элегантное": они перезапускают электронику самолета каждые 274 дня ;-)
Скачал на всякий случай ролик, такая годнота на ютюбе не часто!!! Понимаю все со скрипом, читаю книги и пересматриваю ролики и с каждым разом все больше и больше понимания материала. Спасибо вам!!!
спасибо, все аргументированно и доступно объяснено. С первым видом записи был знаком и сознательно использовал, а вот второй вариант с приведением к знаковому- хорошая идея. Еще раз благодарен за идею.
что бы небыло переполнений, можно ли сделать на устройстве режим выкл, когда с выходов ничего не пойдет, произойдет безопасное отключение периферии и в конце сделать сброс таймера, это актуально для систем которые обесточиваются в конце дня или при выключении питания счетчики обнуляются?
Второй вариант нерабочий полностью, более того, компилятор цикл с условием беззнаковое меньше 0 скорее всего вообще выкинет. Если сравнивать с окончательным значением, то оба аргумента надо приводить к знаковому типу, тогда переполнение не страшно.
Для ESP8266 delay() обеспечивает поддержку стека WiFi и кормление сторожевого пса, там длинные циклы - верный путь к перезагрузке или потере пакетов WiFi.
Спасибо было интересно, если я правильно понял millis() можно использовать для своего таймера, так что-бы милисекунды считались с момента запуска функции таймера, а при каждом новом вызове, просто обновлять стартовое значение полученное из millis(). Допустим если программа будет работать как простые часы, что произойдет через 49 дней с такими часами?
Да все просто заводятся доп. переменные для дней,часов, минут. Но на практике это не нужно ведь есть довольно точные модули часов реального времени с батарейкой которые решают почти все проблемы.
Насколько стандартные настройки этих всяких ардуиновских millis и micro надёжно работают при передаче данных на больших скоростях, допустим при взаимодействии с радиомодулем или по usb с компом на больших скоростях? (больших - это например 1.5 Мбит/с, не жалкие 9600 стандартных бод в каждом проекте)
Функции работают на отсчетах аппаратного таймера, т.е. сами по себе отсчеты точны. Но учитывая время исполнения кода на 16 МГц 8 битах... Предельно короткие задержки даже на ассемблере трудно сделать стабильными.
@@alexmorozov73 хмм, ну ладно. Просто хотелось бы избежать перепиливания ардуиновских библиотек в работоспособное для этих целей состояние, но, если вы правы, проще свою оптимизацию сделать
Что за абсурдные вопросы? Вы ВЫЗЫВАЕТЕ функцию, она не работает, а просто при очередном вызове возвращает текущее значение на основании таймера. Зачем ее обнулять?
Alex Morozov Давайте разберём на примере. Имеется концевик и пир датчик. Из нагрузки освещение и вентилятор. Свет зависит от датчиков а вентилятор от времени. Дэлэй невыгоден - можно пропустить срабатывания датчиков. С функцией милис весь цикл работать должен без сбоев и остановок.
Ответьте на единственный вопрос. Так как millis не очень корректно на ардуино работает, как я понимаю можно использовать micros по такому же алгоритму?
А что не так с millis? И millis и micros работают на таймерах. Соответственно, разница только в точности. И 32-х битный micros может считать всего на 71.5 мин. в отличие от 49+ суток миллисекунд в millis. А само сравнение с переполнением, естественно, будет одинаковым.
@@alexmorozov73 Дело в том что я на Драйве читал статьи и люди фото прилагали что с миллис время за сутки на ардуино с реальным отсчетом не совпадает более чем на 10 минут, с микрос дела лучше. Потом посмотрел это видео ruclips.net/video/m3ViTkyPUKo/видео.html 16:14 рассказывает о том что на ардуино не гарантирован по точности счетчик, то есть если запрошено 3 миллисекунды то они могут истечь через 1 миллисекунду, как по вашим наблюдениям есть такая проблема? Спасибо за ответ!
Макетируйте! Добавьте к AVR RTC-часы и раз в час сверяйте время из часов и показания millis. Сами все узнаете. А на конкретных платах и кварц может быть нестабильным, и питание ненадежным, все это может оказать влияние на стабильность таймеров.
Автору: Совет - для перехода на слово вперед/назад юзай стрелки + Ctrl - для выделения слова к вышеуказанному добавь Shift. Не будет лишних движений (так сказать не будем оленями :) )
"А мужики то не знают!" (С) :) Меня и так ругают, что я слишком быстро что-то делаю. Чаще всего я делаю что-то неоптимальным образом просто чтобы подумать, что сказать дальше, потому что снимаю без "черновиков" и плана.
Ясно. В целом лекции отличные. И даже меньше по обьему за раз идут на пользу. Лет 15 назад я говорил, что С не для меня (писал исключительно на Дельфи) Но увлечение программированием и контроллерами сделали свое дело - вот я уже и программирую ардуино, потому как легче сделать самому, чем найти действительно грамотного человека. С вашими уроками стало полегче в понимании С++ за что ОГРОМНОЕ СПАСИБО. Буду премного благодарен, если рассмотрите вопрос общения нескольких *дуин по интерфейсу RS-485, потому как опыта мало и написание сей возможности идет пока совково :(
Прошу помощи, пожалуйста разжуйте мне как это понять: stepTime = 1; void loop(){ millisStart = millis(); while(millis() - millisStart < stepTime){ do{ ... }while(условие) millisStart = 0L; } ... } плюс возможно увеличение / уменьшение stepTime во время выполнения кода. Как (millis() - millisStart < stepTime) может оставаться истиной, или когда оно может быть истиной?
Это что за поток сознания? :) За 1 мс. процессор на 16 МГц выполняет до 16 млн. простейших операций (в среднем по 2-4 такта на операцию, т.е. 4-8 млн. операций). Значит первый while до 1 мс. может повторяться без проблем. А чтобы менять переменную условия цикла в самом цикле и точно не зависеть от оптимизации компиллятора, ее можно объявить с ключевым словом volatile, что запретит оптимизировать код с ней.
@@alexmorozov73 Вот как я понимаю: присваиваем millisStart текущее значение millis(), и допустим это абстрактные 28 микросекунд, далее переходим к следующей процедуре, и наверняка значение millis увеличилось, ну допустим до 29 микросекунд, так вот : while нас спрашивает: (millis() - millisStart < stepTime), то есть (29-28
Миллисекунды! Еще раз говорю, millis() увеличится через 1 мс. Это не так уж и мало. Код выглядит странно в любом случае. Особенно присвоение 0 переменной, которая из millis() вычитается, делая сравнение бессмысленным, вместо break, если уж нужно из цикла выйти. А само исполнение кода от кривизны реализации не зависит и оно очевидно. Не понимаю в чем вопрос. Вы и так описали как оно работает.
(Сначала дисклаймер: если автор адекватный, то поймет, а если нет, то может не читать этот коммент) Спасибо! Понимаю, что Вам мое спасибо, как клизма мертвому, но мне похрен, я спасибо не для Вас говорю, а для себя.. Но если вы человек с толстой душевной организацией (не ООО и не ИП, а OAO ну или хотя б ЗАО). Блин я запутался.. ну да хрен с ним. Крч. Спасибо.. реально годный материал! // !сарказм
Если коротко - на практике нет никакой проблемы переполнения. Очень мало вероятно что интервалы которые нужно будет будут близки к ~49дням Естественно если проверяется правильным способом через if(millis()-start >= interval) { // timeout event } И главное конечно использовать unsigned long, а не какие то левые типы.
Спасибо, не придавал значения таким тонкостям, а теперь буду! хотя в нашей деревне электричество вырубают регулярно, заботятся видимо, чтоб не было переполнения))
Отключения происходят каждые ~50 дней? Наверняка так и есть. =)
видимо delay и break срабатывает
Статья на хабре недавно выходила. Как в самолетах боинг борются с переполнением? Решение очень "элегантное": они перезапускают электронику самолета каждые 274 дня ;-)
Скачал на всякий случай ролик, такая годнота на ютюбе не часто!!! Понимаю все со скрипом, читаю книги и пересматриваю ролики и с каждым разом все больше и больше понимания материала. Спасибо вам!!!
...тупо сравниваем,остро вычитаем,нежно делим, сладко используем.Где найти аписание аленьей логики?
Продолжения бы годных проектов. Далеко не все тут программисты. В расчете на адекватное осознание этого комментария.
спасибо, все аргументированно и доступно объяснено. С первым видом записи был знаком и сознательно использовал, а вот второй вариант с приведением к знаковому- хорошая идея. Еще раз благодарен за идею.
что бы небыло переполнений, можно ли сделать на устройстве режим выкл, когда с выходов ничего не пойдет, произойдет безопасное отключение периферии и в конце сделать сброс таймера, это актуально для систем которые обесточиваются в конце дня или при выключении питания счетчики обнуляются?
Stop=millis()+timeout;
while(millis()
В одно ухо влетело, из другого вылетело?
//1) вариант первый. простой
#define TIMEOUT 60000
uint32_t start = millis();
while(millis() - start < TIMEOUT) {/*_*/}
//
//2) вариант второй. когда TIMEOUT сложное и хочется определить его заранее
uint32_t Timeout = 1000*60;
uint32_t stop = millis() + Timeout;
while((int32_t)(millis() - stop) < 0) {/*_*/} //изм.
Второй вариант нерабочий полностью, более того, компилятор цикл с условием беззнаковое меньше 0 скорее всего вообще выкинет. Если сравнивать с окончательным значением, то оба аргумента надо приводить к знаковому типу, тогда переполнение не страшно.
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));
}
}
Чем цикл отличается от delay? И там и там бесполезно обращатся к процессору, пока цикл не закончится.
Для ESP8266 delay() обеспечивает поддержку стека WiFi и кормление сторожевого пса, там длинные циклы - верный путь к перезагрузке или потере пакетов WiFi.
Спасибо было интересно, если я правильно понял millis() можно использовать для своего таймера, так что-бы милисекунды считались с момента запуска функции таймера, а при каждом новом вызове, просто обновлять стартовое значение полученное из millis(). Допустим если программа будет работать как простые часы, что произойдет через 49 дней с такими часами?
Через 49,7 дней "часы" видимо вернутся в "прошлое" и так по кругу.
Да все просто заводятся доп. переменные для дней,часов, минут.
Но на практике это не нужно ведь есть довольно точные модули часов реального времени с батарейкой которые решают почти все проблемы.
Насколько стандартные настройки этих всяких ардуиновских millis и micro надёжно работают при передаче данных на больших скоростях, допустим при взаимодействии с радиомодулем или по usb с компом на больших скоростях? (больших - это например 1.5 Мбит/с, не жалкие 9600 стандартных бод в каждом проекте)
Функции работают на отсчетах аппаратного таймера, т.е. сами по себе отсчеты точны. Но учитывая время исполнения кода на 16 МГц 8 битах... Предельно короткие задержки даже на ассемблере трудно сделать стабильными.
@@alexmorozov73 хмм, ну ладно. Просто хотелось бы избежать перепиливания ардуиновских библиотек в работоспособное для этих целей состояние, но, если вы правы, проще свою оптимизацию сделать
Сколько этих функций может работать одновременно? Как обнулить эту функцию?
Что за абсурдные вопросы?
Вы ВЫЗЫВАЕТЕ функцию, она не работает, а просто при очередном вызове возвращает текущее значение на основании таймера. Зачем ее обнулять?
Alex Morozov Давайте разберём на примере. Имеется концевик и пир датчик. Из нагрузки освещение и вентилятор. Свет зависит от датчиков а вентилятор от времени. Дэлэй невыгоден - можно пропустить срабатывания датчиков. С функцией милис весь цикл работать должен без сбоев и остановок.
Ответьте на единственный вопрос. Так как millis не очень корректно на ардуино работает, как я понимаю можно использовать micros по такому же алгоритму?
А что не так с millis? И millis и micros работают на таймерах. Соответственно, разница только в точности. И 32-х битный micros может считать всего на 71.5 мин. в отличие от 49+ суток миллисекунд в millis.
А само сравнение с переполнением, естественно, будет одинаковым.
@@alexmorozov73 Дело в том что я на Драйве читал статьи и люди фото прилагали что с миллис время за сутки на ардуино с реальным отсчетом не совпадает более чем на 10 минут, с микрос дела лучше. Потом посмотрел это видео ruclips.net/video/m3ViTkyPUKo/видео.html 16:14 рассказывает о том что на ардуино не гарантирован по точности счетчик, то есть если запрошено 3 миллисекунды то они могут истечь через 1 миллисекунду, как по вашим наблюдениям есть такая проблема? Спасибо за ответ!
Макетируйте! Добавьте к AVR RTC-часы и раз в час сверяйте время из часов и показания millis. Сами все узнаете.
А на конкретных платах и кварц может быть нестабильным, и питание ненадежным, все это может оказать влияние на стабильность таймеров.
@@alexmorozov73 Все понятно, спасибо большое!
@@TyurinAlexey Честно говоря я тоже смотрел это видео и так и не понял что Автушенко имел ввиду.
Автору: Совет - для перехода на слово вперед/назад юзай стрелки + Ctrl - для выделения слова к вышеуказанному добавь Shift. Не будет лишних движений (так сказать не будем оленями :) )
"А мужики то не знают!" (С) :)
Меня и так ругают, что я слишком быстро что-то делаю. Чаще всего я делаю что-то неоптимальным образом просто чтобы подумать, что сказать дальше, потому что снимаю без "черновиков" и плана.
Ясно. В целом лекции отличные. И даже меньше по обьему за раз идут на пользу. Лет 15 назад я говорил, что С не для меня (писал исключительно на Дельфи) Но увлечение программированием и контроллерами сделали свое дело - вот я уже и программирую ардуино, потому как легче сделать самому, чем найти действительно грамотного человека. С вашими уроками стало полегче в понимании С++ за что ОГРОМНОЕ СПАСИБО. Буду премного благодарен, если рассмотрите вопрос общения нескольких *дуин по интерфейсу RS-485, потому как опыта мало и написание сей возможности идет пока совково :(
Да и еще забыл - может вы знакомы с модулем Yun Shield ? - (трудности с пониманием его программирования)
Yun не видел. Так что увы. Живу по заветам Медведа, т.е. держусь. :)
Прошу помощи, пожалуйста разжуйте мне как это понять:
stepTime = 1;
void loop(){
millisStart = millis();
while(millis() - millisStart < stepTime){
do{
...
}while(условие)
millisStart = 0L;
}
...
}
плюс возможно увеличение / уменьшение stepTime во время выполнения кода.
Как (millis() - millisStart < stepTime) может оставаться истиной, или когда оно может быть истиной?
Это что за поток сознания? :)
За 1 мс. процессор на 16 МГц выполняет до 16 млн. простейших операций (в среднем по 2-4 такта на операцию, т.е. 4-8 млн. операций). Значит первый while до 1 мс. может повторяться без проблем.
А чтобы менять переменную условия цикла в самом цикле и точно не зависеть от оптимизации компиллятора, ее можно объявить с ключевым словом volatile, что запретит оптимизировать код с ней.
@@alexmorozov73 Вот как я понимаю:
присваиваем millisStart текущее значение millis(), и допустим это абстрактные 28 микросекунд, далее переходим к следующей процедуре, и наверняка значение millis увеличилось, ну допустим до 29 микросекунд, так вот : while нас спрашивает: (millis() - millisStart < stepTime), то есть (29-28
Миллисекунды! Еще раз говорю, millis() увеличится через 1 мс. Это не так уж и мало.
Код выглядит странно в любом случае.
Особенно присвоение 0 переменной, которая из millis() вычитается, делая сравнение бессмысленным, вместо break, если уж нужно из цикла выйти.
А само исполнение кода от кривизны реализации не зависит и оно очевидно. Не понимаю в чем вопрос. Вы и так описали как оно работает.
@@alexmorozov73 если я правильно описал как оно работает, то теперь и я задаюсь вопросом: а чё не break?
спасибо за помощь
А откуда этот код? Что там за "условие"?
(Сначала дисклаймер: если автор адекватный, то поймет, а если нет, то может не читать этот коммент)
Спасибо! Понимаю, что Вам мое спасибо, как клизма мертвому, но мне похрен, я спасибо не для Вас говорю, а для себя.. Но если вы человек с толстой душевной организацией (не ООО и не ИП, а OAO ну или хотя б ЗАО).
Блин я запутался.. ну да хрен с ним. Крч.
Спасибо.. реально годный материал! // !сарказм
Если коротко - на практике нет никакой проблемы переполнения.
Очень мало вероятно что интервалы которые нужно будет будут близки к ~49дням
Естественно если проверяется правильным способом через
if(millis()-start >= interval) { // timeout event }
И главное конечно использовать unsigned long, а не какие то левые типы.
Ага, диспетчерская аэропорта как то переполнилась и на несколько часов потеряла видимость самолётов.