Многоканальный независимый диммер переменного тока с использованием Arduino

Я хочу построить 8-канальный диммер переменного тока с независимым управлением с помощью Arduino. Я успешно протестировал одноканальный диммер, но я застрял в расширении его до 8 каналов. Схема, которую я имею в виду, приведена ниже.схема одноканального диммера

Код Arduino, который я использую, приведен ниже.

/*
AC Voltage dimmer with Zero cross detection
Author: Charith Fernanado http://www.inmojo.com
License: Creative Commons Attribution Share-Alike 3.0 License. 

Attach the Zero cross pin of the module to Arduino External Interrupt pin
Select the correct Interrupt # from the below table:
(the Pin numbers are digital pins, NOT physical pins:
digital pin 2 [INT0]=physical pin 4 
and digital pin 3 [INT1]= physical pin 5)

 Pin    |  Interrrupt # | Arduino Platform
 ---------------------------------------
 2      |  0            |  All
 3      |  1            |  All
 18     |  5            |  Arduino Mega Only
 19     |  4            |  Arduino Mega Only
 20     |  3            |  Arduino Mega Only
 21     |  2            |  Arduino Mega Only

In the program pin 2 is chosen
 */

int AC_LOAD = 3;    // Output to Opto Triac pin
int dimming = 128;  // Dimming level (0-128)  0 = ON, 128 = OFF
/* Due to timing problems, the use of ‘0’ can sometimes make the circuit 
flicker. It is safer to use a value slightly higher than ‘0’
*/
void setup()
{
  pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
  attachInterrupt(0, zero_crosss_int, RISING);  
// Chooses '0' as interrupt for the zero-crossing
}
// the interrupt function must take no parameters and return nothing
void zero_crosss_int()  
// function to be fired at the zero crossing to dim the light
{
  // Firing angle calculation : 1 full 50Hz wave =1/50=20ms  
  // Every zerocrossing thus: (50Hz)-> 10ms (1/2 Cycle) For 60Hz => 8.33ms

  // 10ms=10000us
  // (10000us - 10us) / 128 = 75 (Approx) For 60Hz =>65
  int dimtime = (75*dimming);    // For 60Hz =>65     
  delayMicroseconds(dimtime);    // Off cycle
  digitalWrite(AC_LOAD, HIGH);   // triac firing
  delayMicroseconds(10);         // triac On propogation delay
                                 //(for 60Hz use 8.33)
  digitalWrite(AC_LOAD, LOW);    // triac Off
}
void loop()  {
 for (int i=5; i <= 128; i++)
{
 dimming=i;
 delay(10);
 }
 }

Любые идеи о том, как я могу расширить код и схему для работы с 8 каналами, которыми можно НЕЗАВИСИМО управлять?

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

Ответы (2)

Без глубокого обзора кода проблема, скорее всего, будет здесь:

delayMicroseconds(dimtime);    // Off cycle
digitalWrite(AC_LOAD, HIGH);   // triac firing
delayMicroseconds(10);         // triac On propogation delay

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

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

  • заданное значение (значение, при котором включается выход таймера) ,
  • фактическое значение (текущее значение времени) и
  • состояние выхода (сработал таймер или нет).

Более простой способ может быть:

  • Разделите свой полупериод на дискретное количество шагов, скажем, 50 мкс.
  • В основной цикл добавьте счетчик, который сбрасывается при пересечении нуля и увеличивается каждые 50 мкс.
  • В цикле сравнивайте уровень диммера для каждого канала с таймером и включайте этот канал, если уровень диммера превышен.

введите описание изображения здесь

Рисунок 1. Связь между током и углом срабатывания.

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

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

Если вы хотите использовать уже протестированную и готовую плату, используйте ее. Каждый канал управляется независимо. 8-канальный диммер переменного тока Arduino

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