Помогите порулить тиристором.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Имеем, дуину нану :-).
Синхронизируем ее оптопарой с сетью 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);}
}

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Что я делаю не так ? Как исправить ?

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Если сравнивать не с высчитанным значением, а просто в строку сравнения времени вбить фиксированное значение, то точно так же плавает угол.
Вот так
CurrentMillis-millis()>=4
Ну не может же время цикла так сильно расходится.

b707
Offline
Зарегистрирован: 26.05.2017

странно, что он у вас вообще включается, посмотрите, в какой момент вы Currentmillis запоминаете

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Ну как в какой, в момент перехода через ноль.
А точнее, последнее значение будет запоминается в том цикле в котором прошлого сигнала синхронизации уже нет, а следующий только появится в следующем цикле.

b707
Offline
Зарегистрирован: 26.05.2017

Kakmyc пишет:
Ну как в какой, в момент перехода через ноль. А точнее, последнее значение будет запоминается в том цикле в котором прошлого сигнала синхронизации уже нет, а следующий только появится в следующем цикле.

ну то есть к заданному интервалу у вас прибавляется неопределенное время - длительность цикла loop(). Хорошо если ЛУП короткий... но если программа еще что-то делает, кроме ловли нуля - то дело будет совсем плохо.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Вся программа представлена в скетче.
И что там так может скакать ?
В цикле проходит два сравнения и по итогам либо арифметическое действие, либо изменение переменной. Это все должно в одну мс укладываться, а тут разброс такой.

b707
Offline
Зарегистрирован: 26.05.2017

Kakmyc пишет:
Вся программа представлена в скетче. И что там так может скакать ?

 у меня большие сомнения в том, что оптопара вам дает "цифровой нуль" - ну то есть такой. что выдает только нули и единицы. Скорее всего сигнал там меняется по синусоиде, а когда вы его читаете как digitalRead - вы получаете "нуль" не только в момент настоящего нуля, но и в любой другой, отстоящий от настоящего нуля на случайную задержку.

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Как картинку вставить ?

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Ноль то у меня не скачет. Все замеры делаю на осциллографе. Меряю два канала. Канал синхронизации и канал сдвига. И сдвиг плавает относительно синхронизации.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

В момент перехода синуса через ноль  светодиод оптрона не горит.
И ещё не будет гореть то время пока ток не превысит какое-то значение.
Плюс всё это зависит от температуры.

Я думаю что ноль синуса будет в середине получившегося импульса когда светодиод не горит,
то есть на выходе оптрона  "разомкнутый ( закрытый)"  транзистор.
Это при условии что сквозные каналы зажигание-открытие и выключение-закрытие
имеют одинаковые уровни срабатывания на включение и выключение.
Что скорее всего так и есть.

b707
Offline
Зарегистрирован: 26.05.2017

Kakmyc, ваш метод сохранения CurrentMillis не просто может, а ДОЛЖЕН давать случайный рассинхрон на плюс-минус 1мс даже при самом коротком ЛУП.  Не забывайте, значения миллис - целые, а значит округляются в программе отбразыванием дробной части.

А с учетом нечеткой детекции нуля - то и больше.

Вообще, чтобы иметь программную точность лучше плюс-минус 1мс - нужно использовать микросекундный таймер.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

И как это реализовать ?

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Всем спасибо, особенно 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);}
}

Kakmyc
Offline
Зарегистрирован: 15.01.2018

[quote=b707]

А с учетом нечеткой детекции нуля - то и больше.

/quote]
Осциллограф мне рассказал, что детекция нуля ЧЕТЧЕ, чем пацанчике на районе. :-)
Записал 10 секунд сигналов. Проверил выборочно, местах в двадцати. Везде четко 10мс за период.