Всем привет! Беда, как обычно пишла откуда не ждали Был собран контроллер света, четре канала, три-ШИМ один-ночничек (три белых светодиода теплого лампового света). И вот вдруг выяснилось, что светодиодные ленты мерцают Очень быстро выяснилось, что мерцание появляется если работают минимум две ленты и одна из них на 9ом пине. Использовал 5, 6 и 9 пины соответственно. Частота ШИМ 490 Гц, но на 5 и 6 около 1кГц. 10 и 11 заняты радиомодулем, от одного 3го толку мало. Можно ли как то безболезненно поднять частоту 9го или снизить 5 и 6го? Так же расмативал вариант аппаратного ШИМ-а, то там может возникнуть конфликт с таймерами и не заклинит ли его при исполнении основного кода (там не много, но все же). Подключенные библиотеки: #include <SPI.h> #include "nRF24L01.h" #include "RF24.h" #include <IRremote.h>
Не все библиотеки знаю, но если у Вас есть рабочий ШИМ и необходимо просто увеличить частоту, то да. Какая примерная частота нужна на 9-том, какая нужна на 5 и 6? У Вас UNO?
У меня Nano, но по сути та-же Uno. Было бы неплохо поднять на 9ом до ~980 Гц (вроде-бы точное значение на 5 и 6- 976 Гц). Ну и как резервный вариант, 5 и 6- 490 Гц, на случай, если что то закофликтует по первому таймеру. Вообще, чисто теоретически, если какая то библиотека использует тот же таймер, при изменении частоты Шим работоспособность сохранится?
Да, только в экономичной упаковке. К вечеру сделаю, мне сейчас самому надо поднять до 8Khz, надо вспомнить как делал и документацию почитать на Atmega328. Хм, если в библиотеки используется тот же таймер, то увеличение частоты ШИМ-а, на ШИМ не повлияет. Но теоретически может повлиять на библиотеки, так как увеличение частоты ШИМ-а это изменение настройки таймера.
Получить, по быстрому заданные Вами 1Khz, не удалось. Одним изменением пределителя таймера тут не отделаешься, но возможно это и не нужно. Попробуйте этот код на 4Khz, добавьте его в setup. Код (C++): cli(); // Запрещаем все прерывания. TCCR1B = TCCR1B & B11111000 | B00000010; // Устанавливаем предделитель таймера 1 к 8. sei(); // Разрешаем обратно все прерывания. А дальше работайте как и работали. UPD. Мне уже не требуется ШИМ 8Khz, попробуйте возможно данного решения хватит, но если требуется именно 1Khz пишите, продолжу разбираться.
Разобрался, вот код именно 1Khz, добавьте его в setup. Код (C++): cli(); // Запрещаем все прерывания. TCCR1A = TCCR1A & B11111100 | B00000011; TCCR1B = TCCR1B & B11111000 | B00000010; // Устанавливаем предделитель таймера 1 к 8. sei(); // Разрешаем обратно все прерывания. А дальше работайте как и работали. В плавную настройку не вникал, просто запустил ШИМ в режиме - PWM, Phase Correct, 10-bit.
Спасибо огромное! Завтра все запущу и доложу как оно полетело Такой вопросик, как вернуть все обратно, просто залить скетч без установки делителя? То есть, этот код меняет параметры на время работы или прошивает железо?
Не за что, тут все помогаю друг другу по мере сил и времени. Увы не знаю как это отразится на библиотеках. Просто удалить эти сроки из setup, да кстати код Код (C++): byte PWM_PIN = 9; int pwm_value; void setup() { pinMode(PWM_PIN, OUTPUT); Serial.begin(115200); cli(); // Запрещаем все прерывания. TCCR1A = TCCR1A & B11111100 | B00000011; TCCR1B = TCCR1B & B11111000 | B00000010; // Устанавливаем предделитель таймера 1 к 8. sei(); // Разрешаем обратно все прерывания. } void loop() { analogWrite(PWM_PIN, 40); } Код грубый, чтобы просто показать куда вставлять данную секцию. Как только зальете другой скетч или уберете данную секцию, все вернется как было. Это просто настройка таймера 1.
Изменить частоту получилось и вродебы ничего не навернулось, но вот мигание не исчезло, но стало заметно реже, где-то раз в полсекунды. Так же рассмотрел в картонную трубку, что этот канал действительно мигает, а не накладывается свет (или как там), похоже какие то помехи на мосфите. Но зато теперь понятна зависимость от частот. Попробую собрать простенький осцилограф, чтоб посмотреть что там и как, ну и накину кондеров в разных местах. Но в любом случае спасибо вам за код, весьма полезная штука.
Тогда можно увеличить значительно частоту ШИМ, примерно на 32Khz. Сегодня не доберусь до контролеров, но завтра к вечеру постараюсь.
Думаювы правы, чем больше будет разница, тем "мельче" будут "миги". Но аппаратную часть тоже нужно проверить, может где "сопля".
Это точно. Скачал pdf, инет на работе ужас, но все равно жду специалиста. Попробуйте данный код. Код (C++): cli();// Запрещаем все прерывания. TCCR1B = TCCR1B & B11111000 | B00000001; // Устанавливаем предделитель таймера 1 к 1. sei();// Разрешаем обратно все прерывания. На железе сейчас проверить не смогу, он должен дать ШИМ около 64KHz. Если он не поможет, скорее всего у Вас аппаратная проблема.
С вашей последней правкой все работает как надо, по началу немного глючило из за конденсатора (зарезал ШИМ). Ничего не мигает (хотя у меня уже в глазах и так все мигает от этих светодиодов). И, радость-радость, ни радиомодуль, ни IR приемник не пострадали.