Диммер 220 вольт от РоботДин

Rankle
Offline
Зарегистрирован: 31.10.2020

Добрый день.

Весь день сижу в интернете перерыл кучу ссылок. Нашёл одну работающую великолепно.

Подскажите пожалуйста как отредактировать функцию обработки перехода через Ноль, что бы исключить Delay?

void zero_crosss_int()  //function to be fired at the zero crossing to dim the light
{
  int dimtime = (75*dimming);    // For 60Hz =>65    
  delayMicroseconds(dimtime);    // Wait till firing the TRIAC
  digitalWrite(AC_LOAD, HIGH);   // Fire the TRIAC
  delayMicroseconds(10);         // triac On propogation delay (for 60Hz use 8.33)
  digitalWrite(AC_LOAD, LOW);    // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC
}

Потому что после ее выполнения работа остальной программы ЖУТКО тормозит.

Т.е. при работе с поворотным энкодером после каждого поворота я жду до 5 секунд что бы увидеть реакцию.

А так же при отображении на LCD тоже значения отображаются с задержкой в секунд 3-5.

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

Очевидно делать через таймер, а не через delay()

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Rankle пишет:
как отредактировать функцию обработки перехода через Ноль, что бы исключить Delay?
Никак.

Её нужно выбросить, а вместо неё написать ТРИ другие. И, заодно, поменять логику в месте её вызова.

Дим-мычъ
Offline
Зарегистрирован: 20.03.2021

В программировании на C я близок к "0", но как по мне, функция перехода через ноль, довольно много ресурса МК займёт.

Не проще ли использовать какую-нибудь оптопару, в которой эта функция уже встроена?

Rankle
Offline
Зарегистрирован: 31.10.2020

Евгений, подскажите какие функции? Мне надо что бы в определенный момент в программе диммер полностью медленно зажёг лампу, а в другой момент полностью медленно её погасил. От 0 до 100% и наоборот. Не основвываясь на каких либо датчиках, кнопках, энкодерах и прочее. Я уже всё перечитал и видимо что то недопонимаю.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Rankle пишет:
Евгений, подскажите какие функции?

Ну, как, какие - такие же, только не одну, а три. Вот смотрите на мои комментарии к Вашем коду

void zero_crosss_int(void) {
  delayMicroseconds(75*dimming); // Первая задержка
  digitalWrite(AC_LOAD, HIGH);   // Дело №1
  delayMicroseconds(10);         // Вторая задержка
  digitalWrite(AC_LOAD, LOW);    // дело №2
}

Вам потребуется функция, которая может настроить таймер так, чтобы через указанный интервал была вызвана указанная Вами функция. Таких полно во всевозможных библиотеках таймеров, но я эти библиотеки не пользую, потому не очень знаю. Допустим эта функция называется setupCallOnce и имеет два параметра - первый - количество микросекунд и второй - имя функции, которую надо вызывать (имя в С/С++ является указателем на функцию). Т.е. если мы запишем так:

setupCallOnce(1500, kaka);

то эта функция настроит таймер и немедленно вернёт управление, Ваша программа продолжит исполнение. А через 1500 микросекунд Ваша программа прервётся, выполнится функция kaka и после этого Ваша программа продолжит выполнение с того места, где прервалась.

Если такая функция у Вас есть, то вместо одной Вашей функции zero_crosss_int, Вы пишете три

void delo2(void) {
	digitalWrite(AC_LOAD, LOW); 
}

void delo1(void) {
	digitalWrite(AC_LOAD, HIGH);   // Дело №1
	setupCallOnce(10, delo2);
}

void zero_crosss_int() {
	setupCallOnce(75*dimming, delo1);
}

Вызываете zero_crosss_int. Она настроит таймер и вернёт управление Вашей программе, которая продолжит работу. Через 75*dimming микросекунд Ваша программа прервётся, исполнится функция delo1. Та выполнит digitalWrite и настроит таймер. Ваша программа после этого продолжится, а через 10 микросекунд, снова прервётся на выполнение функции delo2, после чего снова продолжится.

Вот, примерно так это и делается.

Функцию с функционалом как у setupCallOnce поищите в библиотеках таймеров - таких функций навалом. Это первое, чем прочищают горло программисты, впервые пришедшие в мир микроконтроллеров :-)

Rankle
Offline
Зарегистрирован: 31.10.2020

Добрый день

Попробовал на библиотеке Алекса Гайвера.

void SwitchDownDimmer() 
{
  digitalWrite(AC_LOAD, LOW); 
}

void SwitchUpDimmer() {
  digitalWrite(AC_LOAD, HIGH);   
  Timer0.setPeriod(10);
  SwitchDownDimmer();
}

void zero_cross() {
  Timer0.setPeriod(75*dimming);
  SwitchUpDimmer();
}

Работает но не так как надо. Нет плавности включения. Просто включает и всё..

Я прочитал мануал по работе с этой библиотекой. Там используется обработчик ISR.

Может с этой библиотекой такой алгоритм не работает?

Изменение переменной dimming в коде происходит по установления флага

if ( ....)
{

for (int i=128; i > 5; i--) { dimming=i; delay(50); 
}

 

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

1. Настраиваем таймер на нужную точность.
2. При переходе через ноль запускаем таймер
3. При достижении нужного значения (угол открытия тиристора ) подаём на нужный пин нужный сигнал.
4. Обнуляем счётчик таймера
5. Меняем значение по совпадению на равное 5-10мкс(тиристор нужно закрыть)
6. По истечению снимаем сигнал с пина.
7. Отключаем таймер до момента следующего перехода через 0

Rankle
Offline
Зарегистрирован: 31.10.2020

Поправьте по коду пожалуйста:

#include <GyverTimers.h>

int8_t AC_LOAD = 9;    // Output to Opto Triac pin
volatile int8_t dimming = 128;  // Dimming level (0-128)  0 = ON, 128 = OFF

void setup() 
{
  pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
  digitalWrite (AC_LOAD, LOW);
  attachInterrupt(1, zero_cross, RINSING);  // Choose the zero cross interrupt # from the table above
  Timer0.setPeriod(37);             // 37 мкс - период прерываний для 255 шагов и 50 Гц
  Timer0.stop();
}

void loop() 
  {
   for (int i=128; i > 5; i--) { dimming=i; delay(50); }

   dimming = 128;
   delay(50);
  }


void SwitchDownDimmer() 
{
  digitalWrite(AC_LOAD, LOW); 
  Timer0.restart();  
}

void SwitchUpDimmer() {
  Timer0.restart();
  digitalWrite(AC_LOAD, HIGH);   
  Timer0.setPeriod(10);
  SwitchDownDimmer();
}

void zero_cross() {
  Timer0.setPeriod(75*dimming);
  SwitchUpDimmer();
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Rankle пишет:

void SwitchDownDimmer() 
{
  digitalWrite(AC_LOAD, LOW); 
}

void SwitchUpDimmer() {
  digitalWrite(AC_LOAD, HIGH);   
  Timer0.setPeriod(10);
  SwitchDownDimmer();
}

void zero_cross() {
  Timer0.setPeriod(75*dimming);
  SwitchUpDimmer();
}

Вы делаете СОВСЕМ НЕ ТО. Внимательно посмотрите на мой код и сравните со своим! Нахрена Вы вызываете SwitchUpDimmer и SwitchDownDimmer в строках №№ 14 и 9? Их должен таймер вызывать, а не Вы!

SLKH
Offline
Зарегистрирован: 17.08.2015

Без особых на то причин я бы не стал заморачиваться с заменой второй задержки (строка 6 исходного текста). 10 микросекунд раз в полупериод (0.1%) вряд будут заметны.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

SLKH пишет:

Без особых на то причин я бы не стал заморачиваться с заменой второй задержки (строка 6 исходного текста). 10 микросекунд раз в полупериод (0.1%) вряд будут заметны.

Это да.

А если тактовая частота типа 1МГц, так и вообще смысла нет - там только на вход в прерывание 4 такта нужно, а задержка всего на 10.

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

SLKH пишет:

Без особых на то причин я бы не стал заморачиваться с заменой второй задержки (строка 6 исходного текста). 10 микросекунд раз в полупериод (0.1%) вряд будут заметны.

+100500 тем более, что именно эта задержка необходима в таком виде - она пережидает переходные процессы типа звон.

SLKH
Offline
Зарегистрирован: 17.08.2015

nik182 пишет:

SLKH пишет:

Без особых на то причин я бы не стал заморачиваться с заменой второй задержки (строка 6 исходного текста). 10 микросекунд раз в полупериод (0.1%) вряд будут заметны.

+100500 тем более, что именно эта задержка необходима в таком виде - она пережидает переходные процессы типа звон.

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

Rankle
Offline
Зарегистрирован: 31.10.2020

Вот не знаю - нахрена.

Я 350 прмеров уже скачал из инета, прочитал не одну страницу текста. Я понял что везде показаны примеры диммера, а на самом деле реализована не функция диммирования а функция реле.

НЕТУ ПЛАВНОГО ВКЛЮЧЕНИЯ!!

Как мне понять чё делать, если плавного включения НЕТ.

Скачал очередной пример. Лампа накаливания моргает как азбука морзе. Опять нет плавного включения. Хотя на видео автор ползунковым регулятором как то ее включает плавно. Ничего не понимаю Как?

Скажите пожалуйста точно, что мне здесь поменять что бы я увидел плавность включения? (в Loop закоментированы оригинальные строки. Я всего лишь из заменил на плавное изменение переменной)

#include <CyberLib.h>
#define dimPin 9
#define zeroPin 3
volatile int tic, Dimmer;

void setup() {
  Serial.begin(9600);
  pinMode(dimPin, OUTPUT);
  digitalWrite(dimPin, 0);
  pinMode(zeroPin, INPUT);                 // настраиваем порт на вход для отслеживания прохождения сигнала через ноль
  attachInterrupt(1, detect_up, RISING);  // настроить срабатывание прерывания interrupt0 на pin 2 на низкий уровень

  StartTimer1(timer_interrupt, 40);        // время для одного разряда ШИМ
  StopTimer1();                            // остановить таймер

  Serial.println("Start");
}

void loop() {
   for (int i=0; i < 255; i++) { Dimmer=i; delay(50); }
   delay (100);
   Dimmer = 255;

  // раскомментировать для ввода числа диммирования чеерез монитор порта (0 - 255)
  //if (Serial.available()) {
  //  Dimmer = Serial.parseInt();
  //  Serial.println(Dimmer);
  //}
  
  // раскомментировать для управления потенциометром (аналоговый А0)
  // Dimmer = map(analogRead(0), 0, 1023, 240, 0);

} //----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ-------------------------- void timer_interrupt() { // прерывания таймера срабатывают каждые 40 мкс tic++; // счетчик if (tic > Dimmer) // если настало время включать ток digitalWrite(dimPin, 1); // врубить ток } void detect_up() { // обработка внешнего прерывания на пересекание нуля снизу tic = 0; // обнулить счетчик ResumeTimer1(); // перезапустить таймер attachInterrupt(1, detect_down, RISING); // перенастроить прерывание } void detect_down() { // обработка внешнего прерывания на пересекание нуля сверху tic = 0; // обнулить счетчик StopTimer1(); // остановить таймер digitalWrite(dimPin, 0); // вырубить ток attachInterrupt(1, detect_up, FALLING); // перенастроить прерывание } //----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ--------------------------

 

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

Rankle пишет:

Я всего лишь из заменил на плавное изменение переменной)

код вставьте нормально

И слушайте, если вы в этом нихрена не понимаете - зачем вы лезете править код?

Rankle
Offline
Зарегистрирован: 31.10.2020
#include <CyberLib.h>
#define dimPin 9
#define zeroPin 3
volatile int tic, Dimmer;

void setup() {
  Serial.begin(9600);
  pinMode(dimPin, OUTPUT);
  digitalWrite(dimPin, 0);
  pinMode(zeroPin, INPUT);                 // настраиваем порт на вход для отслеживания прохождения сигнала через ноль
  attachInterrupt(1, detect_up, RISING);  // настроить срабатывание прерывания interrupt0 на pin 2 на низкий уровень

  StartTimer1(timer_interrupt, 40);        // время для одного разряда ШИМ
  StopTimer1();                            // остановить таймер

  Serial.println("Start");
}

void loop() {
  // раскомментировать для ввода числа диммирования чеерез монитор порта (0 - 255)
  //if (Serial.available()) {
  //  Dimmer = Serial.parseInt();
  //  Serial.println(Dimmer);
  // }
  
  // раскомментировать для управления потенциометром (аналоговый А0)
  // Dimmer = map(analogRead(0), 0, 1023, 240, 0);
   
   for (int i=0; i < 255; i++) { Dimmer=i; delay(50); }
   delay (100);
   Dimmer = 255;

}

//--
void timer_interrupt() {       // прерывания таймера срабатывают каждые 40 мкс
  tic++;                       // счетчик
  if (tic > Dimmer)            // если настало время включать ток
    digitalWrite(dimPin, 1);   // врубить ток
}

void  detect_up() {    // обработка внешнего прерывания на пересекание нуля снизу
  tic = 0;                                  // обнулить счетчик
  ResumeTimer1();                           // перезапустить таймер
  attachInterrupt(1, detect_down, RISING);  // перенастроить прерывание
}

void  detect_down() {  // обработка внешнего прерывания на пересекание нуля сверху
  tic = 0;                                  // обнулить счетчик
  StopTimer1();                             // остановить таймер
  digitalWrite(dimPin, 0);                  // вырубить ток
  attachInterrupt(1, detect_up, FALLING);   // перенастроить прерывание
}
//--

 

Rankle
Offline
Зарегистрирован: 31.10.2020

Да, я не понимаю. Но очень хочу понять и разобраться.

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

Мол все равно сейчас ничего не понимаешь

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

пины правильно подключены? пин 3 - детектор нуля?

попробуйте свою строчку изменить вот так:

for (int i=0; i < 255; i++) { 
noInterrupts();
Dimmer=i; 
interrupts();
delay(100); }

 

Rankle
Offline
Зарегистрирован: 31.10.2020

b707 пишет:

пины правильно подключены? пин 3 - детектор нуля?

попробуйте свою строчку изменить вот так:

for (int i=0; i < 255; i++) { 
noInterrupts();
Dimmer=i; 
interrupts();
delay(100); }

 

 

да, 3 пин подключен к Zero на диммере (2 пин у меня поворотный энкодер).

Я потом этот код в главную программу вставлю.

Попробовал пример. Не могу обьяснить словами. Моргает с разными интервалами. Жаль не могу прикрепить видео.

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

вы уверены. что у вас зерокросс на модуле работает? - по коду, насколько я вижу - проблем нет, все должно отрабатывать правильно

Rankle
Offline
Зарегистрирован: 31.10.2020

b707 пишет:

вы уверены. что у вас зерокросс на модуле работает? - по коду, насколько я вижу - проблем нет, все должно отрабатывать правильно

 

В самом начале темы я приложил код. Он работает отменно. Только там - delay.

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

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

Rankle пишет:

В самом начале темы я приложил код. Он работает отменно. Только там - delay.

да. сорри, уже посмотрел.

Этот код другой и, возможно, он вам не подходит.

Можете написать, как у вас вызывается прерывание на пересечение нуля в том коде. что "прекрасно работает"?

Rankle
Offline
Зарегистрирован: 31.10.2020
int AC_LOAD = 9;    // Output to Opto Triac pin
int dimming = 128;  // Dimming level (0-128)  0 = ON, 128 = OFF

void setup()
{
  pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
  attachInterrupt(1, zero_crosss_int, RISING);  // Choose the zero cross interrupt # from the table above
}

void zero_crosss_int()  //function to be fired at the zero crossing to dim the light
{

  int dimtime = (75*dimming);    // For 60Hz =>65    
  delayMicroseconds(dimtime);    // Wait till firing the TRIAC
  digitalWrite(AC_LOAD, HIGH);   // Fire the TRIAC
  delayMicroseconds(10);         // triac On propogation delay (for 60Hz use 8.33)
  digitalWrite(AC_LOAD, LOW);    // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC
}

void loop()  
{
  for (int i=128; i > 5; i--)
  {
    dimming=i;
    delay(50);
  }
}

 

Rankle
Offline
Зарегистрирован: 31.10.2020

Вот этот код работает как надо.

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

вот это пробуйте

#include <CyberLib.h>
#define dimPin 9
#define zeroPin 3
volatile int tic, Dimmer;

void setup() {
  Serial.begin(9600);
  pinMode(dimPin, OUTPUT);
  digitalWrite(dimPin, 0);
  pinMode(zeroPin, INPUT);                 // настраиваем порт на вход для отслеживания прохождения сигнала через ноль
  attachInterrupt(1, detect_up, RISING);  // настроить срабатывание прерывания interrupt0 на pin 2 на низкий уровень

  StartTimer1(timer_interrupt, 40);        // время для одного разряда ШИМ
  Serial.println("Start");
}

void loop() {
  // раскомментировать для ввода числа диммирования чеерез монитор порта (0 - 255)
  //if (Serial.available()) {
  //  Dimmer = Serial.parseInt();
  //  Serial.println(Dimmer);
  // }
  
  // раскомментировать для управления потенциометром (аналоговый А0)
  // Dimmer = map(analogRead(0), 0, 1023, 240, 0);
   
   for (int i=0; i < 255; i++) { 
     noInterrupts();
     Dimmer=i; 
     interrupts();
     delay(50); 
    }
   delay (100);
   Dimmer = 255;

}

//--
void timer_interrupt() {       // прерывания таймера срабатывают каждые 40 мкс
  tic++;                       // счетчик
  if (tic > Dimmer)  {          // если настало время включать ток
    digitalWrite(dimPin, 1); 
    delayMicroseconds(10); 
    digitalWrite(dimPin, 0);
    tic = -10000;              //от в707 - предотвращение повторных включений триака в одном периоде
  }
  
}

void  detect_up() {    
  tic = 0;                                  // обнулить счетчик
 }

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

А можно уточнить: какой контроллер и его частота?

 

Rankle
Offline
Зарегистрирован: 31.10.2020

b707 пишет:

вот это пробуйте

#include <CyberLib.h>
#define dimPin 9
#define zeroPin 3
volatile int tic, Dimmer;

void setup() {
  Serial.begin(9600);
  pinMode(dimPin, OUTPUT);
  digitalWrite(dimPin, 0);
  pinMode(zeroPin, INPUT);                 // настраиваем порт на вход для отслеживания прохождения сигнала через ноль
  attachInterrupt(1, detect_up, RISING);  // настроить срабатывание прерывания interrupt0 на pin 2 на низкий уровень

  StartTimer1(timer_interrupt, 40);        // время для одного разряда ШИМ
  Serial.println("Start");
}

void loop() {
  // раскомментировать для ввода числа диммирования чеерез монитор порта (0 - 255)
  //if (Serial.available()) {
  //  Dimmer = Serial.parseInt();
  //  Serial.println(Dimmer);
  // }
  
  // раскомментировать для управления потенциометром (аналоговый А0)
  // Dimmer = map(analogRead(0), 0, 1023, 240, 0);
   
   for (int i=0; i < 255; i++) { 
     noInterrupts();
     Dimmer=i; 
     interrupts();
     delay(50); 
    }
   delay (100);
   Dimmer = 255;

}

//--
void timer_interrupt() {       // прерывания таймера срабатывают каждые 40 мкс
  tic++;                       // счетчик
  if (tic > Dimmer)  {          // если настало время включать ток
    digitalWrite(dimPin, 1); 
    delayMicroseconds(10); 
    digitalWrite(dimPin, 0);
    tic = -10000;              //от в707 - предотвращение повторных включений триака в одном периоде
  }
  
}

void  detect_up() {    
  tic = 0;                                  // обнулить счетчик
 }

 

 

 спасибо. В понедельник попробую. У меня всё на работе.

Rankle
Offline
Зарегистрирован: 31.10.2020

wdrakula пишет:

А можно уточнить: какой контроллер и его частота?

 

 

Ардуино Нано (ATmega 328, 16Мгц)

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

Почему в стартовом посте нужен "диммер", а в итоге "плавное включение" ?
Это как бы не одно и то же.

Rankle
Offline
Зарегистрирован: 31.10.2020

Потому что "dimming" в переводе с английского означает затемнение, потускнение, гаснущий и т. п.

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

Rankle пишет:
Потому что "dimming" в переводе с английского означает затемнение, потускнение, гаснущий и т. п.

С какого тогда тебе нужно плавное зажигание ?
Диммер в техническом плане, это регулятор.
Плавный розжиг/затухание это одна из его опций.

Rankle
Offline
Зарегистрирован: 31.10.2020

Вот мне и нужна реализация этой самой опции. А включить и выключить я и с помощью реле могу. Если вам нечего сказать ничего по существу (помочь исправить код, ну или внести в него изменения) то не надо здесь сыпать теорией и этимологией слова. Пожалуйста. Я за практическим советом и реальной помощью сюда обратился.

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

Можете показать сам модуль?

Дело в том, что я как-то купил модуль RBDDimmer без детекции нуля, вернее, она там как бы и была, но ардуино не видела этот переход.

Rankle
Offline
Зарегистрирован: 31.10.2020

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

Rankle пишет:
Вот мне и нужна реализация этой самой опции. А включить и выключить я и с помощью реле могу. Если вам нечего сказать ничего по существу (помочь исправить код, ну или внести в него изменения) то не надо здесь сыпать теорией и этимологией слова. Пожалуйста. Я за практическим советом и реальной помощью сюда обратился.

Я тебе уже дал совет и даже алгоритм расписал.
"Чего же тебе ещё надо , собака?" © И.Грозный (ИВМП)

ЗЫ: за готовым кодом в раздел :"ищу исполнителя"

Rankle
Offline
Зарегистрирован: 31.10.2020

Kakmyc пишет:
Rankle пишет:
Вот мне и нужна реализация этой самой опции. А включить и выключить я и с помощью реле могу. Если вам нечего сказать ничего по существу (помочь исправить код, ну или внести в него изменения) то не надо здесь сыпать теорией и этимологией слова. Пожалуйста. Я за практическим советом и реальной помощью сюда обратился.
Я тебе уже дал совет и даже алгоритм расписал. "Чего же тебе ещё надо , собака?" © И.Грозный (ИВМП) ЗЫ: за готовым кодом в раздел :"ищу исполнителя"

 

Я рад, что вы любите Гайдая и цитируете его шедевры. И тыкать мне не надо, я с вами на брудершафт мороженое не лизал

P.S. Я "реализовал" предложенный вами алгоритм (#16). Нет плавного включения. Результат - ацикличное включение и выключение лампы накаливания.

Код за меня писать не надо. Достаточно указать на мои ошибки

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

Про диммеры на форуме куча тем. Мы вот уже 4 года назад один диммер на прерываниях отладили. http://arduino.ru/forum/programmirovanie/attiny85-i-preryvanie

 

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

Rankle пишет:

Вот мне и нужна реализация этой самой опции. А включить и выключить я и с помощью реле могу. Если вам нечего сказать ничего по существу (помочь исправить код, ну или внести в него изменения) то не надо здесь сыпать теорией и этимологией слова. Пожалуйста. Я за практическим советом и реальной помощью сюда обратился

Через жопу реализовал.

Алгоритм такой:
1. На старте угол зажигания (время после перехода через ноль)максимальный
2. Через миллис реализуем нужную плавность зажигания
Т.е :
if(угол не минимальный&& millis()-lastTimeFade>=100)
{ lastTimeFade=millis(); угол--;}

Rankle
Offline
Зарегистрирован: 31.10.2020

Kakmyc пишет:
Rankle пишет:

Вот мне и нужна реализация этой самой опции. А включить и выключить я и с помощью реле могу. Если вам нечего сказать ничего по существу (помочь исправить код, ну или внести в него изменения) то не надо здесь сыпать теорией и этимологией слова. Пожалуйста. Я за практическим советом и реальной помощью сюда обратился

Через жопу реализовал. Алгоритм такой: 1. На старте угол зажигания (время после перехода через ноль)максимальный 2. Через миллис реализуем нужную плавность зажигания Т.е : if(угол не минимальный&& millis()-lastTimeFade>=100) { lastTimeFade=millis(); угол--;}

 

Ну а чё, у нас в России всё череж жопу. Как без этого?

Я конечно не на милис попробовал сделать, но что то сделал.

Только лампа включается и не выключается плавно.

 Прошу подсказать где я ошибся.

#include <TimerOne.h>

volatile uint8_t tic ;
uint8_t data;
int AC_LOAD1 = 8; //первый диммер
int AC_LOAD2 = 9; //последний диммер
int Dimmer1; //brighness 1
int Dimmer2; //brighness 2
void setup() {


   pinMode (AC_LOAD1, OUTPUT);
   digitalWrite(AC_LOAD1, LOW); // гасим оответствующий пин
   pinMode (AC_LOAD2, OUTPUT);
   digitalWrite(AC_LOAD2, LOW); // гасим оответствующий пин
   Dimmer1 = 10; //выставим яркость соответствующего диммера в 0
   Dimmer2 = 10; //выставим яркость соответствующего диммера в 0
  
  attachInterrupt(0, detect_up, LOW);  // настроить срабатывание прерывания interrupt0 на pin 2 на низкий уровень
  Timer1.initialize(40);              // Интервал срабатывания таймера в мкс
  Timer1.attachInterrupt(halfcycle);   //будет вызыватся каждый раз при отсчете заданого времени
  Timer1.stop();
  Serial.begin(9600); //инициализация порта
}

//********************обработчики прерываний*******************************
void halfcycle()  //прерывания таймера
{
  tic--;  //счетчик
  if (Dimmer2 > tic ) digitalWrite(AC_LOAD2, HIGH); //управляем выходом (откроем семистор)
}

void  detect_up()  // обработка внешнего прерывания. Сработает по переднему фронту
{
  tic = 200;           //обнулить счетчик
  Timer1.resume();   //запустить таймер
  attachInterrupt(0, detect_down, HIGH);  //перепрограммировать прерывание на другой обработчик
}

void  detect_down()  // обработка внешнего прерывания. Сработает по заднему фронту
{
  Timer1.stop(); //остановить таймер
  digitalWrite(AC_LOAD2, HIGH);
  tic = 200;     //обнулить счетчик
  attachInterrupt(0, detect_up, LOW); //перепрограммировать прерывание на другой обработчик

}

void loop() {
  {
    for (int  p = 0; p < 200; p++)
    {
      Dimmer2 = p;
      delay(5);
    }
  }
} 

 

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

Везде.
Особенно в том месте, где должно плавно выключаться.

Неправильно вообще всё.

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

Rankle. вы код #25 пробовали?

и еще вопрос - вы что диммировать пытаетесь?

Rankle
Offline
Зарегистрирован: 31.10.2020

Kakmyc пишет:
Везде. Особенно в том месте, где должно плавно выключаться. Неправильно вообще всё.

Вы забыли ещё ногами постучать по полу. Детский сад, её богу. Везде и всё тут.

Rankle
Offline
Зарегистрирован: 31.10.2020

b707 пишет:

Rankle. вы код #25 пробовали?

и еще вопрос - вы что диммировать пытаетесь?

Я писал ранее (#36) , что пытаюсь диммировать лампу накаливания. Обычную. Отечественную. С цоколем E27 на 60 Ватт.

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

Rankle пишет:

Вы забыли ещё ногами постучать по полу. Детский сад, её богу. Везде и всё тут.

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

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

Rankle пишет:

Я писал ранее (#36) , что пытаюсь диммировать лампу накаливания. Обычную. Отечественную. С цоколем E27 на 60 Ватт.

а что про #25 молчите? Вы этот код пробовали7

Rankle
Offline
Зарегистрирован: 31.10.2020

b707 пишет:

Rankle пишет:

Я писал ранее (#36) , что пытаюсь диммировать лампу накаливания. Обычную. Отечественную. С цоколем E27 на 60 Ватт.

а что про #25 молчите? Вы этот код пробовали7

b707 Я вчера с утра сразу же попробовал его "внедрив" в свою программу. Моргал ещё как.

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

Сейчас запустил "как есть". Работает. правда в конце затухания небольшой "минус", но теперь я с ним сам разберусь. Знаете я до этого думал что нельзя пользоваться delay в прерываниях attachinterrupt. Я не предполагал что в прерываниях таймера это можно. Теперь буду добавлять в свой код условия что бы всё заработало на 100%.

b707 спасибо большое за помощь и терпение

 

 

Rankle
Offline
Зарегистрирован: 31.10.2020

Kakmyc][quote=Rankle пишет:

...... Не вижу смысла вам помогать абсолютно.

 

Да и ладно. Это сразу было понятно.

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

Rankle пишет:

Знаете я до этого думал что нельзя пользоваться delay в прерываниях attachinterrupt. Я не предполагал что в прерываниях таймера это можно.

Функцию delay() нельзя использовать в прерываниях, а вот delayMicroseconds() - можно. А какое прерывание - таймера или attachinterrupt - значения не имеет.

Дим-мычъ
Offline
Зарегистрирован: 20.03.2021

b707 пишет:

Функцию delay() нельзя использовать в прерываниях, а вот delayMicroseconds() - можно. А какое прерывание - таймера или attachinterrupt - значения не имеет.

Весьма ценное ( для меня, как для новичка)  замечание. Ещё бы знать почему?

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

Дим-мычъ пишет:

Весьма ценное ( для меня, как для новичка)  замечание. Ещё бы знать почему?

Ну наверное потому, что прерывания не работают внутри прерываний.