Изменение оборотов вентилятора с помощью Arduino

ТРИ МИРА
ТРИ МИРА аватар
Offline
Зарегистрирован: 09.01.2012

Доброго времени суток уважаемые.

Прошу отнестись с пониманием к необычной на мой взгляд идеи. Так или иначе помощь ваша краене необходима.

Задача на первый взгляд очень простая, необходимо реализовать возможность изменять обороты вентилятора QLZ06/1200 (там все его характеристики). Рассматриваю любые варианты (плавный или ступенчатый), но этим должен управлять Arduino (конечно код я сам напишу).

Мне важно выяснить схему подключения.

Убедительная просьба всем кто чем сможет помочь оставить хоть какое то совет или ссылку на полехный материал.

За ранее всем уастникам крайне благодарен за уделенное время, проявленный интерес, а тем более за великодушную помощь в столь не легком деле. (Советы по поиску в писковых системах прошу не оставлять)

ТРИ МИРА
ТРИ МИРА аватар
Offline
Зарегистрирован: 09.01.2012

 Есть такая статья http://easyelectronics.ru/upravlenie-moshhnoj-nagruzkoj-peremennogo-toka.html, можно ли по этой схеме управлять обораотами вентилятора или только включать и выключать можно.

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

На контроллере нужно будет реализовать фазовое управление оптосиммистором (с синхронизацией по началу полупериода). Вам нужно управлять задержкой включения оптосиммистора относительно начала полупериода. При этом задержка 0 будет соответствовать полной мощности, задержка  5 мс - половине, 10 мс - 0 мощности. Схему определения начала полупериода где-то встрецал - поищите. Она на оптроне собрана. Если ничего не найдете, я Вам потом нарисую. 

ТРИ МИРА
ТРИ МИРА аватар
Offline
Зарегистрирован: 09.01.2012

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

Было бы не плохо получить от вас схему и примерные характеристики оптосиммистора способного поддерживать нагрузку указанного вентилятока (напряжений 220в мощьностью 24Вт).

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

 Есть схем множество фазоимпульсного регулятора мощности для цепей переменного тока....

RC-цепочка определяет момент открытия тиристора в каждом полупериоде переменного напряжения питания нагрузки.

Синхронизируем Ардуину под частоту сети 50 Гц и управляем нагрузкой....

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012
ТРИ МИРА
ТРИ МИРА аватар
Offline
Зарегистрирован: 09.01.2012

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

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

А никто и не обещает регулировку оборотов. Здесь регулируется мощность (точнее, напряжение). Возмите в магазине диммер и проверте, как будут регулироваться обороты. Если нормально - расковыривайте диммер и внедряйте туда управление от дуины, или собирайте схему по ссылке выше. Если стоит задача регулировки именно оборотов, то еще нужно завести датчик оборотов на дуину и делать управление типа ПИД-регулятора. Но это уже программрские вопросы, не имеющие отношения к железу. 

ТРИ МИРА
ТРИ МИРА аватар
Offline
Зарегистрирован: 09.01.2012

 хорошо, тогда вот какой вопрос.

Можно ли в указанной выше схеме использовать только правую часть.

Если нет, то какие могут быть пробены.

Если да , то какие меня ждут ограничения или что то вроде этого.

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Нет. Только полностью. Левая часть - это и есть синхронизация с началом полупериода, по этому сигналу нужно запускать таймер задержки управляющего импульса. Без левой части Вы сможете только включать и выключать. 

ТРИ МИРА
ТРИ МИРА аватар
Offline
Зарегистрирован: 09.01.2012

у меня два варианта. 1. я еще плохо понимаю систему работы полупериодов. 2. Мне просто нучно что то проще для реализации задуманого выше.

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Тогда так:

1. Вы изучаете методику регулирования мощности при помощи изменения фазы открытия симистора

2. Ищите устройство управления мотором, у которого есть вход задания. 

ТРИ МИРА
ТРИ МИРА аватар
Offline
Зарегистрирован: 09.01.2012

Дело то все в том я не хотел использовать готовые решения, просто управление мощьностью, вот что мне нужно.

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Тогда ваш вариант №1

Читайте теорию, без понимания процесса не получится написать программу. 

http://electricalschool.info/main/455-tiristory-princip-dejjstvija.html

http://www.radioradar.net/hand_book/documentation/tiristor_simistor.html

Фазовое управление - из википедии

 

ТРИ МИРА
ТРИ МИРА аватар
Offline
Зарегистрирован: 09.01.2012

 все это конечно хорошо, но мне вообще то хотелось просто снизить обороты вентиялятора, как то все сложно получается

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Чтобы просто снизить, нужен ЛАТР или резистор. А Вы ставили задачу "регулировать". 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

ТРИ МИРА пишет:

.......но этим должен управлять Arduino.....

....а ЛАТР можно как раз сервой вращать :)

ТРИ МИРА
ТРИ МИРА аватар
Offline
Зарегистрирован: 09.01.2012

нет это очень громосткой ичестно гоаоря экспериментальное устройсво, ля моей задумки не подойдет.

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

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Правильный подход! Главное - разберитесь с принципом, разобраться с программированием поможем. 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

 Закупил мелочёвку, начал паять.... "в лоб" - напрограммировал так :

#define ControlSimistor 8              // пин для управления симистором
#define ControlZero 2                  // пин контроля перехода сети через НУЛЬ
#define tSimistor 20                   // длительность импульса для открытия симистора
// таблица соответствия времени "задержки управляющего импульса" и "мощности", от 0% до 100%
int tPower[ 101 ] = { 9900 , 9269 , 9006 , 8803 , 8631 , 8479 , 8340 , 8212 , 8093 , 7980 ,
                      7872 , 7769 , 7671 , 7575 , 7483 , 7393 , 7306 , 7221 , 7139 , 7057 ,                             
                      6978 , 6900 , 6823 , 6748 , 6673 , 6600 , 6528 , 6456 , 6386 , 6316 ,
                      6247 , 6178 , 6111 , 6043 , 5976 , 5910 , 5844 , 5779 , 5714 , 5649 ,
                      5585 , 5520 , 5456 , 5393 , 5329 , 5266 , 5202 , 5139 , 5076 , 5013 ,
                      4950 , 4887 , 4824 , 4761 , 4698 , 4634 , 4571 , 4507 , 4444 , 4380 ,
                      4315 , 4251 , 4186 , 4121 , 4056 , 3990 , 3924 , 3857 , 3789 , 3722 ,
                      3653 , 3584 , 3514 , 3444 , 3372 , 3300 , 3227 , 3152 , 3077 , 3000 ,
                      2922 , 2843 , 2761 , 2679 , 2594 , 2507 , 2417 , 2325 , 2229 , 2131 ,
                      2028 , 1920 , 1807 , 1688 , 1560 , 1421 , 1269 , 1097 ,  894 ,  631 , 0 } ;
byte Power = 25 ;                      // значение мощности по умолчанию ( при включении )
volatile boolean Zero = false ;        
//-----------------------------------------------------------------------
void setup()
{
  pinMode( ControlSimistor , OUTPUT ) ;
  pinMode( ControlZero , INPUT ) ;
  digitalWrite( ControlZero , HIGH ) ;
  attachInterrupt(0, EventZero , CHANGE) ;
}
//------------------------------------------------------------------------
 void EventZero()
{  
  Zero = true ;
}
//------------------------------------------------------------------------
 void loop()
{  
  if ( Zero )
  {
    Zero = false ;
    delayMicroseconds( tPower[ Power ] ) ;
    digitalWrite( ControlSimistor , HIGH ) ;
    delayMicroseconds( tSimistor ) ;
    digitalWrite( ControlSimistor , LOW ) ;
  }
// здесь изменяем Power
}
//------------------------------------------------------------------------

А как через счётчики-таймеры - так и не понял.....

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

 Всё по схеме из #5.....

Разъём SV1 - 1 и 3 на пин_GND , 4 на пин_2 , 2 на пин_8

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Молодец! Главное - с принципом разобраться, остальное - приложится.

Если устройство больше ничего делать не будет, то не стоит заморачиваться со счетчиками. разве что для самообразования. 

Но, дам направление по счетчикам: Библиотека TimerOne еще здесь почитать

Нужно сделать ШИМ с частотой 100 Гц и обнулять его (или запускать... не вдавался в подробности реализации этой библы) по Вашему прерыванию. Только измените вариант срабатывания по одному из фронтов.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

AlexFisher пишет:

Если устройство больше ничего делать не будет, то не стоит заморачиваться со счетчиками. разве что для самообразования. 

Устройство будет делать что-то ещё.... И самообразование - естественно....

Путей реализации много. Я попытаюсь пойти по такому ( ниже ) не из-за упёртости, а для изучения таймеров-счётчиков... Надеюсь на Вашу помощь и leshak, конешшшно же.....

Алгоритм :

- датчик нуля сети - на пин 2 ( INT0 )

- обработчик внешнего прерывания :

            - настраиваем счётчик на задержку в 6600 микросекунд - 25% мощности

            - разрешаем работу счётчика с прерыванием по переполнению

            - обработчик прерывания по переполнению 1 :

                            - на пин 9 устанавливаем HIGH

                            - перенастраиваем счётчик на задержку в 20 микросекунд - длительность упрИмпульса для                                             симистора

                            - переопределяем обработчик прерывания по переполнению :

                                                - обработчик прерывания по переполнению 2 :

                                                - на пин 9 устанавливаем LOW

                                                - переопределяем обработчик прерывания по переполнению на 1

 

....а в loop() - меняем значение мощности ( задержки )

Не сильно коряво объяснил ?

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Не сильно :)

Дерзайте. Будем помогать искать ошибки :) 

leshak
Offline
Зарегистрирован: 29.09.2011

 Если не ошибаюсь, то таймер/компаратор можно настроить что-бы он по сработке менял состояние пина на противоположное. То есть в обработчике будет задача только "выставить новое время задержки". А toggle ему он будет делать сам.

Статьи/примеры думаю сами нагуглите. 

А примера "из боевой задачи" можете попробовать порытся в исходниках вот этой библиотеки

http://sourceforge.net/projects/arduinorclib/files/releases/

Она включает в себя и классик для работы с таймером (аналог TimerOne библиотеки), и пример ее использования в классе PPMOut. Он как раз тем и занимается, что вначале расчитывает массив "длины импульсов", а потом переключает выходной пин через эти расчитанные интервалы времени.

Там внутри есть массивчик m_timings. В нем лежат интервалы времени в микросекундах через которые нужно менять пин. Как они расчитываются - можете забить, что-бы не разбиратся "зачем эта библиотека" и "что такое PPM" :)

Просто считаетй что массив m_timings - содержит интервалы. Тогда сам обработчик прерывания выглядит вообще "тупо до крика"

void handler()
{
	// set the compare register with the next value
	OCR1A += m_timings[m_timingPos];
}

Ну а у вас, видимо даже массива не будет, будете по очереди менять 220 и 6600.

Как сконфигурить таймер - смотрите выше в функции ::start  (там используется класс Timer1, если захочется "понять до самого конца - лезте в этот класс Timer1, берите даташит и смотрите какие регистры он выставляет и "что это означает"). Либо просто "спионерте" его себе, и не заморачиваесь использйте Timer1::setToggle(true, true);  :)

P.S. Не знаю хороший ли это "пример" или слишком "замудренный". Просто "последние место где я сталкивался с работой с таймерами".

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

leshak пишет:

Ну а у вас, видимо даже массива не будет, будете по очереди менять 220 и 6600.

Будет массив. Зависимость задежки упрИмпульса от нужной мощности. Мощность -от 0 до 100%, задержка - от 9900 до 0 микросекунд. 6600 - это просто для примера... для 25% мощности...

Спасибо, пойду учицца....

leshak
Offline
Зарегистрирован: 29.09.2011

 

SU-27-16 пишет:

leshak пишет:

Ну а у вас, видимо даже массива не будет, будете по очереди менять 220 и 6600.

Будет массив. Зависимость задежки упрИмпульса от нужной мощности. Мощность -от 0 до 100%, задержка - от 9900 до 0 микросекунд. 6600 - это просто для примера... для 25% мощности...

Спасибо, пойду учицца....

Зачем массив? Одной переменной хватит. У вас же не будет "серии задержек". У вас есть всего два интервала. Один фиксированный (220), а второй будет менятся (0-9900). Ну и что? Просто один константа, второй - переменная :)

#define PAUSE_LENGH 220
volatile unsigned int powerLength=6600;
volatile byte fl=1;
void time_handler(){

  OCR1A += fl?PAUSE_LENGH:powerLength;
  fl=!fl;
}

void loop(){
  ...
   powerLength=...   // меняем текущую мощу
  ...
}

 

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Тем более, что задержку от мощности можно считать - это будет функция от арккосинуса. Типа t=9900*arccos(P*Pi/100), где P в % 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

 Пока вот так :

#define ControlSimistor 9              // пин для управления симистором
#define ControlZero 2                  // пин контроля перехода сети через НУЛЬ
#define tSimistor 20                   // длительность импульса для открытия симистора
// таблица соответствия времени "задержки управляющего импульса" и "мощности", от 0% до 100%
byte tPower[ 202 ] = { 0x26 , 0xAC , 0x24 , 0x35 , 0x23 , 0x2E , 0x22 , 0x63 , 0x21 , 0xB7 , 0x21 , 0x1F , 0x20 , 0x94 , 0x20 , 0x14 , 0x1F , 0x9D , 0x1F , 0x2C ,
                       0x1E , 0xC0 , 0x1E , 0x59 , 0x1D , 0xF7 , 0x1D , 0x97 , 0x1D , 0x3B , 0x1C , 0xE1 , 0x1C , 0x8A , 0x1C , 0x35 , 0x1B , 0xE3 , 0x1B , 0x91 ,
                       0x1B , 0x42 , 0x1A , 0xF4 , 0x1A , 0xA7 , 0x1A , 0x5C , 0x1A , 0x11 , 0x19 , 0xC8 , 0x19 , 0x80 , 0x19 , 0x38 , 0x18 , 0xF2 , 0x18 , 0xAC ,
                       0x18 , 0x67 , 0x18 , 0x22 , 0x17 , 0xDF , 0x17 , 0x9B , 0x17 , 0x58 , 0x17 , 0x16 , 0x16 , 0xD4 , 0x16 , 0x93 , 0x16 , 0x52 , 0x16 , 0x11 ,
                       0x15 , 0xD1 , 0x15 , 0x90 , 0x15 , 0x50 , 0x15 , 0x11 , 0x14 , 0xD1 , 0x14 , 0x92 , 0x14 , 0x52 , 0x14 , 0x13 , 0x13 , 0xD4 , 0x13 , 0x95 ,
                       0x13 , 0x56 , 0x13 , 0x17 , 0x12 , 0xD8 , 0x12 , 0x99 , 0x12 , 0x5A , 0x12 , 0x1A , 0x11 , 0xDB , 0x11 , 0x9B , 0x11 , 0x5C , 0x11 , 0x1C ,
                       0x10 , 0xDB , 0x10 , 0x9B , 0x10 , 0x5A , 0x10 , 0x19 , 0x0F , 0xD8 , 0x0F , 0x96 , 0x0F , 0x54 , 0x0F , 0x11 , 0x0E , 0xCD , 0x0E , 0x8A ,
                       0x0E , 0x45 , 0x0E , 0x00 , 0x0D , 0xBA , 0x0D , 0x74 , 0x0D , 0x2C , 0x0C , 0xE4 , 0x0C , 0x9B , 0x0C , 0x50 , 0x0C , 0x05 , 0x0B , 0xB8 ,
                       0x0B , 0x6A , 0x0B , 0x1B , 0x0A , 0xC9 , 0x0A , 0x77 , 0x0A , 0x22 , 0x09 , 0xCB , 0x09 , 0x71 , 0x09 , 0x15 , 0x08 , 0xB5 , 0x08 , 0x53 ,
                       0x07 , 0xEC , 0x07 , 0x80 , 0x07 , 0x0F , 0x06 , 0x98 , 0x06 , 0x18 , 0x05 , 0x8D , 0x04 , 0xF5 , 0x04 , 0x49 , 0x03 , 0x7E , 0x02 , 0x77 , 0x00 , 0x01 } ;
/* int tPower[ 101 ] = { 9900 , 9269 , 9006 , 8803 , 8631 , 8479 , 8340 , 8212 , 8093 , 7980 ,
                      7872 , 7769 , 7671 , 7575 , 7483 , 7393 , 7306 , 7221 , 7139 , 7057 ,                             
                      6978 , 6900 , 6823 , 6748 , 6673 , 6600 , 6528 , 6456 , 6386 , 6316 ,
                      6247 , 6178 , 6111 , 6043 , 5976 , 5910 , 5844 , 5779 , 5714 , 5649 ,
                      5585 , 5520 , 5456 , 5393 , 5329 , 5266 , 5202 , 5139 , 5076 , 5013 ,
                      4950 , 4887 , 4824 , 4761 , 4698 , 4634 , 4571 , 4507 , 4444 , 4380 ,
                      4315 , 4251 , 4186 , 4121 , 4056 , 3990 , 3924 , 3857 , 3789 , 3722 ,
                      3653 , 3584 , 3514 , 3444 , 3372 , 3300 , 3227 , 3152 , 3077 , 3000 ,
                      2922 , 2843 , 2761 , 2679 , 2594 , 2507 , 2417 , 2325 , 2229 , 2131 ,
                      2028 , 1920 , 1807 , 1688 , 1560 , 1421 , 1269 , 1097 ,  894 ,  631 , 0 } ; */
byte Power = 25 ;                               // значение мощности по умолчанию ( при включении )  
volatile boolean ImpuseControl = true ;        // false - формирование задержки, true - формирование открывающего импульса
//-----------------------------------------------------------------------
void setup()
{
  pinMode( ControlSimistor , OUTPUT ) ;                 // пин для управления симистором - ВЫХОД
  digitalWrite( ControlSimistor , LOW ) ;               // пин для управления симистором - НАЧАЛЬНОЕ ЗНАЧЕНИЕ
  pinMode( ControlZero , INPUT ) ;                      // пин контроля перехода сети через НУЛЬ - ВХОД
  digitalWrite( ControlZero , HIGH ) ;                  // пин контроля перехода сети через НУЛЬ - ПОДТЯЖКА К +
  attachInterrupt(0, EventZero , CHANGE) ;              // пин контроля перехода сети через НУЛЬ - НАЗНАЧЕНИЕ ПРЕРЫВАНИЯ
  TCCR1A = 0x40 ;                                       // COM1A1 = 1 - изменяем состояние пина 9 на противоположный
  TCCR1B = 0x00 ;                                       // счётчик остановлен
//  TIMSK = 0x10 ;                                        // OCIE1A = 1 - прерывание по компаратору
  OCR1AH = tPower[ Power * 2 ] ;                        // начальная задержка 6600 микросекунд для 25% мощности
  OCR1AL = tPower[ Power * 2 + 1 ] ;                    // начальная задержка 6600 микросекунд для 25% мощности
}
//-----------------------------------------------------------------------
ISR(TIMER1_COMPA_vect)
{
  if ( ImpuseControl )
  {
    OCR1AH = 0x00 ;                                     // формирование импульса
    OCR1AL = 0x14 ;
  }
  if ( !ImpuseControl )
  {
    OCR1AH = tPower[ Power * 2 ] ;                      // формирование задержки
    OCR1AL = tPower[ Power * 2 + 1 ] ;
    TCCR1B = 0x00 ;                                     // останавливаем счётчик, ждём прерывания по переходу сети через НУЛЬ
  }
  TCNT1H = 0 ;                                          // обнуляем счётчик
  TCNT1L = 0 ;                                          // обнуляем счётчик
  ImpuseControl = !ImpuseControl ;
}
//------------------------------------------------------------------------
 void EventZero()
{  
  TCCR1B = 0x01 ;                                       // разрешение счёта, CS10 = 1 - без предделителя, CLK / 1
}
//------------------------------------------------------------------------
 void loop()
{  
  // здесь изменяем Power и многое другое, кроме использования ШИМ на 9 и 10 пинах
}
//------------------------------------------------------------------------

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

 из-за строки #37 - не компилируется :(

или регистр масок - по другому обозначается ?

Срасибо за скетчи, но - из #26 - мне в жисть не разобраться после Паскаля :)

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

AlexFisher пишет:

t=9900*arccos(P*Pi/100), где P в % 

это я чуть-чуть знаю :)

alfa = arccos ( P / 50 - 1 )                          - в радианах

alfa = arccos ( P / 50 - 1 ) * 180 / Pi          - в градусах

t = arccos ( P / 50 - 1 ) * 180 / Pi * 10000 / 180       - в микросекундах ( для 50 Гц )

t = arccos ( P / 50 - 1 ) * 10000 / Pi , с учётом открИмпульса -        t = arccos ( P / 50 - 1 ) * 9980 / Pi

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

 Таблицу соответствия делал, ибо не нашёл в Разделе Программирование - arccos ()....

leshak
Offline
Зарегистрирован: 29.09.2011

SU-27-16 пишет:

 Таблицу соответствия делал, ибо не нашёл в Разделе Программирование - arccos ()....

Нужно еще помнить что "Раздел программирования" рассказывает только про "ардуино функции" (и то, не всегда полно, на arduino.cc - полней). Но и там - не все бывает задокументированно. Следу "заветам AlexFisher" полезном еще самому .h файла библиотек порытся, там бывают полезняшки которые в доках не описанны.

И опять-таки, помним что "ардуино" и "обертка" под которой лежит C/C++ AVR-ристый. Поэтому многие вещи можно гуглить не только в компании с словом "Arduino" но и C/C++ AVR

В частности можно использовать многие функции из AvrLibc  (как минимум всякие работы со строками)

http://www.nongnu.org/avr-libc/user-manual/modules.html

Помоему там и кой чаго "математического" надыбать можно :)

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

 :) arcCos() без библиотек работает, как в экселе - acos()

Это пока крайняя версия :

#define ControlSimistor 9              // пин для управления симистором
#define ControlZero 2                  // пин контроля перехода сети через НУЛЬ
byte Power = 25 ;                               // значение мощности по умолчанию ( при включении )  
float Temp ;
volatile boolean ImpulseControl = true ;        // false - формирование задержки, true - формирование открывающего импульса
volatile byte tImpulseControlH ;                // начальная задержка 6640 микросекунд для 25% мощности
volatile byte tImpulseControlL ;                // начальная задержка 6640 микросекунд для 25% мощности
//-----------------------------------------------------------------------
void setup()
{
  Serial.begin( 9600 ) ;
  pinMode( ControlSimistor , OUTPUT ) ;                 // пин для управления симистором - ВЫХОД
  digitalWrite( ControlSimistor , LOW ) ;               // пин для управления симистором - НАЧАЛЬНОЕ ЗНАЧЕНИЕ
  pinMode( ControlZero , INPUT ) ;                      // пин контроля перехода сети через НУЛЬ - ВХОД
  digitalWrite( ControlZero , HIGH ) ;                  // пин контроля перехода сети через НУЛЬ - ПОДТЯЖКА К +
  attachInterrupt(0, EventZero , CHANGE) ;              // пин контроля перехода сети через НУЛЬ - НАЗНАЧЕНИЕ ПРЕРЫВАНИЯ
  TCCR1A = 0x40 ;                                       // COM1A1 = 1 - изменяем состояние пина 9 на противоположный
  TCCR1B = 0x00 ;                                       // счётчик остановлен
//  TIMSK = 0x10 ;                                        // OCIE1A = 1 - прерывание по компаратору
  CalctImpulseControl( Power ) ;                          // начальная задержка для мощности по умолчанию
}
//-----------------------------------------------------------------------
ISR(TIMER1_COMPA_vect)
{
  if ( ImpulseControl )
  {
    OCR1AH = 0x00 ;                                     // формирование импульса 21 микросекунда
    OCR1AL = 0x15 ;
  }
  if ( !ImpulseControl )
  {
    OCR1AH = tImpulseControlH ;                         // формирование задержки
    OCR1AL = tImpulseControlL ;
    TCCR1B = 0x00 ;                                     // останавливаем счётчик до следующего EventZero()
  }
  TCNT1H = 0 ;                                          // обнуляем счётчик
  TCNT1L = 0 ;                                          // обнуляем счётчик
  ImpulseControl = !ImpulseControl ;
}
//------------------------------------------------------------------------
 void EventZero()
{  
  TCCR1B = 0x01 ;                                       // разрешение счёта, CS10 = 1 - без предделителя, CLK / 1
}
//------------------------------------------------------------------------
 void CalctImpulseControl( byte _Power )
{  
  Temp = acos( Power / 50.0 - 1 ) * 9960 / 3.1415926 ;    // рассчёт времени задержки от мощности в процентах
  tImpulseControlH = int( Temp ) >> 8 ;
  tImpulseControlL = ( int( Temp ) & 0xFF ) + 2 ;
}
//------------------------------------------------------------------------
 void PrintControl()
{  
  Serial.print( Power ) ;
  Serial.print( "     " ) ;
  Serial.print( Temp ) ;
  Serial.print( "     0x" ) ;
  Serial.print( tImpulseControlH , HEX ) ;
  Serial.print( tImpulseControlL , HEX ) ;
  Serial.print( "     " ) ;
  Serial.print( tImpulseControlH * 256 + tImpulseControlL , DEC ) ;
  Serial.println( "" ) ;
  delay( 100 ) ;
}
//------------------------------------------------------------------------
 void loop()
{  
  for ( byte n = 0 ; n < 101 ; n ++ )
  {
    Power = n ;
    CalctImpulseControl( Power ) ;
    PrintControl() ;
  }
  for ( int n = 99 ; n > 0 ; n -- )
  {
    Power = n ;
    CalctImpulseControl( Power ) ;
    PrintControl() ;
  }
}
//------------------------------------------------------------------------

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

 строки нужно добавить    #28A = #36    и    #28B = #37 ....

Почему же строка #19 капризничает ?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

SU-27-16 пишет:

 строки нужно добавить    #28A = #36    и    #28B = #37 ....

Нет, не надо....... забыл, что это уже сделано в ## после if-ов

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

SU-27-16 пишет:

 :) arcCos() без библиотек работает, как в экселе - acos()

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

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

 Извините... Наверное тихо спросил.... :)

Компилятор ругается на обращение к регистру маски прерываний. ПРОШУ ПОМОЩИ !

.....если раскомментить TIMSK , всё ломается :(

void setup()
{
  Serial.begin( 9600 ) ;
  pinMode( ControlSimistor , OUTPUT ) ;                 // пин для управления симистором - ВЫХОД
  digitalWrite( ControlSimistor , LOW ) ;               // пин для управления симистором - НАЧАЛЬНОЕ ЗНАЧЕНИЕ
  pinMode( ControlZero , INPUT ) ;                      // пин контроля перехода сети через НУЛЬ - ВХОД
  digitalWrite( ControlZero , HIGH ) ;                  // пин контроля перехода сети через НУЛЬ - ПОДТЯЖКА К +
  attachInterrupt(0, EventZero , CHANGE) ;              // пин контроля перехода сети через НУЛЬ - НАЗНАЧЕНИЕ ПРЕРЫВАНИЯ
  TCCR1A = 0x40 ;                                       // COM1A1 = 1 - изменяем состояние пина 9 на противоположный
  TCCR1B = 0x00 ;                                       // счётчик остановлен
//  TIMSK = 0x10 ;                                        // OCIE1A = 1 - прерывание по компаратору
  CalctImpulseControl( Power ) ;                        // начальная задержка для мощности по умолчанию
}

 

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Потому что этот регистр для каждого таймера свой, т.е. нет TIMSK, есть TIMSK0, TIMSK1, TIMSK2

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

AlexFisher пишет:

Не сильно :)

Дерзайте. Будем помогать искать ошибки :) 

Это Вы и вы - умеете !!!!!!

А по алгоритму - критиканёте ?

Что обрабатываются оба полупериода сетевого напряжения.... Что счётчик заморожен после формирования открывающего импульса до окончания полупериода.....

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

 Конспектировал, пересчитывал все регистры, и спареннные, и одиночные..... А вот просчитался про TIMSK0.....2 :(

Спасибо !

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Читайте хедеры!

Я это нашел в iom238p.h (он для UNO как раз) :)

ТРИ МИРА
ТРИ МИРА аватар
Offline
Зарегистрирован: 09.01.2012

Привет ребята. Есть одна не приятная проблема, каксаемая симистора.Есть такое убеждения что они не стабильно работае, а вот альтернативы я что то не нашел. Не стабильность работы связано с так называемым залипанием или ложным сработыванием. Разумеется все это лезчится отключением питания и новым запуском системы.

ТРИ МИРА
ТРИ МИРА аватар
Offline
Зарегистрирован: 09.01.2012

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

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Есть еще "выключаемые" тиристоры.

ТРИ МИРА
ТРИ МИРА аватар
Offline
Зарегистрирован: 09.01.2012

AlexFisher пишет:

Есть еще "выключаемые" тиристоры.

было бы неплохо посмотреть пример.

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

ТРИ МИРА пишет:

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

Почему "ни у кого не встречалось" - есть в интернете статьи по проблемам ложного срабатывания. Правда в них говорится, что причина этому - неэквивалентная замена силовых транзисторов, что приводит к изменению резистивно-емкостных параметров. Методов борьбы я не увидел, да и та статья на это не претендовала...

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

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

http://ru.wikipedia.org/wiki/%D0%A1%D0%B8%D0%BC%D0%B8%D1%81%D1%82%D0%BE%D1%80

Ищите абзац "Ограничения".

"Залипание" - это когда скорость переключения больше допустимой (dU/dt больше указанного в параметрах симистора). Проявляется на индуктивной нагрузке.

 

ТРИ МИРА
ТРИ МИРА аватар
Offline
Зарегистрирован: 09.01.2012

Рас уж симистор такой вариант не надежный может на мощном транзисторе возможно такое реализовать.

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Можно, управление будет проще (стандартный ШИМ), но схема сложнее - нужно изолированное питание для транзистора (в принципе, китайский адаптер подойдет). Нужен опртрон, транзистор должен быть включен в диагональ моста из мощных диодов.

Ну и греться это будет не в пример сильнее.

Если не понятно, набросаю схему.

ТРИ МИРА
ТРИ МИРА аватар
Offline
Зарегистрирован: 09.01.2012

AlexFisher пишет:

Можно, управление будет проще (стандартный ШИМ), но схема сложнее - нужно изолированное питание для транзистора (в принципе, китайский адаптер подойдет). Нужен опртрон, транзистор должен быть включен в диагональ моста из мощных диодов.

Ну и греться это будет не в пример сильнее.

Если не понятно, набросаю схему.

Оптром уже приобрел MOС3020, мощьный транзистор еще не купил просто незнаю какой подойдет. Про схему даже и не мечтал, буду признателен. Немного не понял про какой арептер идет речь. На сколько мощьные диоды понадобятся. Да и нужен ли мне мощьные детали, там вентилятор то простенький и слабенький )