• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Мерцание лампы от AC Light Dimmer Module

nikolz

Well-known member
у меня нет такого модуля, поэтому отладить могу на ESP8266 и на СИ.
 

petran67

New member
попробуйте распечатать переменные T,T1,D1,D2:

Код:
#include "CyberLib.h" //Библиотека от Cyber-Place.ru
volatile uint32_t  T,T1,D1,D2;
#define DT 10 //длительность импульса
#define Tdet 10000     //длительность импульса 100 Гц
#define Tdet2 Tdet/2    // половина длительность  100 Гц

void setup()
{
    D5_Out; D6_Out; //Настраиваем порты на выход
    D2_In; //настраиваем порт на вход для отслеживания прохождения сигнала через ноль
    pinMode(A0, INPUT);
    pinMode(A1, INPUT);
    T=micros();
    attachInterrupt(0,detect,RISING); // настроить срабатывание прерывания interrupt0 на pin 2  по положительному фронту
    UART_Init(115200); //инициализация порта
}
void loop()
{
    D5_Low; D6_Low;
    T1=micros()-T;
             ardprintf(" %d %d %d %d ", T,T1,D1,D2);

     if (T1>0 && T1<Tdet)   //контроль длительности импульса детектора
     {
       if (D1-T1)>0) { D5_High; delayMicroseconds(DT);D1=0;}
       if (D2-T1)>0) { D6_High; delayMicroseconds(DT);D2=0;}
       }
}
void detect() // обработка внешнего прерывания
{
   if (T1>Tdet2)  //фильтр дребезга перехода
{ T=micros();
D1=map(analogRead(0), 0, 1023, 255, 0); // Эти входы для потенциометров
D2= map(analogRead(1), 0, 1023, 255, 0);
}
}
error: 'ardprintf' was not declared in this scope

ardprintf(" %d %d %d %d ", T,T1,D1,D2);

^~~~~~~~~
Или я не понимаю что подразумевается под словом "распечатать переменные"? ((
 

nikolz

Well-known member
error: 'ardprintf' was not declared in this scope

ardprintf(" %d %d %d %d ", T,T1,D1,D2);

^~~~~~~~~
Или я не понимаю что подразумевается под словом "распечатать переменные"? ((
искал в ардуине эквивалент os_printf с форматом, нашел этот.
Но очевидно из другой библиотеки
Поставьте как знаете распечатку этих переменных
------------------
Еще обратил внимание, что у вас вроде бы алгоритм в скетче не соответствует схеме.
Вы схему и скетч сами написали или взяли готовую?
 

nikolz

Well-known member
вы делаете управление на две лампочки. Верно?
Для отладки сделайте на одну а потом добавьте сколько угодно.
 

nikolz

Well-known member
посмотрите внимательно это

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


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

petran67

New member
Еще обратил внимание, что у вас вроде бы алгоритм в скетче не соответствует схеме.
Вы схему и скетч сами написали или взяли готовую?
Я частично брал готовый скетч но на один канал и с управлением по серийному порту. Немножко поиздевался над ним как мог, попутно лазя по форумам. То что получилось - получилось. Все работает, да вот, мерцает немножко, что бьет по глазам и нервам.
 

petran67

New member
Но вы по его окончанию останавливаете таймер.
По-моему здесь ошибка. проверьте логику .
На сколько я понял, вместо "void detect_down() // обработка внешнего прерывания. Сработает по заднему фронту " надо поменять на стабильную длительность импульса в 10 мс и тогда остановка таймера.
Только вот какими магическими байками ему указывать это? Может кто в курсе магии Nano?
 

nikolz

Well-known member
На сколько я понял, вместо "void detect_down() // обработка внешнего прерывания. Сработает по заднему фронту " надо поменять на стабильную длительность импульса в 10 мс и тогда остановка таймера.
Только вот какими магическими байками ему указывать это? Может кто в курсе магии Nano?
нет не то.
вот еще вариант более простой ,без прерываний И таймера
надо вставить чтение pin2.
Код:
#include "CyberLib.h" //Библиотека от Cyber-Place.ru
volatile uint32_t  T,T1,D1,D2,s;
volatile uint8  s,s1;       // s - сигнал pin2
#define DT 10 //длительность импульса
#define Tdet 10000     //длительность импульса 100 Гц
#define Tdet2 Tdet/2    // половина длительность  100 Гц

void setup()
{
    D5_Out; D6_Out; //Настраиваем порты на выход
    D2_In; //настраиваем порт на вход для отслеживания прохождения сигнала через ноль
    pinMode(A0, INPUT);    pinMode(A1, INPUT);
    T=micros();  s=0; s1=0;
    UART_Init(115200); //инициализация порта
}
void loop()
{    D5_Low; D6_Low;
     T1=micros()-T;
    if ((T1>0) && (T1<Tdet))   //контроль длительности импульса детектора
     {
       if ((D1-T1)>0) { D5_High; delayMicroseconds(DT);D1=0;}
       if ((D2-T1)>0) { D6_High; delayMicroseconds(DT);D2=0;}
       }
     s=...  //читаем  сигнал с pin2 в s   -- надо добавить чтение пина
    if ((s==1) && (s1==0)) {
        T=micros();
        D1 = map(analogRead(0), 0, 1023, 255, 0);
        D2 = map(analogRead(1), 0, 1023, 255, 0);
    }
  s1=s;
}
 

nikolz

Well-known member
Не понял. Так там же и есть указан Pin2 на чтение перехода нуля. Что-то еще надо ему прикручивать?
вот тут
s=... //читаем сигнал с pin2 в s -- надо добавить чтение пина
надо написать присвоение s значения pin2
------------------
В исходном варианте функции чтения pin2 нет, так как там для этого используется прерывание
---------------------
что касается вашего варианта с таймером то он работать не будет
У вас схема нуля работает по полупериодам и импульс , пауза по отдельности всегда будут меньше 10 мс так как их сумма равна 10 мс.
Поэтому прерывание должно работать по одному фронту, можно любому Только в этом случае интервал прерывания будет 10 мс.
 

nikolz

Well-known member
Дело ясное что дело темное. Надо искать форум по Nano.
Спасибо огромное вам за попытку разрешить вопрос.
попробуйте этот вариант:
Код:
#include "CyberLib.h" //Библиотека от Cyber-Place.ru
volatile uint32_t tic, Dimmer1, Dimmer2;

void setup()
{
D5_Out; D6_Out; //Настраиваем порты на выход
D2_In; //настраиваем порт на вход для отслеживания прохождения сигнала через ноль
pinMode(A0, INPUT);
pinMode(A1, INPUT);
attachInterrupt(0, detect_up, LOW); // настроить срабатывание прерывания interrupt0 на pin 2 на низкий уровень
UART_Init(115200); //инициализация порта
}
void loop()
{
    D5_Low; D6_Low;
    uint32_t T1=micros()-tic;
       if ((Dimmer1-T1)>0) { D5_High; delayMicroseconds(100);Dimmer1 =0;}
       if ((Dimmer2-T1)>0) { D6_High; delayMicroseconds(100);Dimmer2 =0;}
}
//********************обработчики прерываний*******************************
void detect_up()
{ 
attachInterrupt(0, detect_down, HIGH); //перепрограммировать прерывание на другой обработчик
}
void detect_down() // обработка внешнего прерывания. Сработает по заднему фронту
{
  tic=micros();
    Dimmer1= map(analogRead(0), 0, 1023, 255, 0); // Эти входы для потенциометров
    Dimmer2 = map(analogRead(1), 0, 1023, 255, 0); }
attachInterrupt(0, detect_up, LOW); //перепрограммировать прерывание на другой обработчик
}
 

nikolz

Well-known member
и еще
причина почему у Вас может не работать предыдущий скетч - это малое значение Dimmer1 и Dimmer2.
они задаются в микросекундах т е максимум это 10000.
Для начала задайте их 5000 (половина диапазона)
например так:

void detect_down() // обработка внешнего прерывания. Сработает по заднему фронту
{
tic=micros();
Dimmer1= 5000; // Эти входы для потенциометров
Dimmer2 = 5000;
attachInterrupt(0, detect_up, LOW); //перепрограммировать прерывание на другой обработчик
}
 

nikolz

Well-known member
вариант с учетом диапазона изменений Dimmer
--------------------
Код:
#include "CyberLib.h" //Библиотека от Cyber-Place.ru
volatile uint16 tic, Dimmer1, Dimmer2;
void setup()
{
D5_Out; D6_Out; //Настраиваем порты на выход
D2_In; //настраиваем порт на вход для отслеживания прохождения сигнала через ноль
pinMode(A0, INPUT);
pinMode(A1, INPUT);
attachInterrupt(0, detect,High); // настроить прерывание interrupt0 на pin 2 на высокий уровень
UART_Init(115200); //инициализация порта
}
void loop()
{
    D5_Low; D6_Low;
    uint16 T1=micros()-tic;  
  digitalWrite(ledPin, val);     // устанавливаем значение на све
       if ((Dimmer1-T1)>0) { D5_High; delayMicroseconds(50);Dimmer1 =0;}
       if ((Dimmer2-T1)>0) { D6_High; delayMicroseconds(50);Dimmer2 =0;}
}
//********************обработчики прерываний*******************************
void detect() // обработка внешнего прерывания.
{
  tic=micros();
    Dimmer1= map(analogRead(0), 0,1023,50,9800); // Эти входы для потенциометров
    Dimmer2 = map(analogRead(1), 0,1023,50,9800);
}
 

nikolz

Well-known member
убрал лишнее:

Код:
Код:
#include "CyberLib.h" //Библиотека от Cyber-Place.ru
volatile uint16 tic, Dimmer1, Dimmer2;
void setup()
{
D5_Out; D6_Out; //Настраиваем порты на выход
D2_In; //настраиваем порт на вход для отслеживания прохождения сигнала через ноль
pinMode(A0, INPUT);
pinMode(A1, INPUT);
attachInterrupt(0, detect,High); // настроить прерывание interrupt0 на pin 2 на высокий уровень
UART_Init(115200); //инициализация порта
}
void loop()
{   D5_Low; D6_Low;
    uint16 T1=micros()-tic; 
    if (T1>0) {
       if ((Dimmer1-T1)>0) { D5_High; delayMicroseconds(50);Dimmer1 =0;}
       if ((Dimmer2-T1)>0) { D6_High; delayMicroseconds(50);Dimmer2 =0;}
       }
}
//********************обработчики прерываний*******************************
void detect() // обработка внешнего прерывания.
{
  tic=micros();
    Dimmer1= map(analogRead(0), 0,1023,50,9800); // Эти входы для потенциометров
    Dimmer2 = map(analogRead(1), 0,1023,50,9800);
}
 

nikolz

Well-known member
совсем короткий вариант:
Код:
#include "CyberLib.h" //Библиотека от Cyber-Place.ru
volatile uint16 tic, Dimmer1, Dimmer2;
void setup()
{
D5_Out; D6_Out; //Настраиваем порты на выход
D2_In;              //настраиваем порт на вход для отслеживания прохождения сигнала через ноль
pinMode(A0, INPUT); pinMode(A1, INPUT);
attachInterrupt(0, detect,High); // interrupt0 на pin 2 на высокий уровень
UART_Init(115200);               //инициализация порта
}
void loop()
{    D5_Low; D6_Low;
    tic++;
    if ((Dimmer1-tic)>0) { D5_High; Dimmer1 =0;}
    if ((Dimmer2-tic)>0) { D6_High; Dimmer2 =0;}
            }
}
//********************обработчики прерываний*******************************
void detect()
{  tic=0; Dimmer1=analogRead(0); Dimmer2=analogRead(1);  }
 

nikolz

Well-known member
совсем смешной диммер:

Код:
#include "CyberLib.h" //Библиотека от Cyber-Place.ru
volatile uint16 Dimmer1, Dimmer2;
void setup()
{
D5_Out; D6_Out; //Настраиваем порты на выход
D2_In; //настраиваем порт на вход для отслеживания прохождения сигнала через ноль
pinMode(A0, INPUT); pinMode(A1, INPUT);
attachInterrupt(0, detect,High); // настроить срабатывание прерывания interrupt0 на pin 2 на высокий уровень
UART_Init(115200); //инициализация порта
}
void loop()
{    D5_Low; D6_Low;
    if ((Dimmer1--)==0) D5_High;
    if ((Dimmer2--)==0) D6_High;
}
//********************обработчики прерываний*******************************
void detect()
{ Dimmer1=analogRead(0)+5; Dimmer2=analogRead(1)+5; }
 

petran67

New member
совсем смешной диммер:

Код:
#include "CyberLib.h" //Библиотека от Cyber-Place.ru
volatile uint16 Dimmer1, Dimmer2;
void setup()
{
D5_Out; D6_Out; //Настраиваем порты на выход
D2_In; //настраиваем порт на вход для отслеживания прохождения сигнала через ноль
pinMode(A0, INPUT); pinMode(A1, INPUT);
attachInterrupt(0, detect,High); // настроить срабатывание прерывания interrupt0 на pin 2 на высокий уровень
UART_Init(115200); //инициализация порта
}
void loop()
{    D5_Low; D6_Low;
    if ((Dimmer1--)==0) D5_High;
    if ((Dimmer2--)==0) D6_High;
}
//********************обработчики прерываний*******************************
void detect()
{ Dimmer1=analogRead(0)+5; Dimmer2=analogRead(1)+5; }
error: 'uint16' does not name a type; did you mean 'uint16_t'?
volatile uint16 Dimmer1, Dimmer2;
^~~~~~
uint16_t
________________________________________________________________________
 
Сверху Снизу