Сетевой ФИ димер - временнОе реле.
- Войдите на сайт для отправки комментариев
Доброго времени суток.)
Мужики, подскажите, что не так. Третий вечер мозг ломаю и уже не знаю что не знаю.
нужно сделать симисторный диммер, который каждые 12 часов будет вкл/выкл нагрузку в сети 220В на треть мощности.
по железу
есть датчик ноля на 814(работает. при пересечении ноля - выдает импульс. сампаялопал)
"драйвер" симистора на МОС-ьке(работает, как и симистор. сампаялопал)
PRO Mini 5V 16MHz x2(разные кварцы, большой и маленький, ВовГат и еще-что)
ЛАТР
под рукой осциллограф 1канал 0-16МГц
и еще куча барахлишка и инструмента, которое собралось за бОльшую часть жизни, в последствии увлечения электроникой.
по программе.
на сколько понял, логика простая. но есть несколько(много) способов реализации. решил пробовать делать так:
ловим импульс на INT0 от датчика ноля и в прерывании запускаем таймер, прерывания которого будут повыше в приоритете в таблице векторов - т.е. второй(третий) таймер.
в прерывании таймера2 считаем задержку до подачи импульса на управляющий электрод симистора и длительность импульса. после чего останавливаем таймер. чем больше задержка до подачи импульса, тем, соответственно, меньше мощность в нагрузке. длительность импульса от 10мкс до 150мкс в зависимости от симистора.
ну и сам опытный образец проги (простите за не причесанность))
volatile unsigned int timer2count; volatile unsigned int dimmingLVL = 1; //1 == 0.00001c 1000==10ms задержка до импульса на УЄ volatile unsigned int pulseToTriac = 2; //1 == 0.00001c длительность импульса на УЭ симистора void setup() { //enable global interrupt sei(); pinMode(2, INPUT); //ZD input pinMode(13, OUTPUT); //Triac attachInterrupt(0, zerroDetect, RISING); //zeroDetect ловим импульс от датчика ноля и перемещаемся по прерыванию в zerroDetect() //********TIMER2 Configuration********** //activate CTC mode bitSet(TCCR2A, WGM01); //TCCR2A |= (1 << WGM01); //set value to compare register OCR2A = 0b10100000; //160 } ///////////////////////////////////////////////////////////// void loop() { } ////////////////////////////////////////////////////////////////// void zerroDetect() { //reset register value TCNT2 = 0b00000000; //чистим считалку на всякий случай //enable compare match interrupt on TIMER2 bitSet(TIMSK2, OCIE2A); //разрешаем прерывания по совпадению таймера2 //prescaller configuration. start timer. TCCR2B |= (1 << CS20);//no presc //запускаем таймер2 без прескаллера и ждем прерывание уже от него } ///////////////////////////////////////////////////////////////// //TIMER2 CTC interrupt handller ISR (TIMER2_COMPA_vect) { timer2count++; //считаем количество срабатываний if (timer2count == dimmingLVL) { //подаем импульс на симистор
//start pulse digitalWrite (13, HIGH); } if (timer2count == dimmingLVL + pulseToTriac) { //считать наверное лучше отдельно в переменную и подставлять сюда ее длясравнения //end of pulse digitalWrite (13, LOW); //disable TC2 bitClear(TCCR2B, CS20); //set no clock sorce mode //disable compare match interrupt on TIMER2 bitClear(TIMSK2, OCIE2A); timer2count = 0; } }
частота срабатываний(тиков таймера) 16МГц / 160(OCR2A) = 100 000Гц 1/100 000 = 0,000010 т.е.10микросекунд
на один полупериод синусоиды будет приходится 0,010 / 0,000010 = 1000 тиков это и должно быть разрешением регулировки Pload/1000tik мне хватит
только вот программа странно работает. если верить осцилографу то цифра один в переменной pulseToTriac в реальности равна 2 миллисекунды, а цифра 2 - 4 миллисекунды
т.е. осцил на ноге 13 показывает меандр с периодом 10мс и длину управляющего импульса 4мс если в pulseToTriac записать 2. а должно быть 20 микросекунд потому что таймер должен тикать с частотой 16МГц / 160(OCR2A) = 100 000 Гц даже без предварительного деления частоты.
по ходу что-то не так с кварцем, или ардуино как-то перенастроило АВР-ку. в общем, я уже не знаю что еще попробовать.
аппаратное прерывание работает. моргал светодиодом каждые 100 полупериодов. а таймер чет не осилю.
подскажите, что я упустил, что я не знаю?)
P.S. разработчик редактора этого форума явно не знает что такое когнитивное искажение - "проклятие знания" и подобные.
остальные надеюсь, поймут.
блть в строке 42 две строки. происки редактора форума. почему первый пост нельзя отредактировать?
Таймер ДО Вас настраивает среда Ардуино. Например, в регистр TCCR2B она пихает бит CS22. Вы же потом по ИЛИ добавляете туда ещё CS20 и получаете делитель не 1, как ожидаете, а 128. Вот и Ваша ошибка как раз в сто раз - всё точно, как доктор прописал.
Кстати, в TCCR2A она пихает WGM20, который Вам, как я понимаю, тоже там нахрен не нужен.
Настраивайте таймер полностью, прописывая все биты - не надейтесь, что там нули. Тогда всё получится.
Кстати, в строке №17 замените на WGM21. На скорость не влияет, но неаккуратненько :-)
блть в строке 42...
Ознакомьтесь вот с этой темой :-)
Ознакомился
простите если было не приятно, я не хотел.)
по поводу строки 17... эх, стыдоба. прост я начинал с нулевого таймера. фантомные боли..))
Да, нет, Вы чего - это тут шутки такие (как и та тема сама по себе) :-)))
Получилось с таймером?
https://playground.arduino.cc/Main/ACPhaseControl/
почему первый пост нельзя отредактировать?
Премудрые студиозы, получив решение курсового, редактировали его в ноль. И оставались висящие между небом и землей темы.((((
на самом деле что-то пошло не так... я психанул, нашел несколько кандёров для конденсаторного БП на время, пока буду разбираться с симистором.
сейчас же достаточно просто вкл/выкл симистор, а кандеры гасят лишнее. так-что можно перейти к часам и расписанию по которому этот симистор вкл/выкл.
это некая костяшка программки которая удовлетворяет минимальные требования. время считаю от внешнего кварца. старался делитель выставить максимально большим что бы больше времени основной программе оставить. фазо-импульсную регулировку и модуль RTC оставлю для версии 1.1)) хах))
в общем, буду счастлив, если кто ни будь глянет.. может я накосячил фатально-фундаментально и часы будут кривыми как && мои руки?)
16МГц/1024(предделитель)=15625/125(OCR2A=124)=125Гц = 1с; или я что-то напутал?
главное что бы часы шли ровно. если основная программа где-то чуть еле подвиснет то это не страшно.
я вот не рискну браться. может не знаю где лежит.. как вообще выглядит корректная инициализация, настройка таймера на СТС прям по пунктам по порядку? или тут нет однозначности? каждый как-то делает по своему что-ли. срачи разводят..
нужно сделать симисторный диммер, который каждые 12 часов будет вкл/выкл нагрузку в сети 220В на треть мощности.
А зачем с таймером мутить если уже есть millis(). Используйте его для учета секунд/минут/часов.
SLKH, что за вопрос?)
asam, ну я тут несколькими постами выше словил граблями в виде высокого уровня абстракции. чуть ниже - чуть интересней.) ну и более гибко, явно, если писать понятно. может мне лучше на форум где сидят в атмел студио?) или как||куда?)
тут порог вхождения ниже, но мне кажется что все стремительно скатывается к AVR
часы то хоть ровные получились?))
а тут есть некий toggle pin? как адекватней вывести частоту срабатывания прерываний от таймеров на ножку что бы осциллом частоту посмотреть?
asam, ну я тут несколькими постами выше словил граблями в виде высокого уровня абстракции. чуть ниже - чуть интересней.)
Ну это не от уровня абстракции проблема, а от незнания матчасти.
Флаг вам в руки.
на сколько я понимаю, события, вызванные прерыванием, при равных условиях, должны "возникать" с частотой прерываний. мне кажется через If-ы будет криво. или я не прав? стесняюсь спросить, вы мне намекаете каждое срабатывание подвигать что-то типа unsigned long = 010101010101.....010101 на ноге?
не согласен по поводу "не знания мат части". это не очевидно что ардуина настраивает железо под себя даже если "явно" не нужно. думаю если бы подход был бы изначально на уровне регистров, где нужно явно указывать что-куда, то подобных граблей бы не возникло.
ну это не плохо. это хорошо если уметь этим пользоваться.
а что если
byte val = 0b0000 0000;
ISR (TIMER2_COMPA_vect){
val = ~val;//поразрядная инверсия
PORTB = val;
}
грубовато, но по идее должно быть ровненько.))
а тут есть некий toggle pin?
В даташите написано:
Добрый вечер AlexPython
На 4й странице в схожей теме
"Устройство ФИУ на симисторе (диммер) для Ардуино"
есть схема и скетч по вашему вопросу.