FastLED дышащий эффект с максимальной яркостью - PullRequest
0 голосов
/ 24 марта 2020

У меня проблема. Я управляю своим WS2812B с помощью Arduino, но у меня проблема с дыхательным эффектом. Я создал класс в коде, который выглядит следующим образом:

String breathDirection = "Down";

void breath_effect()
{
fill_solid(leds, TOTAL_LEDS, primary);
float currentBrightness = FastLED.getBrightness();

if (currentBrightness <= 1)
{
  breathDirection = "Up";
}
else if (currentBrightness >= brightness)
{
  breathDirection = "Down";
}

float brightnessCorrection = static_cast<float>(brightness) / 200;
if (breathDirection == "Down")
{
  currentBrightness = currentBrightness - brightnessCorrection;
  FastLED.setBrightness(currentBrightness);
}
else if (breathDirection == "Up")
{
  Serial.println("Binnen");
  Serial.println(currentBrightness);
  currentBrightness = currentBrightness + brightnessCorrection;
  Serial.println(currentBrightness);
  FastLED.setBrightness(currentBrightness);
}
}

Теперь эффект дыхания работает только тогда, когда переменная brightness установлена ​​на 200. Если я установлю его на другое значение ниже 200, он идет вниз, но никогда не подходит. CurrentBrightness - каждый раунд одного и того же значения. Что здесь не так?

Ответы [ 3 ]

0 голосов
/ 24 марта 2020

Лучше всего было бы написать несколько ценных примеров на бумаге и выполнить ручное прохождение вашей логики дыхания c. Некоторые проблемы, которые я увидел при первом быстром просмотре:

if (currentBrightness <= 0)  ==>    if (currentBrightness == 0) // truncate float to uint8_t

Так что здесь у нас есть только когда 0, если его 1 этот случай пропущен. Имхо логарифм c должен быть

     if (currentBrightness == 0 || brightness > currentBrightness)
      {
          breathDirection = "Up";
      } 
      else if (currentBrightness == 255 || currentBrightness >= brightness)
  ....

, здесь нет смысла использовать float, потому что порт принимает только значения от 0 до 255. Если float доставлен, обрежьте его, преобразовав его в uint8_t. Рисование диаграммы состояний помогает в такой логике. Деление на 200 обеспечивает значения <200 всегда 0 (деление int) </p>

0 голосов
/ 10 апреля 2020

Вы можете попробовать использовать функцию дыхания, которая является просто функцией волнового типа, такой как круговая волна, волна tri angular или волна Гаусса. Вот пример с волной tri angular (взятой из моего урока: Функции дыхательного светодиода Arduino ):

// RGB LED Triangle Wave Breathing LED

int led_pins[4] = {3,5,6};
int jj = 0; // 0 = red, 1 = green, 2 = blue
float smoothness_pts = 500;//larger=slower change in brightness

void setup() {
  Serial.begin(9600);
  for (int ii = 0;ii<sizeof(led_pins)/sizeof(int);ii++){
    pinMode(led_pins[ii],OUTPUT);
  }
}

void loop() {
  for (int ii=0;ii<smoothness_pts;ii++){
    float pwm_val = 255.0*(1.0 -  abs((2.0*(ii/smoothness_pts))-1.0));
    analogWrite(led_pins[jj],int(pwm_val));
    delay(5);
    Serial.println(int(pwm_val));
  }
}

Вы можете установить параметр яркости в плавающем 'pwm_val' в от 1 до 255 (здесь по умолчанию 255,0 (максимальное значение ШИМ в Arduino)). Вот полученный профиль «дыхания», распечатанный на серийный плоттер:

RGB LED Triangle Breathing Function

0 голосов
/ 24 марта 2020

Вам нужно установить глобальные переменные:

// Глобальная область действия:

const float _brightInterval = 1.0f;
const float _maxBright = 255.0f; //i'm not sure whats your max bright here
const float _minBright = 1.0f;

float _brightness = _maxBright;

И вместо строк я бы использовал состояния. Это быстрее и экономит память.

enum states
    {
        hold,
        down,
        up
    };
states _state;

, затем в l oop сделайте что-то вроде этого:

switch (_state)
    {
    case states::down:
        _brightness -= _brightInterval;
        break;
    case states::up:
        _brightness += _brightInterval;
        break;
    case states::hold:
        _brightness -= _brightInterval / 10.0f; //hold makes it go down but in a lower rate.
    default:
        break;
    }

    if (_brightness >= _maxBright)
        _state = states::hold;
    else if (_brightness <= (_maxBright - 50.0f) && _state == states::hold)
        _state = states::down;
    else if (_brightness <= _minBright)
        _state = states::up;

FastLED.setBrightness(_brightness);

Попробуйте изменить эти значения для достижения желаемого эффекта. (_MaxBright - 50.0f) во втором if, это шаг, когда он начинает ускоряться вниз. измените его на возможно (_maxBright - 10.0f)

...