Как подсчитать количество полупериодов ???

GreenLight
Offline
Зарегистрирован: 25.12.2016

Делаю точечную сварку, и появилась идея отмерять длительность импульса не по времени, а по количеству полупериодов напряжения! 

Трансформатор для питания ардуино будет обычный (не импульсный) поэтому я могу "снимать" напряжение прямо с его вторички через диоды и подавать на вход платы через обычный делитель!

За 1 секунду проходит 100 полупериодов, поэтому, если мне нужно включить устройство на 0,1 сек, нужно отсчитать десять полупериодов и выключить!

Для начала нужно объявить две переменные Current_Count=0; //текущее значение счетчика импульсов

и Set_Count=10;// устанавливаемое значение (сколько импульсов отсчитать до выключения)

дальше   if Current_Count < Set_Count {устройство включено} else {выключено}

Мне напонятно только, как с помощью arduino подсчитать количество импульсов? Подскажите пожалуйста!

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

GreenLight пишет:

Делаю точечную сварку, и появилась идея отмерять длительность импульса не по времени, а по количеству полупериодов напряжения! 

IMHO плохая идея:

- усложняет схему,

- усложняет скетч,

- снижает точность измерений.

Цитата:

Мне напонятно только, как с помощью arduino подсчитать количество импульсов? Подскажите пожалуйста!

Считать - просто. Вопрос - оно Вам надо?

gena
Offline
Зарегистрирован: 04.11.2012

  Присоединяюсь к топикстартеру. Сегодня ожидаю прибытия (на предмет изучения) трансформаторной точечной сварки и тоже нужно будет дозировать время её включения. Ознакомтесь, там применяется ардуино https://www.youtube.com/watch?v=U0oUG5AJqM4

   И ещё. Кто то может детально пояснить, как работает Zero Voltage Crossing в MOC3062.

nik182
Offline
Зарегистрирован: 04.05.2015

Что такое MO32062? Почему гугль не дает ничего похожего на Zero Voltage Crossing?

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

GreenLight пишет:

За 1 секунду проходит 100 полупериодов

внезапно! 50Гц

GreenLight пишет:

мне нужно включить устройство на 0,1 сек, нужно отсчитать десять полупериодов и выключить!

отсчитай пять периодов

GreenLight
Offline
Зарегистрирован: 25.12.2016

Я говорю именно про полупериоды, потому что:

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

ну, дык ++n

GreenLight
Offline
Зарегистрирован: 25.12.2016

Наверно нужно ввести ещё одну переменную типа boolean для запоминания состояния? И назвать её например previous_state

boolean previous_state = digitalRead(inPin); // считываем состояние входа и записываем его в переменную previous_state
if digitalRead(inPin &&  previous_state == LOW) // если на входе HIGHT, а раньше было LOW, то...
{
counter++; // увеличиваем счетчик на 1

previous_state= HIGHT; // записываем в переменную 

}

Правильно, я рассуждаю? Если нет, подскажите как? Другого способа я не вижу!

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Чем прохождение через ноль ловите?
 

nik182
Offline
Зарегистрирован: 04.05.2015

https://www.circuitar.com/nanoshields/modules/zero-cross/
Этой штукой. Схема прилагается. Считать количество фронтов.

GreenLight
Offline
Зарегистрирован: 25.12.2016

А если я буду включать/выключать симистор не через обычную оптопару, а оптопару с детектором нуля

нужно ли тогда "ловить" ноль?

Я думал ардуино и так сделает из пульсирующего напряжения прямоугольное - цифровые пины ведь реагируют на определенный уровень напряжения? Правильно?

Посмотрел код:

#define SECONDS 2.0

int count = 0;

void setup()
{
  Serial.begin(9600);
  Serial.println("Zero Cross Test");

  attachInterrupt(0, cross, RISING);
}

void loop()
{
  delay(SECONDS * 1000);

  noInterrupts();
  float hz = count / SECONDS / 2;
  count = 0;
  interrupts();

  Serial.print(hz);
  Serial.println("Hz");
}

void cross() {
  count++;
}

Там другим способом подсчет импульсов сделан! Функция void cross увеличивает счетчик в прерывании!

Только я не понял, зачем там указано #define SECONDS 2.0??? Почему 2.0, а не еденица?

gena
Offline
Зарегистрирован: 04.11.2012

    Торопился утром, ошибся. Правильно MOC3062. Аппарат привезли, изучаю. Просмотрите материал по моей ссылке. Там очень не плохо. Работает с точностью до полупериода, без подсчёта импульсов.

nik182
Offline
Зарегистрирован: 04.05.2015

Может быть потому что подсчёт ведётся 2 секунды?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Я делал на пик контроллере режим торможения двигателя, отлавливал одно прохождение через ноль, датчик нуля не я разрабатывал, схему не скажу, так что с точностью до одного периода можно )))

gena
Offline
Зарегистрирован: 04.11.2012

   Ребята, зачем Вам нужно ловить прохождение через ноль? Ведь можно чуть иначе, и без этого детектора.

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

.

GreenLight
Offline
Зарегистрирован: 25.12.2016

Написал предварительную версию скетча! Оцените пожалуйста!

# define Power_Button 14 // кнопка для включения
# define Output_Pin   13 // выход на оптопару
int Count_Pulses = 0; // счетчик полупериодов напряжения равен 0
int Pulses_Setup = 10; // сколько импульсов задано
int Button_Flag=0; // флаг нажатия кнопки
void setup()
{
  attachInterrupt(0, cross, RISING); // прерывание по спаду
  pinMode(Power_Button,INPUT_PULLUP); // подключить подтягивающий резистор на входе пина кнопки
}

void loop()
{
  noInterrupts(); // запретить прерывания 
      if (digitalRead (!Power_Button)&& Button_Flag ==0) // если кнопка нажата...
         {
          interrupts();            // разрешить прерывания...
            digitalWrite (Output_Pin, HIGH); // подать на выход +
             if (Count_Pulses >= Pulses_Setup) // если количество импульсов совпало с установленным или превысило его
                  { 
                   (Output_Pin, LOW); // выключить
                   noInterrupts(); // запретить прерывания
                   Count_Pulses = 0; // обнулить счетчик
                   Button_Flag = 1; // изменяем состояние флага нажатия кнопки 
                  }
         }
      if(digitalRead(Power_Button)&& Button_Flag ==1)
         {
         Button_Flag = 1; // изменяем состояние флага нажатия кнопки
         }
 }
void cross() {
  Count_Pulses++; // увеличиваем счетчик в прерывании
}

Подскажите пожалуйста, можно ли как-то обойтись без noInterrupts(); и Interrupts(); для того, чтобы отсчет  в прерывании ишёл только, когда нажата кнопка? Или это единственный способ?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

GreenLight, так вы его опробывали, эту вашу предварительную версию? Не вижу причин что б она работала. Ошибка на ошибке сидит и ошибкой погоняет. Да и вообще тут прерывания не нужны.

Можно по просто и надёжно без прерываний:

void setup() {
pinMode(13,OUTPUT);
pinMode(2,INPUT);
pinMode(A0,INPUT_PULLUP);
}
void loop() {
if (digitalRead(A0)==LOW){ while (digitalRead(A0)==LOW);
        while (digitalRead(2)==LOW); //если в сети ноль, то 
            digitalWrite(13,HIGH); //включаем что-то
               for(byte n=0; n<10; n++) { //10 циклов 
                  while (digitalRead(2)==LOW); //ждём единицу
                  while (digitalRead(2)==HIGH);// ждём ноля
                  }
            digitalWrite(13,LOW); // отключаем что-то.
     delay(500); //антидребезговое..
  }
}

И получаем на выходе вот такую прекрасную картинку:

GreenLight
Offline
Зарегистрирован: 25.12.2016

dimax пишет:

GreenLight, так вы его опробывали, эту вашу предварительную версию? Не вижу причин что б она работала. Ошибка на ошибке сидит и ошибкой погоняет.

Странно, я думал все ошибки в коде исправил - компилятор не ругается! 

Если Вам не сложно подскажите пожалуйста, в чем я ошибся? Я не прошу расписывать детально, но подскажите хотя бы по какому запросу погуглить, чтобы я эти ошибки нашел!

Заранее спасибо!

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

GreenLight, вы думаете, раз компилятор не ругается, стало быть и ошибок нет? Увы, он ругается когда уже полный ппц.  Не понимаю,что вы хотите гуглить.   Ошибки в 29, в 21, в 15 строке + одной строки в сетапе не хватает.

  + алгоритмический недостаток -вы включаете Output_Pin пин не в момент перехода ноля, а абы когда. Хотя ничто не мешает это сделать именно в момент перехода ноля.

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

GreenLight, буквально пару недель назад запустил аналогичное устройство, сваривает металл до 0.5мм. Агоритм сварки выбран такой   ипульс-пауза-импульс (экспериментально получено оптимальное время для приварки контактов литий иона     15ms-20ms-30ms  ), двойной импульс выбран после гугления теории точечной сварки. В качестве детектора нуля для привязки начала импульса использую внутренний компаратор АТМЕГИ, с внешним осточником ИОН (0.7в. - обычный диод), и включение трансформатора через симистор BTB16-600 (радиатор не нужен) через оптодинистор MOC3061 (со встроеной схемой привязки к нолю сети).  Периоды не считаю, а просто использую  delay нужной длительности - получается точно (проверял приборами). Установлен LSD 2Х16,  кнопки управления, выбранные параметры сохраняются в EEPROM.   

 

gena
Offline
Зарегистрирован: 04.11.2012

   А какой у Вас трансформатор (мощность, напряжение х.х.)? Мне дали точечную сварку на предмет попытки приварки металла 0,6 мм к литий ионным аккумуляторам. Если не затруднит, дайте ссылку на описание режима "импульс - пауза - импульс".

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

oleg_kazakof пишет:

контактов литий иона     15ms-20ms-30ms  ), двойной импульс выбран после гугления теории точечной

Первый импульс у вас будет в любом случае 20мс, тк. симистор может закрыться только при проходе через ноль.  А второй импульс придёться началом на полный размах фазы, открытие симистора придержит Moc3061, и откроет через четверть периода.Таким образом второй импульс будет занимать точно 2 периода., т.е  фактический ваш тайминг будет 20-20-30

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

dimax пишет:

oleg_kazakof пишет:

контактов литий иона     15ms-20ms-30ms  ), двойной импульс выбран после гугления теории точечной

Первый импульс у вас будет в любом случае 20мс, тк. симистор может закрыться только при проходе через ноль.  А второй импульс придёться началом на полный размах фазы, открытие симистора придержит Moc3061, и откроет через четверть периода.Таким образом второй импульс будет занимать 3 периода., т.е  фактический тайминг будет 20-20-30

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015
[code]
// СКЕТЧ УПРАЛЕНИЯ АППАРАТОМ КОНТАКТНОЙ СВАРКИ
//
//СКЕТЧ использует EEPROM с адреса 0 по 5,
//pin6 - контроль перехода сети через "0"
//pin7 - опорное 0.7v.
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
#include <Wire.h>// I2C
#include <EEPROM.h>
//
 int pin_svarka = 4;//     подключаем оптодинистор MOC3061
 unsigned int impuls_1 = 0;
 unsigned int payza = 0;
 unsigned int impuls_2 = 0;
 int analogklava=A0;//      подключаем кнопки
 float y8 = 0;

void setup(){
// Serial.begin(9600);//монитор IDE
  lcd.init();                      // initialize the lcd 
  lcd.backlight();                 // вкл. подсветку lcd  
  pinMode(pin_svarka, OUTPUT);     //  
       lcd.setCursor(0,0);// (0-номер знакоместа 0-номер строки)
       lcd.print(" svarka_1_k.1.1 ");
       delay(2000);
ACSR=(0<<ACD)|(0<<ACBG)|(0<<ACIE)|(1<<ACIS1)|(1<<ACIS0);
// включить компаратор, сравнение с ВНЕШНИМ ион
}

void loop() {
       delay(100);
       lcd.clear();
  impuls_1 = EEPROM_int_read(0); //адрес 0
  payza = EEPROM_int_read(2); //адрес 2
  impuls_2 = EEPROM_int_read(4); //адрес 4
       lcd.setCursor(0,0);// (0-номер знакоместа 0-номер строки)
       lcd.print("i=");
       lcd.print(impuls_1);
       lcd.setCursor(6,0);// (6-номер знакоместа 0-номер строки)
       lcd.print("p=");
       lcd.print(payza);
       lcd.setCursor(11,0);// (11-номер знакоместа 0-номер строки)
       lcd.print("i=");
       lcd.print(impuls_2);
       lcd.setCursor(0,1);// (0-номер знакоместа 1-номер строки)
       lcd.print("gotov_rabotat");
  
knopki ();
}

void knopki (){ 
   y8 = analogRead(analogklava)*(5.0/1023);
    delay(10);
  if(y8>=0.0 && y8<0.25){ kn1();}// варим

  if(y8>0.95 && y8<1.55){ kn3();}// ввод длительности первого импульса
  if(y8>1.6 && y8<2.15){ kn4();}//  ввод длительности паузы 
  if(y8>2.2 && y8<2.65){ kn5();}//  ввод длительности втрого импульса 
 
} 
void kn1(){
delay(500);
while(1){
if ( bitRead (ACSR,ACO)== 0){ //     читаем выход компаратора и варим
   if(impuls_1 == 0){impuls_1 = 2;}
   if(payza == 0){payza = 2;}
   if(impuls_2 == 0){impuls_2 = 2;}
     digitalWrite(pin_svarka, HIGH);
     delay(impuls_1 - 2);
     digitalWrite(pin_svarka, LOW); 
     delay(payza -2);
     digitalWrite(pin_svarka, HIGH);
     delay(impuls_2 - 2);
     digitalWrite(pin_svarka, LOW); 
     return;}
}
 }
       
void kn3(){
  while(1){
    lcd.clear();
       lcd.setCursor(0,1);// (0-номер знакоместа 1-номер строки)
       lcd.print("vvod");
    if(impuls_1 > 900){impuls_1 = 0;} 
       lcd.setCursor(0,0);// (0-номер знакоместа 0-номер строки)
       lcd.print("i=");
       lcd.print(impuls_1);
     delay(100);  

     y8 = analogRead(analogklava)*(5.0/1023);
     delay(10);
      if(y8>2.7 && y8<3.15){        // kn6 +10ms
      impuls_1 = impuls_1 + 10;}
      if(y8>3.2 && y8<3.6){         // kn7 -10ms
      impuls_1 = impuls_1 - 10;}
     delay(100);
      if(y8>0.35 && y8<0.85){       // kn2  сохраняем
 EEPROM_int_write(0, impuls_1); // адрес 0 (2 байта)  
         return;}
     }//end while
}

void kn4(){
  while(1){
    lcd.clear();
       lcd.setCursor(0,1);// (0-номер знакоместа 1-номер строки)
       lcd.print("vvod");
    if(payza > 900){payza = 0;}
       lcd.setCursor(6,0);// (6-номер знакоместа 0-номер строки)
       lcd.print("p=");
       lcd.print(payza);
     delay(100);  
 
     y8 = analogRead(analogklava)*(5.0/1023);
     delay(10);
       if(y8>2.7 && y8<3.15){      // kn6  +10ms
       payza = payza + 10;}
       if(y8>3.2 && y8<3.6){       // kn7  -10ms
       payza = payza - 10;}
      delay(100);
       if(y8>0.35 && y8<0.85){     // kn2   сохраняем
  EEPROM_int_write(2, payza); // адрес 2 (2 байта) 
          return;}
     }//end while 
 
 }     
void kn5(){
  while(1){
    lcd.clear();
       lcd.setCursor(0,1);// (0-номер знакоместа 1-номер строки)
       lcd.print("vvod");
    if(impuls_2 > 900){impuls_2 = 0;} 
       lcd.setCursor(11,0);// (11-номер знакоместа 0-номер строки)
       lcd.print("i=");
       lcd.print(impuls_2);
     delay(100);  

     y8 = analogRead(analogklava)*(5.0/1023);
     delay(10);
      if(y8>2.7 && y8<3.15){        // kn6   +10ms
      impuls_2 = impuls_2 + 10;}
      if(y8>3.2 && y8<3.6){         // kn7   -10ms
      impuls_2 = impuls_2 - 10;}
     delay(100);
      if(y8>0.35 && y8<0.85){       // kn2   сохраняем
 EEPROM_int_write(4, impuls_2); // адрес 4 (2 байта)  
         return;}
     }//end while
 }
       
       
// чтение 
int EEPROM_int_read(int addr) {     
  byte raw[2]; 
  for(byte i = 0; i < 2; i++) raw[i] = EEPROM.read(addr+i); 
  int &num = (int&)raw; 
  return num;  
} 
// запись 
void EEPROM_int_write(int addr, int num) { 
  byte raw[2]; 
  (int&)raw = num; 
  for(byte i = 0; i < 2; i++) EEPROM.write(addr+i, raw[i]); 
}
       


[/code]

 

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

dimax ВЫ правы, тайминги у меня 10ms - это пол периода а симистор закрывается сам при переходе сети через "0", да не 15ms , а 10-20-30 описка, чтобы не было случайного захвата следующего полупериода импульс запуска делаю на 2ms короче. Код скинул , если получится скопировать схему (так как схемы рисую на листочке, так привык) скину схему и фото аппарата.

 

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

gena пишет:

   А какой у Вас трансформатор (мощность, напряжение х.х.)? Мне дали точечную сварку на предмет попытки приварки металла 0,6 мм к литий ионным аккумуляторам. Если не затруднит, дайте ссылку на описание режима "импульс - пауза - импульс".

Трансформатор советского производства П-образный было написано 380в. на 24в. ,  размер примерно 20см*15см*7см (примерно потому, что сейчас он находится в другом месте), смотал вторичную обмотку и часть первичной (до тех пор пока первичная обмотка не стала ощютимо гретья после нескольких минут работы). Наматал вторичную в 3 - провода (толщина провода примерно с мезинец) 3 витка, напряжение Х.Х. около 4 вольт.

 Ссылки на режим импульс-пауза-импульс уменя нет, просто гугл на пол дня, там где-то есть даже форум по контактной сварке.

 

 

 

Logik
Offline
Зарегистрирован: 05.08.2014

dimax пишет:

oleg_kazakof пишет:

контактов литий иона     15ms-20ms-30ms  ), двойной импульс выбран после гугления теории точечной

Первый импульс у вас будет в любом случае 20мс, тк. симистор может закрыться только при проходе через ноль.  Таким образом второй импульс будет занимать точно 2 периода., т.е  фактический ваш тайминг будет 20-20-30

Не понял в чем сложность получить 15мс в первом импульсе. Семистор открываем через 5мс после перехода через ноль, получаем четверть периода плюс еще полупериод и даст 15мс и семистор закроется.

dimax пишет:

Таким образом второй импульс будет занимать точно 2 периода., т.е  фактический ваш тайминг будет 20-20-30

Два периода - это 40мс при 50Гц. Или я чего не понимаю?

 Интересно былобы услышать о преимуществах двух импульсов над одним.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Logik, сложностей нет, но речь шла про оптосимистор c контролем пересечения ноля, который все операции делает в момент пересечения ноля, т.е.  возможно получить лишь тайминги, кратные 10мс, т.е. полупериоду.

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

Logik пишет:

Не понял в чем сложность получить 15мс в первом импульсе. Семистор открываем через 5мс после перехода через ноль, получаем четверть периода плюс еще полупериод и даст 15мс и семистор закроется.

Cемистор открывается только в момент перехода сети через ноль для этого стоит оптодинистор MOC3061, в противном случае получаем мощный генератор помех и большую вероятность пробоя семистора.

 

 Интересно былобы услышать о преимуществах двух импульсов над одним.

гугл в помощь.

 

[/quote]

Logik
Offline
Зарегистрирован: 05.08.2014

dimax пишет:

Logik, сложностей нет, но речь шла про оптосимистор c контролем пересечения ноля, который все операции делает в момент пересечения ноля, т.е.  возможно получить лишь тайминги, кратные 10мс, т.е. полупериоду.

Понятно. Симистор слишком умный, зараза. Отличный пример того, что логика девайса должна быть в софте а не схемотехнике. Но думаю, что 10, что 15 не критично будет.

Logik
Offline
Зарегистрирован: 05.08.2014

oleg_kazakof нафига в гугл посылать, если " просто гугл на пол дня,".Вы кратко своими словами намекните чем лучше, и подтверждает ли ваш личный опыт это.

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

Logik пишет:

oleg_kazakof нафига в гугл посылать, если " просто гугл на пол дня,".Вы кратко своими словами намекните чем лучше, и подтверждает ли ваш личный опыт это.

Насколько я понял из гугления : первый импульс -разогревает металл, выжигает грязь, а горячий металл естественно электроды сильнее сжимают с друг с другом  - второй импульс собственно и сваривает металл. Одним импульсом варить не пробовал поэтому что лучше сказать не могу.

 

 

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

nik182
Offline
Зарегистрирован: 04.05.2015

Всё отлично, только совсем не понимаю зачем синхронизовать с сетью? МОС сам засинхронизирует с нулём. Подать в любой момент сигнал на открывание подождать любое время, больше 10 милисекунд отключить зажигание. МОС сам отсчитает время точно кратное 10 мс и отключится. Другого просто быть не может. Проверьте сами. На какую бы фазу напряжения не пришёлся импульс включения, тирристор включится в начале следующего полупериода и выключится в конце того, где отключилось зажигание.  Если например подать импульс 30 мс то тирристор будет открыт только 3 полупериода. Т.е. delay(30); без синхронизации  вполне выполнит поставленную задачу.  

gena
Offline
Зарегистрирован: 04.11.2012

  Вот и я на это делаю ставку, но практически ещё не проверял как работает MOC3062.

GreenLight
Offline
Зарегистрирован: 25.12.2016

Подскажите пожалуйста насчет кода

void setup() {
pinMode(13,OUTPUT);
pinMode(2,INPUT);
pinMode(A0,INPUT_PULLUP);
}
void loop() {
if (digitalRead(A0)==LOW){ while (digitalRead(A0)==LOW);
        while (digitalRead(2)==LOW); //если в сети ноль, то 
            digitalWrite(13,HIGH); //включаем что-то
               for(byte n=0; n<10; n++) { //10 циклов 
                  while (digitalRead(2)==LOW); //ждём единицу
                  while (digitalRead(2)==HIGH);// ждём ноля
                  }
            digitalWrite(13,LOW); // отключаем что-то.
     delay(500); //антидребезговое..
  }
}

Я так и не понял, почему в строке 7 два раза повторяется digitalRead(A0)==LOW ? Объясните пожалуйста "чайнику"! Заранее спасибо!

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

GreenLight, они разные (1) -если пин 1 == low, то...     ( 2) крутим цикл пока пока пин1 ==low  Попросту говоря программа стопорится  и продолжит свой ход лишь когда кнопку отпустят.

 

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

nik182 пишет:

Всё отлично, только совсем не понимаю зачем синхронизовать с сетью? МОС сам засинхронизирует с нулём. Подать в любой момент сигнал на открывание подождать любое время, больше 10 милисекунд отключить зажигание. МОС сам отсчитает время точно кратное 10 мс и отключится. Другого просто быть не может. Проверьте сами. 

Давайте рассмотрим такой вариант: допустим необходимо получить импульс сварки 10ms - соответственно логично сделать импульс управления также 10ms (и допустим что момент нажатия кнопки попал на "0" сети) - в итоге можем получить импульс сварки 10ms , а можем и 20ms так нужно добавить время на выполнения каманд переключения пина, но тогда Вы скажете сделаем импульс управления не 10 ms , 8ms - вэтом случае мы можем получить импульс сварки 10ms, а может вообще не быть сварочного импульса. Это при сварке одиночным импульсом, у меня сварка имеет три временных интервала работы - импульс - пауза - импульс, вот теперь сами пасчитайте наложение временных интервалов. Както так.

rs. симистор открывается при каком-то начальном напряжении, при "0" вообще ничего открыться не может, тоесть и это время нужно учитывать. А если мне допустим нужен тайминг 20-10-30ms ???. вот по этой причине сделал двойную привязку к "0" сети.  Конечно это не самолёт но всё-же я посчитал , что лишним это не будет.  

 

GreenLight
Offline
Зарегистрирован: 25.12.2016

Переписал код, чтобы количество импульсов можно было изменять кнопками! Добавил индикацию всего на одном светодиоде!

#define PowerPin 13         // выход для управления силовой частью
#define PowerBottonPin A0  // вход для кнопки включения 
#define ReadPulsePin 2    // вход для подсчета импульсов
#define ButtonPlus   3   // кнопка для увеличения
#define ButtonMinus  4  // кнопка для уменьшения
#define Step 10        // шаг измениния количества полупериодов
#define debounce 150  // время задержки для антидребезга
#define MaxValue 100 // максимальное значение полупериодов
#define MinValue 10  // минимальное значение полупериодов
#define LedPin 5       // светодиод индикации
#define ShortPause 300 // пауза для миганий светодиода (сколько ипульсов/10)
#define LongPause 1000 // длинная пауза между количеством миганий светодиода
int HalfCycles = 10; // начальное значение переменной, сколько полупериодов отсчитать

void setup() {
pinMode(PowerPin,OUTPUT);               // выход
pinMode(LedPin,OUTPUT);                // выход светодиода
pinMode(PowerBottonPin,INPUT_PULLUP); // вход с подтягивающим резистором
pinMode(ReadPulsePin,INPUT);         // вход
}

void LedBlink() { // функция мигания светодиодом
  digitalWrite(PowerPin,HIGH); // вкл.
  delay (ShortPause); // короткая пауза между миганиями
  digitalWrite(PowerPin,LOW);  // выкл.
  delay (ShortPause); // короткая пауза между миганиями
}
void loop() {
for(int a=0; a < (HalfCycles/10); a++) { LedBlink();}// сколько раз мигнуть светодиодом, чтобы 
  // показать установленное количество импульсов/10
  

delay (LongPause); // длительная пауза между миганиями

if (digitalRead(ButtonPlus)) { // если нажата кнопка ButtonPlus
         while(HalfCycles<MaxValue){ // пока значение не достигло максимума
            HalfCycles += Step; // увеличиваем переменную количества полупериодов 
                           // на заданный шаг
         delay(debounce); // пауза для защиты от дребезга...
         }
      }
if (digitalRead(ButtonMinus)) { // если нажата кнопка ButtonMinus
         while(HalfCycles > MaxValue){ // пока значение не достигло минимума
            HalfCycles -= Step; // уменьшаем переменную количества полупериодов 
                           // на заданный шаг
         delay(debounce); // пауза для защиты от дребезга...
         }
      }
   
if (digitalRead(PowerBottonPin)==LOW){ while (digitalRead(PowerBottonPin)==LOW);
// если кнопка нажата, то пока она нажата
  while (digitalRead(ReadPulsePin)==LOW);
    // пока в сети 0 (ноль)... 
            digitalWrite(PowerPin,HIGH); //включаем что-то
               for(int n=0; n < HalfCycles; n++) { 
                  // начинаем отсчет количества полупериодов
                  while (digitalRead(ReadPulsePin)==LOW); //ждём единицу
                  while (digitalRead(ReadPulsePin)==HIGH);// ждём ноля
                  }
            digitalWrite(PowerPin,LOW); // отключаем что-то.
     delay(debounce); //антидребезговое..
  }
}

Прокомментирована каждая срочка! Оцените пожалуйста!

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

GreenLight пишет:

Переписал код, чтобы количество импульсов можно было изменять кнопками! Добавил индикацию всего на одном светодио

Прокомментирована каждая срочка! Оцените пожалуйста!

А, принципиальную схему Вашего устройства можно, или это курсовая или диплом.

 

 

nik182
Offline
Зарегистрирован: 04.05.2015

Время переключения пина меньше микросекунды. На фоне 10 милисекунд величина бесконечно малая, не влияющая на результат. 

А вообще практика критерий истины. В даташите нет параметра, как длительность задержки импульса относительно нуля напряжения влияет на запуск тиристора. Нужно провести опыты, что бы что то утверждать. Как мне кажется, любой импульс, длительностью меньше 10 мс должен давать один полупериод, меньше 20 мс - 2 полупериода и.т.д. На это немекает фигура 3 даташита, где черным по белому написано, что 100микросекундный импульс номинального управляющего тока вызывает срабатывание тригера запуска. По логике zero-crossing после срабатывания тригера будет выдан следующий полупериод.

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

nik182 пишет:

Время переключения пина меньше микросекунды. На фоне 10 милисекунд величина бесконечно малая, не влияющая на результат. 

А вообще практика критерий истины. В даташите нет параметра, как длительность задержки импульса относительно нуля напряжения влияет на запуск тиристора. Нужно провести опыты, что бы что то утверждать. Как мне кажется, любой импульс, длительностью меньше 10 мс должен давать один полупериод, меньше 20 мс - 2 полупериода и.т.д. На это немекает фигура 3 даташита, где черным по белому написано, что 100микросекундный импульс номинального управляющего тока вызывает срабатывание тригера запуска. По логике zero-crossing после срабатывания тригера будет выдан следующий полупериод.

Почитайте ещё раз внимательно, что я написал выше, сделайте устройство, приведите осциллограммы, а потом будем диспутировать. (или у Вас нет осцилографа ???).

 

 

nik182
Offline
Зарегистрирован: 04.05.2015

У меня нет MOC. У меня есть даташит с граффиками. Всё что я написал подтверждается даташитом. Я вам предлагаю проверить. MOC у вас. Проверьте и подтвердите, что я не прав. 

Я утверждаю, что любой импульс 100 микросекунд приведет к выдаче одного полуперода.

gena
Offline
Зарегистрирован: 04.11.2012

   А кто как представляет себе работу схемы детектра нуля в фотосимисторе MOC? Я вот вижу, пока, такие варианты:

1. Если напряжение на фотосимисторе менее Zero Voltage Crossing, то свет от светодиода доходит до фотосимистора и пытается его открыть (освещая). Когда напряжение превышает величину Zero Voltage Crossing, нечто блокирует возможность открыть фотосимистор (примитивно говоря - закрывается фотошторка).

2. В момент достижения напряжения на выводах фотосимистора величины Zero Voltage Crossing, происходит стробирование (как в D- триггере) фотосимистора, и если светодиод в этот момент светил, то фотосимистор откроется.

   Казалось бы результат будет один и тот же, но, момент, когда фотосимистор откроется, будет немного разным. В варианте 1 - возможно отрытие фотосимистора практически сразу после нуля напряжения, а в варианте 2 - только в момент входного напряжения равного Zero Voltage Crossing.

И ещё вопрос. А одинаково ли происходит срабатывание фотосимистора на разных полуволнах сетевого напряжения (положительном, отрицательном)?

nik182
Offline
Зарегистрирован: 04.05.2015

В даташите устройство называется тригер. Импульс взводит тригер и при прересечении нуля он срабатывает и сбрасывается. Тиристор открыт, пока ток через него не упадет до нуля. Если в это время придёт еще импульс или предыдущий не прекратится, тригер будет взвед вновь и будет ждать следующего пересечения нуля. От длительности запускающего импульса зависит только сработал тригер или нет. Если его длительность меньше 100микросекунд, нужно увеличивать ток, согласна фиг.3  даташита. 

gena
Offline
Зарегистрирован: 04.11.2012

   Я не понял смысла предложения " Импульс взводит тригер и при прересечении нуля он срабатывает и сбрасывается." Импульс - это свет от светодиода? Что значит "он срабатывает и сбрасывается."?

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015