Таймеры библиотеки Adafruit NeoPixel

ArhAngeL
Offline
Зарегистрирован: 06.02.2018

Добрый день.

Собрано небольшое устройство на базе Arduino Nano ATmega328P для контроля температуры, управления вентиляторами и подсветкой в системном блоке.

Вентиляторы управляются через mosfet ШИМ с 5 вывода. светодиодных лент несколько, но с ними проблем никаких. В общем то было на мой взгляд все верно рассчитано, но когда подключил к целевым вентиляторам, а не с тем, который тестировал, от частоты ШИМ они "запели". Решением было поднять частоту ШИМ добавив строку в setup:

TCCR0B = TCCR0B & 0b11111000 | 0x01;

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

Я понимаю, что неудачно выбрана нога ардуино для управления мосфетом, так как ее ШИМ завязан с таймером 0, но поменять ее уже технологически сложная задача.

Вопрос заключается в следующем: читал, что можно поменять таймер, который использует библиотека Adafruit NeoPixel. Можно ли как-то это сделать, чтобы вернуть ее функционал при поднятой частоте ШИМ на 5 и 6 выводах?

Заранее спасибо!

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

Вы уверены, что проблема в библиотеке. Точно? Кода Вы не показываете, но мне кажется, что проблема нв в библиотеке, а в том, что у Вас просто ускорился millis и соответсвенно delay. Вот всё и поплыло. Везде, где используются эти функции (или всё, что на них завязано) - всё ускорилось.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Adafruit NeoPixel в реализации AVR не использует таймер, как мне помнится. Там все на nop-ах завязано. Так что я за вариант из #1

ArhAngeL
Offline
Зарегистрирован: 06.02.2018

Спасибо за инфу и интерес к моему вопросу. Я понял, попробую увеличить время задержек millis и delay.

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

ArhAngeL пишет:

Спасибо за инфу и интерес к моему вопросу. Я понял, попробую увеличить время задержек millis и delay.

Не надо! Сейчас напишу, что надо делать ... чуть позже, а то много букв.

ArhAngeL
Offline
Зарегистрирован: 06.02.2018

Буду благодарен.

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

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

Если уж совсем нет возможности поменять пин и оставить в покое нулевой таймер, то я бы поступил так:

1. Отложил бы в сторонку это скетч, а взял бы самый простой блинк (хоть с делэем, хоть с миллисом - всё равно). Это чтобы никакие сложности не мешались.

2. В программе для блинка вставил бы Ваше изменение частоты. Проверил бы, и убедился бы, что период блинка поплыл (а куда он денется?)

3. Сделал бы копию системного файла wiring.c (для сохранности) и полез бы в него. Логика работы миллиса там вполне понятна и вся она базируется на том, что делитель у нулевого таймера - 64. Так вот, я бы поменял логику подсчёта времени в этом файле так, чтобы с Вашим новым делителем миллис считался бы корректно.

4. Тщательно проверил бы на блинке, что да - корректно считается - период блинка правильный. 

5. После этого вставил бы в основной код "жирный" комментарий, что его (код) надо компилировать только с модифицированным wiring.c и скомпилировал бы.

По идее, теперь всё должно заработать корректно где бы и кто бы не использовал миллис и делэй, т.к. они теперь работают корректно на Вашей новой частоте.

Ну, а  впредь этот изменённый wiring.c использовать для перекомпиляции этого кода (а для остальных - обычный).

ArhAngeL
Offline
Зарегистрирован: 06.02.2018

Евгений, спасибо за ответ. Сделаю именно так, отличное решение!