Официальный сайт компании Arduino по адресу arduino.cc
ШИМ не изменяется плавно
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Всем привет.
Я тут делаю управляемый 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 пины и всё работает.