Помогите порулить тиристором.
- Войдите на сайт для отправки комментариев
Втр, 23/01/2018 - 12:48
Имеем, дуину нану :-).
Синхронизируем ее оптопарой с сетью 220в.
Сдвигаем через миллис и резистор на определенный угол. И все вроде работает, только сдвиг очень произвольный , разница до 2мс доходит.
Скетч
#define sync 3
unsigned long TimeShift=0;
unsigned long CurrentMillis=0;
void setup (){
pinMode(8,OUTPUT);
pinMode(sync,INPUT_PULLUP);
}
void loop(){
TimeShift=analogRead(0);
if(digitalRead(sync)==0)
{if(millis()-CurrentMillis>=TimeShift/125){digitalWrite(8,1); }
} else{CurrentMillis=millis();
digitalWrite(8,0);}
}
Что я делаю не так ? Как исправить ?
Если сравнивать не с высчитанным значением, а просто в строку сравнения времени вбить фиксированное значение, то точно так же плавает угол.
Вот так
CurrentMillis-millis()>=4
Ну не может же время цикла так сильно расходится.
странно, что он у вас вообще включается, посмотрите, в какой момент вы Currentmillis запоминаете
Ну как в какой, в момент перехода через ноль.
А точнее, последнее значение будет запоминается в том цикле в котором прошлого сигнала синхронизации уже нет, а следующий только появится в следующем цикле.
ну то есть к заданному интервалу у вас прибавляется неопределенное время - длительность цикла loop(). Хорошо если ЛУП короткий... но если программа еще что-то делает, кроме ловли нуля - то дело будет совсем плохо.
Вся программа представлена в скетче.
И что там так может скакать ?
В цикле проходит два сравнения и по итогам либо арифметическое действие, либо изменение переменной. Это все должно в одну мс укладываться, а тут разброс такой.
у меня большие сомнения в том, что оптопара вам дает "цифровой нуль" - ну то есть такой. что выдает только нули и единицы. Скорее всего сигнал там меняется по синусоиде, а когда вы его читаете как digitalRead - вы получаете "нуль" не только в момент настоящего нуля, но и в любой другой, отстоящий от настоящего нуля на случайную задержку.
Как картинку вставить ?
Ноль то у меня не скачет. Все замеры делаю на осциллографе. Меряю два канала. Канал синхронизации и канал сдвига. И сдвиг плавает относительно синхронизации.
В момент перехода синуса через ноль светодиод оптрона не горит.
И ещё не будет гореть то время пока ток не превысит какое-то значение.
Плюс всё это зависит от температуры.
Я думаю что ноль синуса будет в середине получившегося импульса когда светодиод не горит,
то есть на выходе оптрона "разомкнутый ( закрытый)" транзистор.
Это при условии что сквозные каналы зажигание-открытие и выключение-закрытие
имеют одинаковые уровни срабатывания на включение и выключение.
Что скорее всего так и есть.
Kakmyc, ваш метод сохранения CurrentMillis не просто может, а ДОЛЖЕН давать случайный рассинхрон на плюс-минус 1мс даже при самом коротком ЛУП. Не забывайте, значения миллис - целые, а значит округляются в программе отбразыванием дробной части.
А с учетом нечеткой детекции нуля - то и больше.
Вообще, чтобы иметь программную точность лучше плюс-минус 1мс - нужно использовать микросекундный таймер.
И как это реализовать ?
Всем спасибо, особенно b707. С микросом все заработало как надо.
#define sync 3
unsigned long CurrentMicros=0;
unsigned long TimeShift=0;
void setup (){
pinMode(10,OUTPUT);
pinMode(sync,INPUT_PULLUP);
}
void loop(){
TimeShift=analogRead(0)*8;
if(digitalRead(sync)==0)
{if(micros()-CurrentMicros>=TimeShift){digitalWrite(10,1); }
} else {CurrentMicros=micros();digitalWrite(10,0);}
}
[quote=b707]
А с учетом нечеткой детекции нуля - то и больше.
/quote]
Осциллограф мне рассказал, что детекция нуля ЧЕТЧЕ, чем пацанчике на районе. :-)
Записал 10 секунд сигналов. Проверил выборочно, местах в двадцати. Везде четко 10мс за период.