Алгоритм Брезенхема без привязки с ZeroCross

Известен механизм управления мощностью по Брезенхему (на Форуме обсуждался не раз), обеспечивающий пропуск нужного количество полупериодов (в лампу, ТЭН…) с достаточно равномерной последовательностью. Как правило, его исполнение привязывалось к моменту перехода переменного напряжения через ноль. То есть, посредством строки “attachInterrupt (X,OutPWR, CHANGE);” по прерыванию запускается функция void OutPWR (), в которой код

//тип переменных pwr - int, er- int, reg- int, out- boolean
void OutPWR()
{
   reg = pwr + er; //pwr- задание выходной мощности в %, er- ошибка округления
   if (reg < 50)
   {
     out=0;
     er = reg ; // reg- переменная для расчетов
   }
   else
   {
    out=1;
    er=reg-100;
   }
   digitalWrite(13,out);//пин через который осуществляется дискретное управление
}

выполняет регулируемую подачу мощности. Код НЕ МОЙ, я его спёр на Форуме! А если делать то же самое, не используя аппаратное прерывания, а с определенной частотой, например, посредством millis()?
Понятно, что в случае отслеживания процесса по zerocross при переходе напряжения через 0 исполняющий симистор самостоятельно закроется и откроется, если на то будет соответствующая команда перед следующим полупериодом. А вот как его закрыть принудительно в случае использования таймера? Сломал голову (увы, пока еще слабую для программирования)…

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

Да, он закроется, но при ПЕРВОМ же переходе через ноль. То есть, максимум через 10 мс. А если мне надо, чтобы он был открыт в течение всего периода таймера (например, 30 мс), а в конце закрылся?

Нужно, чтобы управляющий сигнал был всё это время

Если я правильно понял, мы имеем некий период таймера, в начале которого (по команде вышеприведенного кода) пишем на управляющем пине либо HIGH либо LOW. B тем самым, выполняем алгоритм Брезенхема не по аппаратному прерыванию, а просто с частотой таймера?

И он открывает симистор как попало и на сколько электробогу угодно.

Садман, извини, не понял. Это ирония или предположение о работе? Если последнее, то надо развернуть мысль.

Извините, подзабыл Брезенхема, не скажу, но оптосимисторы с zerocross легко доступны

Индикатор перехода напряжения через ноль - это лишняя плата с лишними деталями. Весь ее смак в том, что она позволяет работать с частотой 100 Гц. Но это в практическом плане не дает никаких преимуществ, поэтом проще программно привязаться к времени, в на к самой сети. Други, опишу процесс, как его вижу. Если где капкан, поправьте.
При срабатывании таймера (да хоть на millis()) сначала определяем по вышеприведенному коду надо или не надо “зажигать” управляющий пин, и, соответственно, туда HIGH либо LOW. Как мне кажется, должно работать. Но встает вопрос: насколько этот коротенький код шустрый в смысле времени? От этого зависит период таймера.

digitalWrite() замените на прямое управление - будет шустрым

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

Не только. Открывать симистор лучше короткими импульсами в начале каждого полупериода. Закроется он сам.

Плохо. Любой софтверный “таймер”:

  1. нестабилен;
  2. никак не связан с окружающей средой.

В итоге имеем: в один полупериод открылись на 50%, во второй на 90%, в третий дернулись сразу после зерокросса. И в чем тут выигрыш?

1 лайк

Точного закрытия симистора по времени не будет, т.к. если надо , по таймеру закрывать, а до нуля ещё далеко, ничего не поделаешь.(без заморочек). Чтобы этого избежать, можно, вместо симистора использовать транзистор (MОСФЕТ). Если нагрузка невелика, zerocross необязателен.

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

Не спится старому пню…

//UNO
// Объявление пинов исполнения
int pin_heater=8;   //ТЭН
// Объявление переменных нагрева
int heater_time=17;      //Интервал переключения нагрева
long heater_previous;    //Время последнего переключения нагрева
boolean heater_status;   //Состояние нагрева
// Объявление переменных Брезенхема
int heater_power=34;     //% мощности нагрева
int heater_error;       //Ошибка округления
int heater_reg;         //ПGеременная для расчета

void setup() 
{   
  pinMode (pin_heater, OUTPUT);
}

void loop() 
{
  unsigned long heater_current = millis();
  //Проверяем не прошел ли нужный интервал, если прошел то
  if(heater_current - heater_previous > heater_time) 
  {
    //Cохраняем время последнего переключения
    heater_previous = heater_current; 
    //Определяем надобность включить ТЭН
    heater_reg = heater_power + heater_error;
    if (heater_reg < 50)
    {
      heater_status=0;
      heater_error=heater_reg;
    }
    else
    {
      heater_status=1;
      heater_error=heater_reg-100;
    }
    digitalWrite(pin_heater,heater_status);
  }
}    

Время переключения взял 17 мсек, чтобы не было уж сильно кратно полупериоду напряжения сети. В нагрузке - пока лампочка. Пробовал с разными показателями процентной доли мощности (heater_power) от 0 до 100. Светит с достаточно равномерным (на глаз, конечно) мерцанием. В выходные проверю на мощном ТЭНе ваттметром.

Что то я не догнал идею. Что преследуется в конечном итоге?

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

А насчет рандомайза я и не подумал! Хорошая идея, проверю и ее. Считать эффективность (я тоже не математик), думаю, следует попроще. Для этого существует секундомер и электросчетчик (или ваттметр, он тоже считает “съеденную” электроэнергию). В общем, отчитаюсь.

как уже сказано

т.е. понятны какие фичи вылезут от такого управления, непонятно, а к чему же это может привести в конечном итого.

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

зы2. причем если взять для управления симистором МОС с ZeroCross, тогда останется только неточность ± полупериод в каждом интервале включения.