И, этот способ ну, мягко говоря, не очень, особенно когда всего лишь нужно мигать светодиодом.
Код громоздок, избыточен, требует кучи лишних переменных. Если его нужно несколько раз использовать, а то и для нескольких светодиодов имеем еще и проблемы с синхронизацией.
Т.к. программа обычно делает еще что-то кроме мигания светодиодом, то мы никогда точно не знаем когда она доберется до if(millis() - previousMillis > interval) – интервал мигания может быть очень нестабильный, если светодиодов несколько, и они могут мигать вообще вразнобой, что иногда плохо или банально некрасиво. Ну, и тут очень простоя программа мигания, если нужно сделать что-то красивее нужно городить еще кучу ifов.
Короче, предлагаю, простой, короткий и довольно универсальный вариант:
Переменная blnk – задает тип мигания, если она равно 0 – диод не горит совсем, если 255 – то все время, в других случаях разнообразно мигает (надеюсь понятно почему как). Тут все легко масштабировать, как на кол-во светодиодов, так и по способу мигания. И да, разные светодиоды будут мигать в унисон. Управлять их миганием очень просто – нужно лишь внутри кода менять blnk по необходимости.
А в исходном варианте к чему привязка идёт?
Поставьте в 8-й строке "стабильного" варианта delay(random(255)) и проверьте - действительно ли есть различия.
А в исходном варианте к чему привязка идёт? Поставьте в 8-й строке "стабильного" варианта delay(random(255)) и проверьте - действительно ли есть различия.
Ну, использование delay - это вообще вредительство, тут тогда вообще все только через прерывания нормально будет работать, а их использование, ИМХО, не всегда оправдано. В моем варианте, как минимум не будет происходит накопление ошибки. Даже если программа по пути "затупит", по из-за делая, или по более веской причине, в любом случае в следующем цикле все устоканится и рассинхрона не будет. "Классический" пример в любом случае оказывается еще хуже.
Видимо для деления на 1000 есть короткий алгоритм, по этому код не сильно вырос
Перебрал несколько вариантов - все в пределах 844 - 848 байт.
Komandir пишет:
Так millis не кратно 1000 и будет один периодический конкретный рассинхрон.
А чему оно кратно? Я в одном проекте этот способ использую, рассинхрона не наблюдаю. У меня там несколько диодов мигают. А вот со старым способом - наоборот все довольно быстро уплывало, нужно было специально с этим бороться.
Задача должна правильно решаться на всем временном отрезке ! Если вы этого не понимаете, то не надо других вводить в блуд вашего заблуждения !!!
А Вы собственно, какую задачу решаете? Управление АЭС? Я вот решал задачу - красиво и просто мигать светодиодами, которые являются индикаторами некоторых процессов, от которых не зависят чья либо жизни и здоровье, а так же состояние экономики страны. Предложенный мною код, с этой задачей справляется на 99,9999%, при этом экономит, как ни странно, память и нервы. Опять таки, по сравнению с "классикой" я не вижу недостатков. А использование прерываний, а так же отслеживания обнуления millis - для данной задачи избыточная сложность, у нас тут, видите ли, МК с весьма ограниченными ресурсами, чтоб все их тратить на совсем уж идеальное мигание.
Если можете предложить способ ЛУЧШЕ, для данной задачи - милости просим.
Я можно сказать жизнь доверил МК - использую его в качестве круиз-контроля.
Ну, тогда я Вам официально запрещаю использовать предложенный мною код, не хочу брать грех на душу... Хотя нет, я же не претендую на авторство, и ни как не могу регламентировать использование кода.
RxMaxx видимо сегодня как раз тот 40 день у движка форума
Да не, это все код виноват зловредный, стопудово. Одно его существование сломало форум, я уж молчу про Чернобыль и COVID19. Он уже пробил брешь в пространстве-времени и создал черную дыру.
Если можете предложить способ ЛУЧШЕ, для данной задачи - милости просим.
Это не ЛУЧШЕ, но некоторые замечания. (Времена примерные, т.к. смотрел на симуляторе.)
i=(unsignedLongL/1000)%2; занимает около 600 тактов
i=(unsignedLongL/1024)%2; занимает около 77 тактов.
Иногда это может иметь значение. И если надо просто моргать, а не отмерять интервалы, то может имеет смысл делить на 1024. (можно пойти дальше и читать внутренний счетчик и вообще не делить, но это наверное перебор ).
Есть только Цезий-133 непогрешимый, все остальные "счётчики" так или иначе пропускают, даже Земля наша, не зря же високосные дни и даже секунды придумали.
Да, если делить не на 1000 а на степень двойки, то можно сэкономить еще целых 92 байта! Что делает код еще меньше и быстрее по сравнению с "классикой", но чаще все таки приходится использовать обычные секунды (и кратные им), и страдать за это, даже millis страдают. Наша система измерения времени вообще жутко неудобная с точки зрения программирования, что ж поделать то.
не зря же високосные дни и даже секунды придумали.
Пример неудачный, ибо григорианский календарь есть явная провокация Врага рода человеческого. Посудите сами, ввёл его папа Григорий тринадцатый, а тринадцатые числа в нём попадают на пятницу чаще, чем на любой другой день недели!
Дело в том, что я не заменил строчку i=(uL/1024)%2, а добавил k=(uL>>10) & 0x01 и компилятор просто взял готовый ответ.
И в том и в другом случае занимает около 80 тактов.
00000094 CLI Global Interrupt Disable
k= (uL>>10) & 0x01;
00000095 LDS R24,0x0112 Load direct from data space
00000097 LDS R25,0x0113 Load direct from data space
00000099 LDS R26,0x0114 Load direct from data space
0000009B LDS R27,0x0115 Load direct from data space
0000009D LDI R18,0x0A Load immediate
0000009E LSR R27 Logical shift right
0000009F ROR R26 Rotate right through carry
000000A0 ROR R25 Rotate right through carry
000000A1 ROR R24 Rotate right through carry
000000A2 DEC R18 Decrement
000000A3 BRNE PC-0x05 Branch if not equal
000000A4 ANDI R24,0x01 Logical AND with immediate
000000A5 STS 0x0117,R24 Store direct to data space
cli();
000000A7 CLI Global Interrupt Disable
Давайте еще раз помигаем светодиодом. Не претендую на оригинальность, все уже когда-то было, но я таки пришел вот к такому способу.
Обычно, когда речь идет о каких-либо периодических действиях, то чаще всего предлагается подобный алгоритм:
И, этот способ ну, мягко говоря, не очень, особенно когда всего лишь нужно мигать светодиодом.
Код громоздок, избыточен, требует кучи лишних переменных. Если его нужно несколько раз использовать, а то и для нескольких светодиодов имеем еще и проблемы с синхронизацией.
Т.к. программа обычно делает еще что-то кроме мигания светодиодом, то мы никогда точно не знаем когда она доберется до if(millis() - previousMillis > interval) – интервал мигания может быть очень нестабильный, если светодиодов несколько, и они могут мигать вообще вразнобой, что иногда плохо или банально некрасиво. Ну, и тут очень простоя программа мигания, если нужно сделать что-то красивее нужно городить еще кучу ifов.
Короче, предлагаю, простой, короткий и довольно универсальный вариант:
Переменная blnk – задает тип мигания, если она равно 0 – диод не горит совсем, если 255 – то все время, в других случаях разнообразно мигает (надеюсь понятно почему как). Тут все легко масштабировать, как на кол-во светодиодов, так и по способу мигания. И да, разные светодиоды будут мигать в унисон. Управлять их миганием очень просто – нужно лишь внутри кода менять blnk по необходимости.
Не хочу расстраивать, но и в Вашем случае особой стабилизации интервала мигания не наблюдается.
Почему же? Тут идет привязка точно к millis, ни что никуда не уплывет.
А в исходном варианте к чему привязка идёт?
Поставьте в 8-й строке "стабильного" варианта delay(random(255)) и проверьте - действительно ли есть различия.
Ну, использование delay - это вообще вредительство, тут тогда вообще все только через прерывания нормально будет работать, а их использование, ИМХО, не всегда оправдано. В моем варианте, как минимум не будет происходит накопление ошибки. Даже если программа по пути "затупит", по из-за делая, или по более веской причине, в любом случае в следующем цикле все устоканится и рассинхрона не будет. "Классический" пример в любом случае оказывается еще хуже.
Ну, если Вам нравятся дорогие % и / , которые почему-то работают лучше, чем классический вариант, то у меня вопросов более нет.
А чем они так дороги? Можете предложить способ лучше, со схожим функиционалом и простотой?
В моем варианте, как минимум не будет происходит накопление ошибки.
Чтобы не происходило накопление ошибки
вместо previousMillis = millis();
пишите previousMillis += interval;
Размер заливаемого в камень кода гляньте с делениями и без ...
Чтобы не происходило накопление ошибки
вместо previousMillis = millis();
пишите previousMillis += interval;
Это не мой пример, и не нравится он мне по многим причинам, я из более-менее все назвал выше.
Так как, лично я, особых отличий в итоге не вижу, то и предлагать нечего.
Можете записать меня в консерваторы.
Размер заливаемого в камень кода гляньте с делениями и без ...
Ну, дык
Вы пишите в тему "Этюды для начинающих: blink и без delay, и без millis"
В вашем случае millis() используется.
Так millis не кратно 1000 и будет один периодический конкретный рассинхрон.
Видимо для деления на 1000 есть короткий алгоритм, по этому код не сильно вырос
Вы пишите в тему "Этюды для начинающих: blink и без delay, и без millis"
В вашем случае millis() используется.
Предлагаете отдельную тему создать?
Я тут лишь хочу показать еще один, как мне кажется, простой способ мигания светодиодом без лишних заморочек, но с чуть более расширенным функционалом.
RxMaxx что будет в редкие моменты обнуления millis ?
Видимо для деления на 1000 есть короткий алгоритм, по этому код не сильно вырос
Перебрал несколько вариантов - все в пределах 844 - 848 байт.
Так millis не кратно 1000 и будет один периодический конкретный рассинхрон.
А чему оно кратно? Я в одном проекте этот способ использую, рассинхрона не наблюдаю. У меня там несколько диодов мигают. А вот со старым способом - наоборот все довольно быстро уплывало, нужно было специально с этим бороться.
Предлагаете отдельную тему создать?
Нет. Просто вдруг вы не заметили.
RxMaxx что будет в редкие моменты обнуления millis ?
Ничего страшного. Один кривой мырг раз в 40 дней - это ерунда, сами millis - это далеко не RTC.
Реактор в Чернобыле не по вашему алгоритму работал ?
Реактор в Чернобыле не по вашему алгоритму работал ?
Хотите краткий пересказ из-за чего авария случилась? Или думаете АЭС на МК кто-то делает?
По Вашему - управление АЭС и мигание светодиодами - это сопоставимые по критичности задачи?
Задача должна правильно решаться на всем временном отрезке ! Если вы этого не понимаете, то не надо других вводить в блуд вашего заблуждения !!!
Задача должна правильно решаться на всем временном отрезке ! Если вы этого не понимаете, то не надо других вводить в блуд вашего заблуждения !!!
А Вы собственно, какую задачу решаете? Управление АЭС? Я вот решал задачу - красиво и просто мигать светодиодами, которые являются индикаторами некоторых процессов, от которых не зависят чья либо жизни и здоровье, а так же состояние экономики страны. Предложенный мною код, с этой задачей справляется на 99,9999%, при этом экономит, как ни странно, память и нервы. Опять таки, по сравнению с "классикой" я не вижу недостатков. А использование прерываний, а так же отслеживания обнуления millis - для данной задачи избыточная сложность, у нас тут, видите ли, МК с весьма ограниченными ресурсами, чтоб все их тратить на совсем уж идеальное мигание.
Если можете предложить способ ЛУЧШЕ, для данной задачи - милости просим.
Я можно сказать жизнь доверил МК - использую его в качестве круиз-контроля.
Размер кода на ассемблере всего в два раза больше кода, которые генерируют ваши три строки ...
Я можно сказать жизнь доверил МК - использую его в качестве круиз-контроля.
Ну, тогда я Вам официально запрещаю использовать предложенный мною код, не хочу брать грех на душу... Хотя нет, я же не претендую на авторство, и ни как не могу регламентировать использование кода.
Размер кода на ассемблере всего в два раза больше кода, которые генерируют ваши три строки ...
А еще можно отдельный МК на каждый светодиод повесить, и желательно все продублировать... и все застраховать, на всякий случай.
И строчка там одна, и она работает, вопреки всякой логике. Теперь, что, ради мигания диодом ассемблерные вставки делать?
Вы что сказать то в итоге хотите то? Я вот не могу понять.
Ваш алгоритм не верен - садись два !
Ваш алгоритм не верен - садись два !
Обоснуйте.
...Один кривой мырг ...
...Один кривой мырг ...
Раз в 40 дней, и то не факт, что он там будет, от которого ничего не зависит. И?
P.S. У меня форум уже второй раз глючит, дублирует сообщения. Давайте его тоже за это снесем.
RxMaxx видимо сегодня как раз тот 40 день у движка форума
RxMaxx видимо сегодня как раз тот 40 день у движка форума
Да не, это все код виноват зловредный, стопудово. Одно его существование сломало форум, я уж молчу про Чернобыль и COVID19. Он уже пробил брешь в пространстве-времени и создал черную дыру.
Чё накинулись? Больше мигалок, хороших и разных!
RxMaxx, миллис ещё одну подлость приготовил - он пропускает некоторые числовые значения. Как бы Вашей идее это не нагадило в плане стабильности :-(
Чё накинулись? Больше мигалок, хороших и разных!
У меня есть четырёхбайтовая.))) Но на асм.(
Green она будет так быстро мигать, что не каждым осциллографом увидишь ...
Видно невооруженным глазом.) И даже двухбайтная!)
Через всю память - это не два байта !
Да, но хекс то имеет именно такой размер, какие вопросы.)
Если можете предложить способ ЛУЧШЕ, для данной задачи - милости просим.
Это не ЛУЧШЕ, но некоторые замечания. (Времена примерные, т.к. смотрел на симуляторе.)
i=(unsignedLongL/1000)%2; занимает около 600 тактов
i=(unsignedLongL/1024)%2; занимает около 77 тактов.
Иногда это может иметь значение. И если надо просто моргать, а не отмерять интервалы, то может имеет смысл делить на 1024. (можно пойти дальше и читать внутренний счетчик и вообще не делить, но это наверное перебор ).
А если вместо
i=(unsignedLongL/1024)%2
написать
i = (L>>10) & 0x01;
скока тактов занимает?
скока тактов занимает?
Два. Спасибо.
Дида, степени двойки gcc сам оптимизирует.
Дида, степени двойки gcc сам оптимизирует.
ну от как выяснилось, я лучше gcc оптимизирую. :)
скока тактов занимает?
Два. Спасибо.
Два не может быть.
Хотя, отбросить вообще младший бит, старший сдвинуть на 2 вправо и сделать and или проверить бит. Мошт, и два. Тяжело сабражать в домашнем аресте.
Не, два никак :-)
Не, два никак :-)
Да, два - никак, даже с пахмелью. Пойду займусь тем, что у меня лучше всего получается - навоз растаскивать по гряткам.
RxMaxx, миллис ещё одну подлость приготовил - он пропускает некоторые числовые значения.
Есть только Цезий-133 непогрешимый, все остальные "счётчики" так или иначе пропускают, даже Земля наша, не зря же високосные дни и даже секунды придумали.
Да, если делить не на 1000 а на степень двойки, то можно сэкономить еще целых 92 байта! Что делает код еще меньше и быстрее по сравнению с "классикой", но чаще все таки приходится использовать обычные секунды (и кратные им), и страдать за это, даже millis страдают. Наша система измерения времени вообще жутко неудобная с точки зрения программирования, что ж поделать то.
Убери из классики лишний if... Будет короче.
А если вместо
i=(unsignedLongL/1024)%2
написать
i = (L>>10) & 0x01;
скока тактов занимает?
В своем ответе я крупно лопухнулся ответив 2.
Дело в том, что я не заменил строчку i=(uL/1024)%2, а добавил k=(uL>>10) & 0x01 и компилятор просто взял готовый ответ.
И в том и в другом случае занимает около 80 тактов.