ШИМ не изменяется плавно

Vaskrol
Offline
Зарегистрирован: 08.03.2018

Всем привет.

Я тут делаю управляемый 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;
}

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

В каком месте ты прочитал о том, что контакты А1, А2 и А3 - поддерживают ШИМ?

Vaskrol
Offline
Зарегистрирован: 08.03.2018

wdrakula пишет:

В каком месте ты прочитал о том, что контакты А1, А2 и А3 - поддерживают ШИМ?

о_О Ну я подумал, A - Analog :) Или это работает только для входа?

Проклятье! Так они не поддерживают ШИМ?! Если так, то спасибо! Попробую перепаять схему.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Vaskrol, разработчики Ардуино пытались сделать все так, чтобы было понятно новичкам.

В пезультате, не новичкам - совершенно непонятно.

И, как показывает практика, новичкам - тоже.

Нет в Ардуино аналоговых выводов на выход. Совсем.

Почему назвали функцию analogWrite() - см. выше.

Так что не стоит слишком доверять названиям, лучше справиться в документации.

Тем более, разработчики контроллеров (в отличие от разработчиков Ардуино) поступают вполне логично - различные дополнительные возможности раскидывают по разным пинам. В частности - чтобы избежать конфликтов: если бы ШИМ был только на "аналоговых" выводах, невозможно было бы сделать на Уно более трех пар аналоговый вход - "аналоговый" выход. А так - целых 6.

Vaskrol
Offline
Зарегистрирован: 08.03.2018

Спасибо. Перевесил на 3, 5 и 6 пины и всё работает.