Диммер 220 вольт от РоботДин
- Войдите на сайт для отправки комментариев
Чт, 15/04/2021 - 16:15
Добрый день.
Весь день сижу в интернете перерыл кучу ссылок. Нашёл одну работающую великолепно.
Подскажите пожалуйста как отредактировать функцию обработки перехода через Ноль, что бы исключить Delay?
void zero_crosss_int() //function to be fired at the zero crossing to dim the light { int dimtime = (75*dimming); // For 60Hz =>65 delayMicroseconds(dimtime); // Wait till firing the TRIAC digitalWrite(AC_LOAD, HIGH); // Fire the TRIAC delayMicroseconds(10); // triac On propogation delay (for 60Hz use 8.33) digitalWrite(AC_LOAD, LOW); // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC }
Потому что после ее выполнения работа остальной программы ЖУТКО тормозит.
Т.е. при работе с поворотным энкодером после каждого поворота я жду до 5 секунд что бы увидеть реакцию.
А так же при отображении на LCD тоже значения отображаются с задержкой в секунд 3-5.
Очевидно делать через таймер, а не через delay()
Её нужно выбросить, а вместо неё написать ТРИ другие. И, заодно, поменять логику в месте её вызова.
В программировании на C я близок к "0", но как по мне, функция перехода через ноль, довольно много ресурса МК займёт.
Не проще ли использовать какую-нибудь оптопару, в которой эта функция уже встроена?
Евгений, подскажите какие функции? Мне надо что бы в определенный момент в программе диммер полностью медленно зажёг лампу, а в другой момент полностью медленно её погасил. От 0 до 100% и наоборот. Не основвываясь на каких либо датчиках, кнопках, энкодерах и прочее. Я уже всё перечитал и видимо что то недопонимаю.
Ну, как, какие - такие же, только не одну, а три. Вот смотрите на мои комментарии к Вашем коду
Вам потребуется функция, которая может настроить таймер так, чтобы через указанный интервал была вызвана указанная Вами функция. Таких полно во всевозможных библиотеках таймеров, но я эти библиотеки не пользую, потому не очень знаю. Допустим эта функция называется setupCallOnce и имеет два параметра - первый - количество микросекунд и второй - имя функции, которую надо вызывать (имя в С/С++ является указателем на функцию). Т.е. если мы запишем так:
то эта функция настроит таймер и немедленно вернёт управление, Ваша программа продолжит исполнение. А через 1500 микросекунд Ваша программа прервётся, выполнится функция kaka и после этого Ваша программа продолжит выполнение с того места, где прервалась.
Если такая функция у Вас есть, то вместо одной Вашей функции zero_crosss_int, Вы пишете три
Вызываете zero_crosss_int. Она настроит таймер и вернёт управление Вашей программе, которая продолжит работу. Через 75*dimming микросекунд Ваша программа прервётся, исполнится функция delo1. Та выполнит digitalWrite и настроит таймер. Ваша программа после этого продолжится, а через 10 микросекунд, снова прервётся на выполнение функции delo2, после чего снова продолжится.
Вот, примерно так это и делается.
Функцию с функционалом как у setupCallOnce поищите в библиотеках таймеров - таких функций навалом. Это первое, чем прочищают горло программисты, впервые пришедшие в мир микроконтроллеров :-)
Добрый день
Попробовал на библиотеке Алекса Гайвера.
Работает но не так как надо. Нет плавности включения. Просто включает и всё..
Я прочитал мануал по работе с этой библиотекой. Там используется обработчик ISR.
Может с этой библиотекой такой алгоритм не работает?
Изменение переменной dimming в коде происходит по установления флага
1. Настраиваем таймер на нужную точность.
2. При переходе через ноль запускаем таймер
3. При достижении нужного значения (угол открытия тиристора ) подаём на нужный пин нужный сигнал.
4. Обнуляем счётчик таймера
5. Меняем значение по совпадению на равное 5-10мкс(тиристор нужно закрыть)
6. По истечению снимаем сигнал с пина.
7. Отключаем таймер до момента следующего перехода через 0
Поправьте по коду пожалуйста:
Вы делаете СОВСЕМ НЕ ТО. Внимательно посмотрите на мой код и сравните со своим! Нахрена Вы вызываете SwitchUpDimmer и SwitchDownDimmer в строках №№ 14 и 9? Их должен таймер вызывать, а не Вы!
Без особых на то причин я бы не стал заморачиваться с заменой второй задержки (строка 6 исходного текста). 10 микросекунд раз в полупериод (0.1%) вряд будут заметны.
Без особых на то причин я бы не стал заморачиваться с заменой второй задержки (строка 6 исходного текста). 10 микросекунд раз в полупериод (0.1%) вряд будут заметны.
Это да.
А если тактовая частота типа 1МГц, так и вообще смысла нет - там только на вход в прерывание 4 такта нужно, а задержка всего на 10.
Без особых на то причин я бы не стал заморачиваться с заменой второй задержки (строка 6 исходного текста). 10 микросекунд раз в полупериод (0.1%) вряд будут заметны.
+100500 тем более, что именно эта задержка необходима в таком виде - она пережидает переходные процессы типа звон.
Без особых на то причин я бы не стал заморачиваться с заменой второй задержки (строка 6 исходного текста). 10 микросекунд раз в полупериод (0.1%) вряд будут заметны.
+100500 тем более, что именно эта задержка необходима в таком виде - она пережидает переходные процессы типа звон.
Вот не знаю - нахрена.
Я 350 прмеров уже скачал из инета, прочитал не одну страницу текста. Я понял что везде показаны примеры диммера, а на самом деле реализована не функция диммирования а функция реле.
НЕТУ ПЛАВНОГО ВКЛЮЧЕНИЯ!!
Как мне понять чё делать, если плавного включения НЕТ.
Скачал очередной пример. Лампа накаливания моргает как азбука морзе. Опять нет плавного включения. Хотя на видео автор ползунковым регулятором как то ее включает плавно. Ничего не понимаю Как?
Скажите пожалуйста точно, что мне здесь поменять что бы я увидел плавность включения? (в Loop закоментированы оригинальные строки. Я всего лишь из заменил на плавное изменение переменной)
} //----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ-------------------------- void timer_interrupt() { // прерывания таймера срабатывают каждые 40 мкс tic++; // счетчик if (tic > Dimmer) // если настало время включать ток digitalWrite(dimPin, 1); // врубить ток } void detect_up() { // обработка внешнего прерывания на пересекание нуля снизу tic = 0; // обнулить счетчик ResumeTimer1(); // перезапустить таймер attachInterrupt(1, detect_down, RISING); // перенастроить прерывание } void detect_down() { // обработка внешнего прерывания на пересекание нуля сверху tic = 0; // обнулить счетчик StopTimer1(); // остановить таймер digitalWrite(dimPin, 0); // вырубить ток attachInterrupt(1, detect_up, FALLING); // перенастроить прерывание } //----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ--------------------------
Я всего лишь из заменил на плавное изменение переменной)
код вставьте нормально
И слушайте, если вы в этом нихрена не понимаете - зачем вы лезете править код?
Да, я не понимаю. Но очень хочу понять и разобраться.
С такой точки зрения, если человек пришел в школу или универ, и пока ничего не понимает - то выгнать его ....... ?
Мол все равно сейчас ничего не понимаешь
пины правильно подключены? пин 3 - детектор нуля?
попробуйте свою строчку изменить вот так:
пины правильно подключены? пин 3 - детектор нуля?
попробуйте свою строчку изменить вот так:
да, 3 пин подключен к Zero на диммере (2 пин у меня поворотный энкодер).
Я потом этот код в главную программу вставлю.
Попробовал пример. Не могу обьяснить словами. Моргает с разными интервалами. Жаль не могу прикрепить видео.
вы уверены. что у вас зерокросс на модуле работает? - по коду, насколько я вижу - проблем нет, все должно отрабатывать правильно
вы уверены. что у вас зерокросс на модуле работает? - по коду, насколько я вижу - проблем нет, все должно отрабатывать правильно
В самом начале темы я приложил код. Он работает отменно. Только там - delay.
Из-за этого у меня вся остальная программа тормозит страшно после первого же отрабатывания диммера.
В самом начале темы я приложил код. Он работает отменно. Только там - delay.
да. сорри, уже посмотрел.
Этот код другой и, возможно, он вам не подходит.
Можете написать, как у вас вызывается прерывание на пересечение нуля в том коде. что "прекрасно работает"?
Вот этот код работает как надо.
вот это пробуйте
А можно уточнить: какой контроллер и его частота?
вот это пробуйте
спасибо. В понедельник попробую. У меня всё на работе.
А можно уточнить: какой контроллер и его частота?
Ардуино Нано (ATmega 328, 16Мгц)
Почему в стартовом посте нужен "диммер", а в итоге "плавное включение" ?
Это как бы не одно и то же.
Потому что "dimming" в переводе с английского означает затемнение, потускнение, гаснущий и т. п.
С какого тогда тебе нужно плавное зажигание ?
Диммер в техническом плане, это регулятор.
Плавный розжиг/затухание это одна из его опций.
Вот мне и нужна реализация этой самой опции. А включить и выключить я и с помощью реле могу. Если вам нечего сказать ничего по существу (помочь исправить код, ну или внести в него изменения) то не надо здесь сыпать теорией и этимологией слова. Пожалуйста. Я за практическим советом и реальной помощью сюда обратился.
Можете показать сам модуль?
Дело в том, что я как-то купил модуль RBDDimmer без детекции нуля, вернее, она там как бы и была, но ардуино не видела этот переход.
Я тебе уже дал совет и даже алгоритм расписал.
"Чего же тебе ещё надо , собака?" © И.Грозный (ИВМП)
ЗЫ: за готовым кодом в раздел :"ищу исполнителя"
Я рад, что вы любите Гайдая и цитируете его шедевры. И тыкать мне не надо, я с вами на брудершафт мороженое не лизал
P.S. Я "реализовал" предложенный вами алгоритм (#16). Нет плавного включения. Результат - ацикличное включение и выключение лампы накаливания.
Код за меня писать не надо. Достаточно указать на мои ошибки.
Про диммеры на форуме куча тем. Мы вот уже 4 года назад один диммер на прерываниях отладили. http://arduino.ru/forum/programmirovanie/attiny85-i-preryvanie
Вот мне и нужна реализация этой самой опции. А включить и выключить я и с помощью реле могу. Если вам нечего сказать ничего по существу (помочь исправить код, ну или внести в него изменения) то не надо здесь сыпать теорией и этимологией слова. Пожалуйста. Я за практическим советом и реальной помощью сюда обратился
Через жопу реализовал.
Алгоритм такой:
1. На старте угол зажигания (время после перехода через ноль)максимальный
2. Через миллис реализуем нужную плавность зажигания
Т.е :
if(угол не минимальный&& millis()-lastTimeFade>=100)
{ lastTimeFade=millis(); угол--;}
Вот мне и нужна реализация этой самой опции. А включить и выключить я и с помощью реле могу. Если вам нечего сказать ничего по существу (помочь исправить код, ну или внести в него изменения) то не надо здесь сыпать теорией и этимологией слова. Пожалуйста. Я за практическим советом и реальной помощью сюда обратился
Ну а чё, у нас в России всё череж жопу. Как без этого?
Я конечно не на милис попробовал сделать, но что то сделал.
Только лампа включается и не выключается плавно.
Прошу подсказать где я ошибся.
Везде.
Особенно в том месте, где должно плавно выключаться.
Неправильно вообще всё.
Rankle. вы код #25 пробовали?
и еще вопрос - вы что диммировать пытаетесь?
Вы забыли ещё ногами постучать по полу. Детский сад, её богу. Везде и всё тут.
Rankle. вы код #25 пробовали?
и еще вопрос - вы что диммировать пытаетесь?
Я писал ранее (#36) , что пытаюсь диммировать лампу накаливания. Обычную. Отечественную. С цоколем E27 на 60 Ватт.
Вы забыли ещё ногами постучать по полу. Детский сад, её богу. Везде и всё тут.
Проблема в том, что вы где-то скомунниздили код, нихера в нем не понимаете и при этом пытаетесь сделать вид, что что-то делаете.
Если вы не прописали в коде, плавное затухание, то откуда бы ему взяться ?
Не вижу смысла вам помогать абсолютно.
Я писал ранее (#36) , что пытаюсь диммировать лампу накаливания. Обычную. Отечественную. С цоколем E27 на 60 Ватт.
а что про #25 молчите? Вы этот код пробовали7
Я писал ранее (#36) , что пытаюсь диммировать лампу накаливания. Обычную. Отечественную. С цоколем E27 на 60 Ватт.
а что про #25 молчите? Вы этот код пробовали7
b707 Я вчера с утра сразу же попробовал его "внедрив" в свою программу. Моргал ещё как.
И, почему то, (все остальные скетчи я пробовал "напрямую") а ваш я не попробовал "напрямую", а подставлял в необходимые места своей программы.
Сейчас запустил "как есть". Работает. правда в конце затухания небольшой "минус", но теперь я с ним сам разберусь. Знаете я до этого думал что нельзя пользоваться delay в прерываниях attachinterrupt. Я не предполагал что в прерываниях таймера это можно. Теперь буду добавлять в свой код условия что бы всё заработало на 100%.
b707 спасибо большое за помощь и терпение
...... Не вижу смысла вам помогать абсолютно.
Да и ладно. Это сразу было понятно.
Знаете я до этого думал что нельзя пользоваться delay в прерываниях attachinterrupt. Я не предполагал что в прерываниях таймера это можно.
Функцию delay() нельзя использовать в прерываниях, а вот delayMicroseconds() - можно. А какое прерывание - таймера или attachinterrupt - значения не имеет.
Функцию delay() нельзя использовать в прерываниях, а вот delayMicroseconds() - можно. А какое прерывание - таймера или attachinterrupt - значения не имеет.
Весьма ценное ( для меня, как для новичка) замечание. Ещё бы знать почему?
Весьма ценное ( для меня, как для новичка) замечание. Ещё бы знать почему?
Ну наверное потому, что прерывания не работают внутри прерываний.