Управление светодиодами WS2812B с помощью ШИМ

TrueMuMa
Offline
Зарегистрирован: 30.11.2021

Всем привет, имеется arduino nano и требуется управлять светодиодами по ШИМ. Управляющий сигнал на светодиоды выводится через D5, а считывание PWM происходит на контакте D3. Проблема в том, что не удается заставить работать оба входа одновременно. Когда работает подсветка, PWM не считывается. Пришлось реализовать программное прерывание: каждые 3 секунды запускается считывание PWM и при определенном значении PWM подсветка потом гаснет.

Возможно ли это сделать как то параллельно, чтобы подсветка работала постоянно и не ожидала пока считается сигнал PWM?

//считывание PWM и выполнение условия включения ленты
    if (_gtv5 == 0) 
    {
        _gtv3 = (_SCT_1_PDON) < (1000);
    }
//переключения между считыванием PWM и включением LED
    if (!(0)) 
    {
        if (! _gen3I) 
        {
            _gen3I = 1;
            _gen3O = 1;
            _gen3P =  millis();
        }
    }
     else 
    {
        _gen3I = 0 ;
        _gen3O= 0;
    }
     if (_gen3I) 
    {
         if (_gen3O) 
        {
             if (_isTimer(_gen3P , 3000)) 
            {
                 _gen3P = millis();
                _gen3O = 0;
            }
        }
         else  
        {
             if (_isTimer(_gen3P , 2000)) 
            {
                  _gen3P = millis();
                _gen3O = 1;
            }
        }
    }
    _gtv5 = _gen3O;
    if (_gen3O) 
    {
         if (_trgrt1I) 
        {
             _trgrt1 = 0;
        }
         else 
        {
            _trgrt1 = 1;
            _trgrt1I = 1;
        }
    }
     else 
    {
        _trgrt1 = 0;
        _trgrt1I = 0;
    }
    ;
    _gtv34 = _trgrt1;
}
bool _isTimer(unsigned long startTime, unsigned long period)
{
    unsigned long currentTime;
    currentTime = millis();
    if (currentTime>= startTime) 
    {
        return (currentTime>=(startTime + period));
    }
     else 
    {
        return (currentTime >=(4294967295-startTime+period));
    }
}
bool _isTimerMicros(unsigned long startTime, unsigned long period)
{
    unsigned long currentTime;
    currentTime = micros();
    if (currentTime>= startTime) 
    {
        return (currentTime>=(startTime + period));
    }
     else 
    {
        return (currentTime >=(4294967295-startTime+period));
    }
}
void  _SCT_1coutFunction()
{
    if(!(0)) 
    {
        _SCT_1_PDON= (micros()) - _SCT_1_PDTT;
    }
    attachInterrupt(digitalPinToInterrupt (3), _SCT_1positiveCoutFunction, RISING);
}
void  _SCT_1positiveCoutFunction()
{
    _SCT_1_PDTT= micros();
    attachInterrupt(digitalPinToInterrupt (3), _SCT_1coutFunction, FALLING);
}

 

Komandir
Offline
Зарегистрирован: 18.08.2018

Это "цифровые" светодиоды и у них есть свой контроллер со своим ШИМ. Что вы от них хотите добиться ???

TrueMuMa
Offline
Зарегистрирован: 30.11.2021

Мне нужно управлять этими светодиодами удаленно, с помощью пульта радиоуправления. К ардуино нано на d3 подключен приемник который может выдавать PWM сигнал. Хочу с помощью него управлять включением и отключением светодиодов (сигнала на d5).

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

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

TrueMuMa
Offline
Зарегистрирован: 30.11.2021

ЕвгенийП пишет:

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

Да, все верно

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

чё то ты там намудрил, смотри, тут я принимаю два канала PWM и всё работает

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

TrueMuMa пишет:

Возможно ли это сделать как то параллельно

ХЗ. Смотря как у Вас реализовано управление адресными светодиодами. Я, например, часто делаю это с запрещёнными прерываниями, чтобы тайминги не сбивались. Там очень жёсткие и короткие тайминги и их нельзя обижать. Потому в то время, когда я вывожу информацию на ленту, никакого ШИМа читать нельзя. Если мне нужно что-то читать, я специально организую паузы между выводом пачки данных на ленту и в эти паузы читаю.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

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

какой длительности?

TrueMuMa
Offline
Зарегистрирован: 30.11.2021

ЕвгенийП пишет:

ХЗ. Смотря как у Вас реализовано управление адресными светодиодами. 

Весь код скетча здесь. Я делал в FLProg, т.к. слабо разбираюсь в программировании на С и для меня было непросто сделать даже текущий вариант :)

#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel pixels= Adafruit_NeoPixel(70 ,   5 , NEO_GRB + NEO_KHZ800); //first number change does distance between colors
bool en_151307670_9;
int num_led_151307670_9;
int led_1r_151307670_9;
int led_1g_151307670_9;
int led_1b_151307670_9;
bool en_151307670_34;
int num_led_151307670_34;
int led_1r_151307670_34;
int led_1g_151307670_34;
int led_1b_151307670_34;
bool en_151307670_35;
int num_led_151307670_35;
int led_1r_151307670_35;
int led_1g_151307670_35;
int led_1b_151307670_35;
bool en_151307670_1;
int num_led_151307670_1;
int led_1r_151307670_1;
int led_1g_151307670_1;
int led_1b_151307670_1;
bool en_151307670_2;
int num_led_151307670_2;
int led_1r_151307670_2;
int led_1g_151307670_2;
int led_1b_151307670_2;
bool en_151307670_3;
int num_led_151307670_3;
int led_1r_151307670_3;
int led_1g_151307670_3;
int led_1b_151307670_3;
bool en_151307670_4;
int num_led_151307670_4;
int led_1r_151307670_4;
int led_1g_151307670_4;
int led_1b_151307670_4;
bool en_151307670_5;
int num_led_151307670_5;
int led_1r_151307670_5;
int led_1g_151307670_5;
int led_1b_151307670_5;
bool en_151307670_6;
int num_led_151307670_6;
int led_1r_151307670_6;
int led_1g_151307670_6;
int led_1b_151307670_6;
bool en_151307670_7;
int num_led_151307670_7;
int led_1r_151307670_7;
int led_1g_151307670_7;
int led_1b_151307670_7;
bool en_151307670_8;
int num_led_151307670_8;
int led_1r_151307670_8;
int led_1g_151307670_8;
int led_1b_151307670_8;
bool en_151307670_81;
int num_led_151307670_81;
int led_1r_151307670_81;
int led_1g_151307670_81;
int led_1b_151307670_81;
bool en_151307670_82;
int num_led_151307670_82;
int led_1r_151307670_82;
int led_1g_151307670_82;
int led_1b_151307670_82;
bool _gtv3;
bool _gtv5;
bool _gtv34;
int _gtv35;
bool _gen2I = 0;
bool _gen2O = 0;
unsigned long _gen2P = 0UL;
bool _gen1I = 0;
bool _gen1O = 0;
unsigned long _gen1P = 0UL;
bool _trgrt1 = 0;
bool _trgrt1I = 0;
unsigned long _SCT_1_PDTT = 0UL;
unsigned long _SCT_1_PDON = 0UL;
bool _count2I = 0;
int _count2_Value = 0;
bool _count1I = 0;
int _count1_Value = 0;
bool _gen3I = 0;
bool _gen3O = 0;
unsigned long _gen3P = 0UL;
void setup()
{
    pinMode(3, INPUT);
    attachInterrupt(digitalPinToInterrupt (3), _SCT_1coutFunction, FALLING);
    attachInterrupt(digitalPinToInterrupt (3), _SCT_1positiveCoutFunction, RISING);
    pixels.begin();
    pixels.show(); // Устанавливаем все светодиоды в состояние "Выключено"
    pixels.show(); // Устанавливаем все светодиоды в состояние "Выключено"
      pixels.show(); // Устанавливаем все светодиоды в состояние "Выключено"
      pixels.show(); // Устанавливаем все светодиоды в состояние "Выключено"
      pixels.show(); // Устанавливаем все светодиоды в состояние "Выключено"
      pixels.show(); // Устанавливаем все светодиоды в состояние "Выключено"
      pixels.show(); // Устанавливаем все светодиоды в состояние "Выключено"
      pixels.show(); // Устанавливаем все светодиоды в состояние "Выключено"
      pixels.show(); // Устанавливаем все светодиоды в состояние "Выключено"
      pixels.show(); // Устанавливаем все светодиоды в состояние "Выключено"
      pixels.show(); // Устанавливаем все светодиоды в состояние "Выключено"
      pixels.show(); // Устанавливаем все светодиоды в состояние "Выключено"
      pixels.show(); // Устанавливаем все светодиоды в состояние "Выключено"
      pixels.show(); // Устанавливаем все светодиоды в состояние "Выключено"
}
void loop()
{
    //Плата:1
//Наименование:Инициализация подсветки
    if (_gtv5 == 1) 
    {
    }
    //Плата:2
//Наименование:Счетчик для бегущей волны
    if (_gtv5 == 1) 
    {
        if (_gtv3) 
        {
             if (! _gen2I) 
            {
                _gen2I = 1;
                _gen2O = 1;
                _gen2P = micros();
            }
        }
         else 
        {
            _gen2I = 0 ;
            _gen2O= 0;
        }
        if (_gen2I) 
        {
              if (_isTimerMicros (_gen2P , 1)) 
            {
                 _gen2P = micros();
                _gen2O = ! _gen2O;
            }
        }
        if (_gtv34)
        {
            _count2_Value = 0;
        }
         else 
        {
            if (_gen2O)
            {
                if (! _count2I) 
                {
                    _count2I = 1;
                    _count2_Value = _count2_Value + 1;
                }
            }
             else 
            {
                _count2I = 0;
            }
        }
        _gtv35 = _count2_Value;
        if (!(_gtv3)) 
        {
             if (! _gen1I) 
            {
                _gen1I = 1;
                _gen1O = 1;
                _gen1P = millis();
            }
        }
         else 
        {
            _gen1I = 0 ;
            _gen1O= 0;
        }
        if (_gen1I) 
        {
              if (_isTimer (_gen1P , 1)) 
            {
                 _gen1P = millis();
                _gen1O = ! _gen1O;
            }
        }
        if (_gtv34)
        {
            _count1_Value = 0;
        }
         else 
        {
            if (_gen1O)
            {
                if (! _count1I) 
                {
                    _count1I = 1;
                    _count1_Value = _count1_Value + 1;
                }
            }
             else 
            {
                _count1I = 0;
            }
        }
        en_151307670_9 = _gen1O;
        num_led_151307670_9 = _count1_Value;
        led_1r_151307670_9 = 0;
        led_1g_151307670_9 = 0;
        led_1b_151307670_9 = 0;
        if (en_151307670_9   == 1)
        {
            pixels.setPixelColor(num_led_151307670_9 -1, pixels.Color(led_1r_151307670_9  ,  led_1g_151307670_9  ,  led_1b_151307670_9));
            pixels.show();
        }
        else
        {
            pixels.setPixelColor(num_led_151307670_9 -1, pixels.Color(0 , 0  ,  0));
            pixels.show();
        }
        ;
    }
    //Плата:3
//Наименование:Бегущая волна
    if (_gtv5 == 1) 
    {
        en_151307670_35 = _gtv3;
        num_led_151307670_35 = (_gtv35)+(1);
        led_1r_151307670_35 = 100;
        led_1g_151307670_35 = 0;
        led_1b_151307670_35 = 0;
        if (en_151307670_35   == 1)
        {
            pixels.setPixelColor(num_led_151307670_35 -1, pixels.Color(led_1r_151307670_35  ,  led_1g_151307670_35  ,  led_1b_151307670_35));
            pixels.show();
        }
        else
        {
            pixels.setPixelColor(num_led_151307670_35 -1, pixels.Color(0 , 0  ,  0));
            pixels.show();
        }
        ;
        en_151307670_2 = _gtv3;
        num_led_151307670_2 = (_gtv35)+(3);
        led_1r_151307670_2 = 200;
        led_1g_151307670_2 = 0;
        led_1b_151307670_2 = 0;
        if (en_151307670_2   == 1)
        {
            pixels.setPixelColor(num_led_151307670_2 -1, pixels.Color(led_1r_151307670_2  ,  led_1g_151307670_2  ,  led_1b_151307670_2));
            pixels.show();
        }
        else
        {
            pixels.setPixelColor(num_led_151307670_2 -1, pixels.Color(0 , 0  ,  0));
            pixels.show();
        }
        ;
        en_151307670_3 = _gtv3;
        num_led_151307670_3 = (_gtv35)+(4);
        led_1r_151307670_3 = 255;
        led_1g_151307670_3 = 0;
        led_1b_151307670_3 = 0;
        if (en_151307670_3   == 1)
        {
            pixels.setPixelColor(num_led_151307670_3 -1, pixels.Color(led_1r_151307670_3  ,  led_1g_151307670_3  ,  led_1b_151307670_3));
            pixels.show();
        }
        else
        {
            pixels.setPixelColor(num_led_151307670_3 -1, pixels.Color(0 , 0  ,  0));
            pixels.show();
        }
        ;
        en_151307670_1 = _gtv3;
        num_led_151307670_1 = (_gtv35)+(2);
        led_1r_151307670_1 = 150;
        led_1g_151307670_1 = 0;
        led_1b_151307670_1 = 0;
        if (en_151307670_1   == 1)
        {
            pixels.setPixelColor(num_led_151307670_1 -1, pixels.Color(led_1r_151307670_1  ,  led_1g_151307670_1  ,  led_1b_151307670_1));
            pixels.show();
        }
        else
        {
            pixels.setPixelColor(num_led_151307670_1 -1, pixels.Color(0 , 0  ,  0));
            pixels.show();
        }
        ;
        en_151307670_34 = _gtv3;
        num_led_151307670_34 = _gtv35;
        led_1r_151307670_34 = 10;
        led_1g_151307670_34 = 0;
        led_1b_151307670_34 = 0;
        if (en_151307670_34   == 1)
        {
            pixels.setPixelColor(num_led_151307670_34 -1, pixels.Color(led_1r_151307670_34  ,  led_1g_151307670_34  ,  led_1b_151307670_34));
            pixels.show();
        }
        else
        {
            pixels.setPixelColor(num_led_151307670_34 -1, pixels.Color(0 , 0  ,  0));
            pixels.show();
        }
        ;
        en_151307670_81 = (_gtv35) == (2);
        num_led_151307670_81 = 69;
        led_1r_151307670_81 = 255;
        led_1g_151307670_81 = 255;
        led_1b_151307670_81 = 255;
        if (en_151307670_81   == 1)
        {
            pixels.setPixelColor(num_led_151307670_81 -1, pixels.Color(led_1r_151307670_81  ,  led_1g_151307670_81  ,  led_1b_151307670_81));
            pixels.show();
        }
        else
        {
            pixels.setPixelColor(num_led_151307670_81 -1, pixels.Color(0 , 0  ,  0));
            pixels.show();
        }
        ;
        en_151307670_4 = _gtv3;
        num_led_151307670_4 = (_gtv35)+(10);
        led_1r_151307670_4 = 10;
        led_1g_151307670_4 = 0;
        led_1b_151307670_4 = 0;
        if (en_151307670_4   == 1)
        {
            pixels.setPixelColor(num_led_151307670_4 -1, pixels.Color(led_1r_151307670_4  ,  led_1g_151307670_4  ,  led_1b_151307670_4));
            pixels.show();
        }
        else
        {
            pixels.setPixelColor(num_led_151307670_4 -1, pixels.Color(0 , 0  ,  0));
            pixels.show();
        }
        ;
        en_151307670_6 = _gtv3;
        num_led_151307670_6 = (_gtv35)+(7);
        led_1r_151307670_6 = 150;
        led_1g_151307670_6 = 0;
        led_1b_151307670_6 = 0;
        if (en_151307670_6   == 1)
        {
            pixels.setPixelColor(num_led_151307670_6 -1, pixels.Color(led_1r_151307670_6  ,  led_1g_151307670_6  ,  led_1b_151307670_6));
            pixels.show();
        }
        else
        {
            pixels.setPixelColor(num_led_151307670_6 -1, pixels.Color(0 , 0  ,  0));
            pixels.show();
        }
        ;
        en_151307670_8 = _gtv3;
        num_led_151307670_8 = (_gtv35)+(5);
        led_1r_151307670_8 = 255;
        led_1g_151307670_8 = 0;
        led_1b_151307670_8 = 0;
        if (en_151307670_8   == 1)
        {
            pixels.setPixelColor(num_led_151307670_8 -1, pixels.Color(led_1r_151307670_8  ,  led_1g_151307670_8  ,  led_1b_151307670_8));
            pixels.show();
        }
        else
        {
            pixels.setPixelColor(num_led_151307670_8 -1, pixels.Color(0 , 0  ,  0));
            pixels.show();
        }
        ;
        en_151307670_82 = (_gtv35) == (2);
        num_led_151307670_82 = 70;
        led_1r_151307670_82 = 255;
        led_1g_151307670_82 = 255;
        led_1b_151307670_82 = 255;
        if (en_151307670_82   == 1)
        {
            pixels.setPixelColor(num_led_151307670_82 -1, pixels.Color(led_1r_151307670_82  ,  led_1g_151307670_82  ,  led_1b_151307670_82));
            pixels.show();
        }
        else
        {
            pixels.setPixelColor(num_led_151307670_82 -1, pixels.Color(0 , 0  ,  0));
            pixels.show();
        }
        ;
        en_151307670_7 = _gtv3;
        num_led_151307670_7 = (_gtv35)+(6);
        led_1r_151307670_7 = 200;
        led_1g_151307670_7 = 0;
        led_1b_151307670_7 = 0;
        if (en_151307670_7   == 1)
        {
            pixels.setPixelColor(num_led_151307670_7 -1, pixels.Color(led_1r_151307670_7  ,  led_1g_151307670_7  ,  led_1b_151307670_7));
            pixels.show();
        }
        else
        {
            pixels.setPixelColor(num_led_151307670_7 -1, pixels.Color(0 , 0  ,  0));
            pixels.show();
        }
        ;
        en_151307670_5 = _gtv3;
        num_led_151307670_5 = (_gtv35)+(8);
        led_1r_151307670_5 = 100;
        led_1g_151307670_5 = 0;
        led_1b_151307670_5 = 0;
        if (en_151307670_5   == 1)
        {
            pixels.setPixelColor(num_led_151307670_5 -1, pixels.Color(led_1r_151307670_5  ,  led_1g_151307670_5  ,  led_1b_151307670_5));
            pixels.show();
        }
        else
        {
            pixels.setPixelColor(num_led_151307670_5 -1, pixels.Color(0 , 0  ,  0));
            pixels.show();
        }
        ;
    }
    //Плата:4
//Наименование:Блок считывания PWM и выполнение условия включения ленты
    if (_gtv5 == 0) 
    {
        _gtv3 = (_SCT_1_PDON) < (1000);
    }
    //Плата:5
//Наименование:Блок переключения между считыванием PWM и включением LED
    if (!(0)) 
    {
        if (! _gen3I) 
        {
            _gen3I = 1;
            _gen3O = 1;
            _gen3P =  millis();
        }
    }
     else 
    {
        _gen3I = 0 ;
        _gen3O= 0;
    }
     if (_gen3I) 
    {
         if (_gen3O) 
        {
             if (_isTimer(_gen3P , 3000)) 
            {
                 _gen3P = millis();
                _gen3O = 0;
            }
        }
         else  
        {
             if (_isTimer(_gen3P , 2000)) 
            {
                  _gen3P = millis();
                _gen3O = 1;
            }
        }
    }
    _gtv5 = _gen3O;
    if (_gen3O) 
    {
         if (_trgrt1I) 
        {
             _trgrt1 = 0;
        }
         else 
        {
            _trgrt1 = 1;
            _trgrt1I = 1;
        }
    }
     else 
    {
        _trgrt1 = 0;
        _trgrt1I = 0;
    }
    ;
    _gtv34 = _trgrt1;
}
bool _isTimer(unsigned long startTime, unsigned long period)
{
    unsigned long currentTime;
    currentTime = millis();
    if (currentTime>= startTime) 
    {
        return (currentTime>=(startTime + period));
    }
     else 
    {
        return (currentTime >=(4294967295-startTime+period));
    }
}
bool _isTimerMicros(unsigned long startTime, unsigned long period)
{
    unsigned long currentTime;
    currentTime = micros();
    if (currentTime>= startTime) 
    {
        return (currentTime>=(startTime + period));
    }
     else 
    {
        return (currentTime >=(4294967295-startTime+period));
    }
}
void  _SCT_1coutFunction()
{
    if(!(0)) 
    {
        _SCT_1_PDON= (micros()) - _SCT_1_PDTT;
    }
    attachInterrupt(digitalPinToInterrupt (3), _SCT_1positiveCoutFunction, RISING);
}
void  _SCT_1positiveCoutFunction()
{
    _SCT_1_PDTT= micros();
    attachInterrupt(digitalPinToInterrupt (3), _SCT_1coutFunction, FALLING);
}

 

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

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

В крайнем проекте, там так. Частота обновления ленты установлена 60Гц. Т.е. каждые 16667 микросекунд я начинаю обновлять ленту. Это занимает какое-то время (не помню точно, но сильно меньше периода), а все остальное время (до начала нового обновления) используется для других дел, в частности и для изменения массива из которого в следующий раз будет обновляться лента.

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

TrueMuMa пишет:

Весь код скетча здесь. Я делал в FLProg, т.к. слабо разбираюсь в программировании на С и для меня было непросто сделать даже текущий вариант :)

Ничего не могу сказать, т.к. слабо разбираюсь (вернее, совсем не разбираюсь) в FLProg :-(

TrueMuMa
Offline
Зарегистрирован: 30.11.2021

ЕвгенийП пишет:

В крайнем проекте, там так. Частота обновления ленты установлена 60Гц. Т.е. каждые 16667 микросекунд я начинаю обновлять ленту. Это занимает какое-то время (не помню точно, но сильно меньше периода), а все остальное время (до начала нового обновления) используется для других дел, в частности и для изменения массива из которого в следующий раз будет обновляться лента.

 

Спасибо, стало понятнее, что в целом двигался в правильном направлении, наверное мне нужно уменьшать период опроса ШИМ, чтобы прерывание было менее заметным.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

TrueMuMa пишет:

Весь код скетча здесь. Я делал в FLProg, т.к. слабо разбираюсь в программировании на С и для меня было непросто сделать даже текущий вариант :)

Ничего не могу сказать, т.к. слабо разбираюсь (вернее, совсем не разбираюсь) в FLProg :-(

я тоже не разбираюсь, но строки 92 и 93 меня сильно озадачили, разве так можно?

  attachInterrupt(digitalPinToInterrupt (3), _SCT_1coutFunction, FALLING);
  attachInterrupt(digitalPinToInterrupt (3), _SCT_1positiveCoutFunction, RISING);
  

 

Чтение PWM с использованием микрос совсем простое:
 

volatile unsigned int rc1_data = 0; // значение PWM полученное с приёмника
volatile unsigned long start_timeRC1 = 0; 
volatile unsigned long prevTime;
volatile byte flag_RC1 = 0;

/*******Обработчик прерывания (чтение PWM) *******/
void Rc1() {
  if (digitalRead(2) == HIGH && flag_RC1 == 0) {
    //сохраняем значение времени начала импульса
    start_timeRC1 = micros();
    flag_RC1 = 1;
  }
  if (digitalRead(2) == LOW && flag_RC1 == 1) {
    //сохраняем значение длительности импульса канала 1
    rc1_data = micros() - start_timeRC1;
    flag_RC1 = 0;
  }
  
}//END RC1

void setup() {
  attachInterrupt(0, Rc1, CHANGE);

}

void loop() {

}

 

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

ua6em пишет:

я тоже не разбираюсь, но строки 92 и 93 меня сильно озадачили, разве так можно?

  attachInterrupt(digitalPinToInterrupt (3), _SCT_1coutFunction, FALLING);
  attachInterrupt(digitalPinToInterrupt (3), _SCT_1positiveCoutFunction, RISING);

а это где такое? - строчки эти вижу, но в коде ТС они под другими номерами и не подряд

rkit
Онлайн
Зарегистрирован: 23.11.2016

ua6em пишет:

Чтение PWM с использованием микрос совсем простое:

нет, еще проще - pulsein

TrueMuMa
Offline
Зарегистрирован: 30.11.2021

ua6em пишет:

Чтение PWM с использованием микрос совсем простое:

volatile unsigned int rc1_data = 0; // значение PWM полученное с приёмника
volatile unsigned long start_timeRC1 = 0; 
volatile unsigned long prevTime;
volatile byte flag_RC1 = 0;

/*******Обработчик прерывания (чтение PWM) *******/
void Rc1() {
  if (digitalRead(2) == HIGH && flag_RC1 == 0) {
    //сохраняем значение времени начала импульса
    start_timeRC1 = micros();
    flag_RC1 = 1;
  }
  if (digitalRead(2) == LOW && flag_RC1 == 1) {
    //сохраняем значение длительности импульса канала 1
    rc1_data = micros() - start_timeRC1;
    flag_RC1 = 0;
  }
  
}//END RC1

void setup() {
  attachInterrupt(0, Rc1, CHANGE);

}

void loop() {

}

 

 

Спасибо за пример с функцией micros. А как теперь привязать переменную rc1_data к определенному PWM входу, например D3 в моем случае?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016
volatile unsigned int rc1_data = 0; // значение PWM полученное с приёмника
volatile unsigned long start_timeRC1 = 0; 
volatile unsigned long prevTime;
volatile byte flag_RC1 = 0;

/*******Обработчик прерывания (чтение PWM) *******/
void Rc1() {
  if (digitalRead(3) == HIGH && flag_RC1 == 0) {
    //сохраняем значение времени начала импульса
    start_timeRC1 = micros();
    flag_RC1 = 1;
  }
  if (digitalRead(3) == LOW && flag_RC1 == 1) {
    //сохраняем значение длительности импульса канала 1
    rc1_data = micros() - start_timeRC1;
    flag_RC1 = 0;
  }
  
}//END RC1

void setup() {
  attachInterrupt(1, Rc1, CHANGE);

}

void loop() {

}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

rkit пишет:

ua6em пишет:

 

Чтение PWM с использованием микрос совсем простое:

 

нет, еще проще - pulsein

я эту функцию не смотрел, но навряд ли используемое в ней прерывание будет выше INT0 и INT1 если оно вообще используется

rkit
Онлайн
Зарегистрирован: 23.11.2016

ua6em пишет:

rkit пишет:

ua6em пишет:

 

Чтение PWM с использованием микрос совсем простое:

 

нет, еще проще - pulsein

я эту функцию не смотрел, но навряд ли используемое в ней прерывание будет выше INT0 и INT1 если оно вообще используется

Нет, не используется. И не нужно. И если хочешь задействовать аппаратные ресурсы, то это делается на сраным прерыванием и micros(), а таймером.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

rkit пишет:

Нет, не используется. И не нужно. И если хочешь задействовать аппаратные ресурсы, то это делается на сраным прерыванием и micros(), а таймером.

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

TrueMuMa
Offline
Зарегистрирован: 30.11.2021

Ох, я наверное уже надоел, но теперь у меня проблема что в вашем коде переменная которой присвается флаг после считывания PWM с D3 int, а у меня объявлена bool "_gtv3"

//Считывание PWM и выполнение условия включения ленты
    if (_gtv5 == 0) 
    {
        _gtv3 = (_SCT_1_PDON) < (1000);

Как мне теперь увязать ваш код с моей переменной? А то ведь придется весь код перетряхивать(

volatile unsigned int rc1_data = 0; // значение PWM полученное с приёмника
volatile unsigned long start_timeRC1 = 0; 
volatile unsigned long prevTime;
volatile byte flag_RC1 = 0;

/*******Обработчик прерывания (чтение PWM) *******/
void Rc1() {
  if (digitalRead(3) == HIGH && flag_RC1 == 0) {
    //сохраняем значение времени начала импульса
    start_timeRC1 = micros();
    flag_RC1 = 1;
  }
  if (digitalRead(3) == LOW && flag_RC1 == 1) {
    //сохраняем значение длительности импульса канала 1
    rc1_data = micros() - start_timeRC1;
    flag_RC1 = 0;
  }
  
}//END RC1

void setup() {
  attachInterrupt(1, Rc1, CHANGE);

}

void loop() {

}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

надо всё переписывать полностью, ваш код не исправить (практически)

TrueMuMa
Offline
Зарегистрирован: 30.11.2021

ua6em пишет:

надо всё переписывать полностью, ваш код не исправить (практически)

Понял, примерно так и думал. Спасибо, буду пробовать