ШИМ не изменяется плавно
- Войдите на сайт для отправки комментариев
Всем привет.
Я тут делаю управляемый LED RGB контроллер на дуине. Сначала я использовал для этого вот такой контроллер с соответсвующей библиотекой:
https://ru.aliexpress.com/item/Full-Color-RGB-LED-Strip-Driver-Module-Sh...
С ним кусок 2 метра ленты работает хорошо, цвета меняются плавно и всё ок. Но его мощности недостаточно, чтобы управлять более чем 10 метрами ленты 5050, поэтому я взял другой, устроенный попроще, но расчитанный на 8А на канал. Вот этот:
https://ru.aliexpress.com/item/DC12-24V-24A-Led-RGBW-Strip-Amplifier-6A-...
Здесь внутри всё просто: 3 опторазвязки и 3 мосфета с обвязкой. По факту переплата только за корпус. Тут в коде все проще, используется ШИМ Ардуины. Использую почти тот же код, что и для прошлого варианта, но сам вывод просто через AnalogWrite.
В чем проблема: лента не меняет цвета плавно. Цвета сменяются раз в 2-3 секунды, как и должно, но это происходит резко, а должно быть плавно. Если логгировать вывод R, G и B компонентов через AnalogWrite, то там плавно меняющиеся значения от 0 до 255, как и должно быть. В чем может быть дело?
Вот код:
int pinR = A1;
int pinG = A2;
int pinB = A3;
int hue, saturation, brightness;
int colors[7] = {0, 64, 96, 128, 160, 192, 224};
#define NUM_COLORS 7
void setup() {
delay(2000);
Serial.begin(9600);
pinMode(pinR, OUTPUT);
pinMode(pinG, OUTPUT);
pinMode(pinB, OUTPUT);
hue = 0;
saturation = 0;
brightness = 0;
}
void loop() {
if (brightness < 100){
brightness+=1;
delay(10);
}
else if (saturation < 100){
saturation+=1;
delay(10);
}
else {
if (Contains(colors, hue))
delay(2000);
hue+=1;
if (hue > 360) hue = 0;
delay(10);
}
Serial.print("Setting color: ");
Serial.println(hue, DEC);
WriteHSVtoStrip(hue, saturation, brightness);
}
void WriteHSVtoStrip(float h, float s, float v)
{
int i, r, g ,b;
float f,p,q,t;
h = max(0.0, min(360.0, h));
s = max(0.0, min(100.0, s));
v = max(0.0, min(100.0, v));
s /= 100;
v /= 100;
if(s == 0) {
// Achromatic (grey)
r = g = b = round(v*255);
return;
}
h /= 60; // sector 0 to 5
i = floor(h);
f = h - i; // factorial part of h
p = v * (1 - s);
q = v * (1 - s * f);
t = v * (1 - s * (1 - f));
switch(i) {
case 0:
r = round(255*v);
g = round(255*t);
b = round(255*p);
break;
case 1:
r = round(255*q);
g = round(255*v);
b = round(255*p);
break;
case 2:
r = round(255*p);
g = round(255*v);
b = round(255*t);
break;
case 3:
r = round(255*p);
g = round(255*q);
b = round(255*v);
break;
case 4:
r = round(255*t);
g = round(255*p);
b = round(255*v);
break;
default: // case 5:
r = round(255*v);
g = round(255*p);
b = round(255*q);
}
analogWrite(pinR, 255 - r);
analogWrite(pinG, 255 - g);
analogWrite(pinB, 255 - b);
}
boolean Contains(int arr[], int element) {
for (int i = 0; i < NUM_COLORS; i++) {
if (arr[i] == element) {
return true;
}
}
return false;
}
В каком месте ты прочитал о том, что контакты А1, А2 и А3 - поддерживают ШИМ?
В каком месте ты прочитал о том, что контакты А1, А2 и А3 - поддерживают ШИМ?
о_О Ну я подумал, A - Analog :) Или это работает только для входа?
Проклятье! Так они не поддерживают ШИМ?! Если так, то спасибо! Попробую перепаять схему.
Vaskrol, разработчики Ардуино пытались сделать все так, чтобы было понятно новичкам.
В пезультате, не новичкам - совершенно непонятно.
И, как показывает практика, новичкам - тоже.
Нет в Ардуино аналоговых выводов на выход. Совсем.
Почему назвали функцию analogWrite() - см. выше.
Так что не стоит слишком доверять названиям, лучше справиться в документации.
Тем более, разработчики контроллеров (в отличие от разработчиков Ардуино) поступают вполне логично - различные дополнительные возможности раскидывают по разным пинам. В частности - чтобы избежать конфликтов: если бы ШИМ был только на "аналоговых" выводах, невозможно было бы сделать на Уно более трех пар аналоговый вход - "аналоговый" выход. А так - целых 6.
Спасибо. Перевесил на 3, 5 и 6 пины и всё работает.