Управление светодиодами WS2812B с помощью ШИМ
- Войдите на сайт для отправки комментариев
Втр, 30/11/2021 - 10:33
Всем привет, имеется 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); }
Это "цифровые" светодиоды и у них есть свой контроллер со своим ШИМ. Что вы от них хотите добиться ???
Мне нужно управлять этими светодиодами удаленно, с помощью пульта радиоуправления. К ардуино нано на d3 подключен приемник который может выдавать PWM сигнал. Хочу с помощью него управлять включением и отключением светодиодов (сигнала на d5).
Ага, т.е. при помощи ШИМ Вы управляете ардуиной (извне), а у она управляет светодиодами по обычной схеме, как положено. Я правильно Вас понял?
Ага, т.е. при помощи ШИМ Вы управляете ардуиной (извне), а у она управляет светодиодами по обычной схеме, как положено. Я правильно Вас понял?
Да, все верно
чё то ты там намудрил, смотри, тут я принимаю два канала PWM и всё работает
Возможно ли это сделать как то параллельно
ХЗ. Смотря как у Вас реализовано управление адресными светодиодами. Я, например, часто делаю это с запрещёнными прерываниями, чтобы тайминги не сбивались. Там очень жёсткие и короткие тайминги и их нельзя обижать. Потому в то время, когда я вывожу информацию на ленту, никакого ШИМа читать нельзя. Если мне нужно что-то читать, я специально организую паузы между выводом пачки данных на ленту и в эти паузы читаю.
Если мне нужно что-то читать, я специально организую паузы между выводом пачки данных на ленту и в эти паузы читаю.
какой длительности?
ХЗ. Смотря как у Вас реализовано управление адресными светодиодами.
Весь код скетча здесь. Я делал в FLProg, т.к. слабо разбираюсь в программировании на С и для меня было непросто сделать даже текущий вариант :)
ну, в каждом проекте по своему, от много зависит.
В крайнем проекте, там так. Частота обновления ленты установлена 60Гц. Т.е. каждые 16667 микросекунд я начинаю обновлять ленту. Это занимает какое-то время (не помню точно, но сильно меньше периода), а все остальное время (до начала нового обновления) используется для других дел, в частности и для изменения массива из которого в следующий раз будет обновляться лента.
Весь код скетча здесь. Я делал в FLProg, т.к. слабо разбираюсь в программировании на С и для меня было непросто сделать даже текущий вариант :)
Ничего не могу сказать, т.к. слабо разбираюсь (вернее, совсем не разбираюсь) в FLProg :-(
В крайнем проекте, там так. Частота обновления ленты установлена 60Гц. Т.е. каждые 16667 микросекунд я начинаю обновлять ленту. Это занимает какое-то время (не помню точно, но сильно меньше периода), а все остальное время (до начала нового обновления) используется для других дел, в частности и для изменения массива из которого в следующий раз будет обновляться лента.
Спасибо, стало понятнее, что в целом двигался в правильном направлении, наверное мне нужно уменьшать период опроса ШИМ, чтобы прерывание было менее заметным.
Весь код скетча здесь. Я делал в FLProg, т.к. слабо разбираюсь в программировании на С и для меня было непросто сделать даже текущий вариант :)
Ничего не могу сказать, т.к. слабо разбираюсь (вернее, совсем не разбираюсь) в FLProg :-(
я тоже не разбираюсь, но строки 92 и 93 меня сильно озадачили, разве так можно?
Чтение PWM с использованием микрос совсем простое:
я тоже не разбираюсь, но строки 92 и 93 меня сильно озадачили, разве так можно?
а это где такое? - строчки эти вижу, но в коде ТС они под другими номерами и не подряд
Чтение PWM с использованием микрос совсем простое:
нет, еще проще - pulsein
Чтение PWM с использованием микрос совсем простое:
Спасибо за пример с функцией micros. А как теперь привязать переменную rc1_data к определенному PWM входу, например D3 в моем случае?
Чтение PWM с использованием микрос совсем простое:
нет, еще проще - pulsein
я эту функцию не смотрел, но навряд ли используемое в ней прерывание будет выше INT0 и INT1 если оно вообще используется
Чтение PWM с использованием микрос совсем простое:
нет, еще проще - pulsein
я эту функцию не смотрел, но навряд ли используемое в ней прерывание будет выше INT0 и INT1 если оно вообще используется
Нет, не используется. И не нужно. И если хочешь задействовать аппаратные ресурсы, то это делается на сраным прерыванием и micros(), а таймером.
Нет, не используется. И не нужно. И если хочешь задействовать аппаратные ресурсы, то это делается на сраным прерыванием и micros(), а таймером.
есть у меня и на таймере, данке шон ЕвгенийП, точность там заоблачная получается, но оно тут не нужно
Ох, я наверное уже надоел, но теперь у меня проблема что в вашем коде переменная которой присвается флаг после считывания PWM с D3 int, а у меня объявлена bool "_gtv3"
Как мне теперь увязать ваш код с моей переменной? А то ведь придется весь код перетряхивать(
надо всё переписывать полностью, ваш код не исправить (практически)
надо всё переписывать полностью, ваш код не исправить (практически)
Понял, примерно так и думал. Спасибо, буду пробовать