на самом деле, это часть другой идеи - очереди сообщений. Когда таймеры опрашивают датчики вразнобой, то вызываемые функции кладут в очередь сообщений что что-то изменилось. А цикл обработки сообщений уже делает все что нужно дальше по логике.
Например, добавляем таймер, который срабатывает раз в секунду. Функция увеличивает, допустим счетчик секунд, и если изменились минуты или часы, тогда в очередь сообщений помещается команда перерисовать дисплей. В loop() организована выборка сообщений из очереди и вызов соответствующих функций-обработчиков для данного сообщения. Точно так же со всевозможными датчиками и реле. Если показания датчиков изменились, просто добавляем в очередь сообщение на вкл/выкл исполнительного механизма, и при следующем проходе он будет включен/выключен.
Как только доделаю очередь сообщений - сразу выложу туда же.
Подход интересный. Но не безпроблемная идея. Сам такое юзаю уже не один год, только ориентированую на трудный временной интервал от 10мксек и выше с заточками под аппаратную часть, на 1Ware, серву и т.д.. Формировать интервалы от 1мсек как бы особо и не задача, и соответственно таймер 16-битный на такое жалко. Надо помнить что CallingFunc, вызывается из обработчика прерываний, является его частью и потому соответствующие ограничения. Формирование интервалов времени будет иметь ограниченую точность, пока не завершится один CallingFunc другой интервал не наступит и если она завершится через 10мсек, то это может удлинить другие интервалы на время от 0 до 10мсек, как карта ляжет. Особенно проблемно при кратных и близких к кратным периодах.
Мое ИМХО - это западня для новичков :) Соблазнятся на кажущуюся простоту, заюзают понаписывают чертечего в CallingFunc и будут вобще не понимать чего оно глючит, виснет, и тупит.
нуу, для тех кто понимает, что функции должны быть короткими - я думаю, подспорье. На самом деле на 16 мегагерцах за 1 миллисекунду процессор успеет выполнить больше 10000 инструкций. Конечно функцию можно и длиннее написать, ну я нинаю.
Я лично использую, чтоб опросить датчик(и), сравнить с ранее сохраненным и если есть изменения - положить нужное сообщение в очередь.
А вообще, было время, на Спектруме (3.5 Мгц) и не такое писали :)
Я понял, что с таймерами всё не так просто, написал код по образцу Timer2 и вот после внедрения этого кода начались необъяснимые процессы )))
Лучшее враг хорошего!
Её богу руки растут откуда надо так что кто хочет попинать,
Я лично использую, чтоб опросить датчик(и), сравнить с ранее сохраненным и если есть изменения - положить нужное сообщение в очередь.
Оно конечно верно, но посмотрим на весь процесс в комплексе начиная от "есть изменения" до реакции на них, которые очевидно будут при обработке очередного сообщения из очереди. Где будет узкое место с возможной наибольшей задержкой? - в обработке очереди, т.е. лупе. Сообщения просто будут лежать и ждать сколько прийдется. А смыслу тогда с опросом датчика в прерывании, кроме случая когда надо строго выдерживать период опроса, типа оцифровки звука (но и выдерживать период с проблемами, выше писал). А датчикам обычным, типа температуры или давления - все по барабану.
Я в данный момент пишу автоматизацию теплицы в даче, еще не закончил, со звуком не работаю, датчики дубовые, исполнительные механизмы - еще дубовее, прецизионность особо и не нужна, да я на нее и не претендую. Выложил, так как реально помогает избавить простой код от многочисленных if и прочего мусора millis()-prevmillis>.... Новички пусть и решают, учитывая и Ваше мнение, хотят ли оне попасть в засаду простоты. Я готов отвечать на вопросы.
Выложил, так как реально помогает избавить простой код от многочисленных if и прочего мусора millis()-prevmillis>....
Решение этой неприятности известно, и на форуме дето выкладывалось и обсуждалось. В массивы собираем все интервалы и их функции-одработчики, а в лупе цикл бегает по массиву и ищет кого пора вызывать. В общеи похоже на то, что у Вас с одним приятным отличием - функции-одработчики не из прерывания вызываются, что заметно облегчает жизнь. Но такой подход требует быстрого лупа, для интервалов 1мсек это не просто, но реально. И очередь сообщений тут сильный помошник. А вот менее- уже не реально. Потому для интервалов 10мксек-1мсек я и делаю как у Вас, а для длинных интервалов if (millis()-prevmillis>.... а если их много то в массив, как выше писал. Но часто нужна "сетка" интервалов, чтото типа 10мсек, 1сек, 1мин... тогда через if (millis()-prevmillis> только первый, а остальные как 100шт 10мсек это 1 сек, а 60шт 1сек целая минута. Так проще.
Важно уметь из вариантов выбрать именно то, что в конкретной задаче правильно. А для этого полезно знать + и - того или иного подхода. Универсального идеального, увы нет.
Начал припоминать свой код, и похоже у нас есть одно заметное отличие. У меня список аналогичный Вашим TCallStruct сортирован по WorkingCounter, т.е. ближайший завершающийся интервал самый первый. Соответственно при добавлении нового я ищу ему место в списке для сохранения сортировки. Зато по истечению интервала ничего искать не надо, он первый!
Дет! Что же Вы TimerList.AddStopped изничтожили, а в Редми не подчистили? Непорядок))
Принято к сведению, спасибо, поправлю. Запуск переехал в Add(), последним параметром bool, TIMER_RUNNING (по умолчанию) или TIMER_STOPPED (надо прописывать ручками)
Дет! Что же Вы TimerList.AddStopped изничтожили, а в Редми не подчистили? Непорядок))
Принято к сведению, спасибо, поправлю. Запуск переехал в Add(), последним параметром bool, TIMER_RUNNING (по умолчанию) или TIMER_STOPPED (надо прописывать ручками)
Это уже понял, но пришлось в исходники лезть, а это попаболь для таких програмиздов как я))
А про AddSeconds() и AddMinutes() не вспомнили(( Я сразу не написал, извините.
Ведь стОящая библиотека, не раскрученная тока! У меня 4 диодика моргают с 4-мя различными частотами в зависимости от входного с датчика. Код моргунчиков в 22 стоки уместился!
подпишусь, как нибудь попробую, спасибо
Надо попробовать, а то у меня стандартный Timer2 периодически сыпет мусор в сериал )))
на самом деле, это часть другой идеи - очереди сообщений. Когда таймеры опрашивают датчики вразнобой, то вызываемые функции кладут в очередь сообщений что что-то изменилось. А цикл обработки сообщений уже делает все что нужно дальше по логике.
Например, добавляем таймер, который срабатывает раз в секунду. Функция увеличивает, допустим счетчик секунд, и если изменились минуты или часы, тогда в очередь сообщений помещается команда перерисовать дисплей. В loop() организована выборка сообщений из очереди и вызов соответствующих функций-обработчиков для данного сообщения. Точно так же со всевозможными датчиками и реле. Если показания датчиков изменились, просто добавляем в очередь сообщение на вкл/выкл исполнительного механизма, и при следующем проходе он будет включен/выключен.
Как только доделаю очередь сообщений - сразу выложу туда же.
Подход интересный. Но не безпроблемная идея. Сам такое юзаю уже не один год, только ориентированую на трудный временной интервал от 10мксек и выше с заточками под аппаратную часть, на 1Ware, серву и т.д.. Формировать интервалы от 1мсек как бы особо и не задача, и соответственно таймер 16-битный на такое жалко. Надо помнить что CallingFunc, вызывается из обработчика прерываний, является его частью и потому соответствующие ограничения. Формирование интервалов времени будет иметь ограниченую точность, пока не завершится один CallingFunc другой интервал не наступит и если она завершится через 10мсек, то это может удлинить другие интервалы на время от 0 до 10мсек, как карта ляжет. Особенно проблемно при кратных и близких к кратным периодах.
Мое ИМХО - это западня для новичков :) Соблазнятся на кажущуюся простоту, заюзают понаписывают чертечего в CallingFunc и будут вобще не понимать чего оно глючит, виснет, и тупит.
нуу, для тех кто понимает, что функции должны быть короткими - я думаю, подспорье. На самом деле на 16 мегагерцах за 1 миллисекунду процессор успеет выполнить больше 10000 инструкций. Конечно функцию можно и длиннее написать, ну я нинаю.
Я лично использую, чтоб опросить датчик(и), сравнить с ранее сохраненным и если есть изменения - положить нужное сообщение в очередь.
А вообще, было время, на Спектруме (3.5 Мгц) и не такое писали :)
Я понял, что с таймерами всё не так просто, написал код по образцу Timer2 и вот после внедрения этого кода начались необъяснимые процессы )))
Лучшее враг хорошего!
Её богу руки растут откуда надо так что кто хочет попинать,
Я лично использую, чтоб опросить датчик(и), сравнить с ранее сохраненным и если есть изменения - положить нужное сообщение в очередь.
Оно конечно верно, но посмотрим на весь процесс в комплексе начиная от "есть изменения" до реакции на них, которые очевидно будут при обработке очередного сообщения из очереди. Где будет узкое место с возможной наибольшей задержкой? - в обработке очереди, т.е. лупе. Сообщения просто будут лежать и ждать сколько прийдется. А смыслу тогда с опросом датчика в прерывании, кроме случая когда надо строго выдерживать период опроса, типа оцифровки звука (но и выдерживать период с проблемами, выше писал). А датчикам обычным, типа температуры или давления - все по барабану.
Я в данный момент пишу автоматизацию теплицы в даче, еще не закончил, со звуком не работаю, датчики дубовые, исполнительные механизмы - еще дубовее, прецизионность особо и не нужна, да я на нее и не претендую. Выложил, так как реально помогает избавить простой код от многочисленных if и прочего мусора millis()-prevmillis>.... Новички пусть и решают, учитывая и Ваше мнение, хотят ли оне попасть в засаду простоты. Я готов отвечать на вопросы.
Выложил, так как реально помогает избавить простой код от многочисленных if и прочего мусора millis()-prevmillis>....
Решение этой неприятности известно, и на форуме дето выкладывалось и обсуждалось. В массивы собираем все интервалы и их функции-одработчики, а в лупе цикл бегает по массиву и ищет кого пора вызывать. В общеи похоже на то, что у Вас с одним приятным отличием - функции-одработчики не из прерывания вызываются, что заметно облегчает жизнь. Но такой подход требует быстрого лупа, для интервалов 1мсек это не просто, но реально. И очередь сообщений тут сильный помошник. А вот менее- уже не реально. Потому для интервалов 10мксек-1мсек я и делаю как у Вас, а для длинных интервалов if (millis()-prevmillis>.... а если их много то в массив, как выше писал. Но часто нужна "сетка" интервалов, чтото типа 10мсек, 1сек, 1мин... тогда через if (millis()-prevmillis> только первый, а остальные как 100шт 10мсек это 1 сек, а 60шт 1сек целая минута. Так проще.
Ну вот и альтернатива. :)
Ага:)
Важно уметь из вариантов выбрать именно то, что в конкретной задаче правильно. А для этого полезно знать + и - того или иного подхода. Универсального идеального, увы нет.
Начал припоминать свой код, и похоже у нас есть одно заметное отличие. У меня список аналогичный Вашим TCallStruct сортирован по WorkingCounter, т.е. ближайший завершающийся интервал самый первый. Соответственно при добавлении нового я ищу ему место в списке для сохранения сортировки. Зато по истечению интервала ничего искать не надо, он первый!
Ну, наверное, это разумно. Я не догадалса.
нихрена не понял, но чую, мне это надо )))
нихрена не понял, но чую, мне это надо )))
Дак пропробуй
Дет! Что же Вы TimerList.AddStopped изничтожили, а в Редми не подчистили? Непорядок))
Дет! Что же Вы TimerList.AddStopped изничтожили, а в Редми не подчистили? Непорядок))
Принято к сведению, спасибо, поправлю. Запуск переехал в Add(), последним параметром bool, TIMER_RUNNING (по умолчанию) или TIMER_STOPPED (надо прописывать ручками)
Дет! Что же Вы TimerList.AddStopped изничтожили, а в Редми не подчистили? Непорядок))
Принято к сведению, спасибо, поправлю. Запуск переехал в Add(), последним параметром bool, TIMER_RUNNING (по умолчанию) или TIMER_STOPPED (надо прописывать ручками)
Это уже понял, но пришлось в исходники лезть, а это попаболь для таких програмиздов как я))
Updated.
А про AddSeconds() и AddMinutes() не вспомнили(( Я сразу не написал, извините.
Ведь стОящая библиотека, не раскрученная тока! У меня 4 диодика моргают с 4-мя различными частотами в зависимости от входного с датчика. Код моргунчиков в 22 стоки уместился!
Код моргунчиков в 22 стоки уместился!
нудакёптать. :)
А про AddSeconds() и AddMinutes() не вспомнили(( Я сразу не написал, извините.
Хочу заново написать нормальное описание, вместо этой ахинеи.
Хочу заново написать нормальное описание
С одной стороны и без описания разораться не мудрЕно, но не помешало бы