具有最大亮度的 FastLED 呼吸效果
FastLED breathing effect with max brightness
我有问题。我正在使用 Arduino 控制我的 WS2812B,但呼吸效果有问题。我在代码中创建了一个 class,如下所示:
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 每一轮都是相同的值。
这里出了什么问题?
您需要设置全局变量:
//全局范围:
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;
然后在循环中做这样的事情:
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);
尝试更改这些值以达到您想要的效果。
第二个if中的(_maxBright - 50.0f),就是开始加速下降的那一步。将其更改为 (_maxBright - 10.0f)
最好是在纸上写一些价值示例,然后手动演练您的呼吸逻辑。我在第一眼看到的一些问题:
if (currentBrightness <= 0) ==> if (currentBrightness == 0) // truncate float to uint8_t
所以这里我们只有0的时候up,如果是1这个case就跳过了。恕我直言,逻辑必须是
if (currentBrightness == 0 || brightness > currentBrightness)
{
breathDirection = "Up";
}
else if (currentBrightness == 255 || currentBrightness >= brightness)
....
这里使用浮点数没有意义,因为端口只接受 0 到 255 之间的值。如果交付了浮点数,则通过将其转换为 uint8_t 来截断它。绘制状态图有助于这样的逻辑。除以 200 的值 < 200 始终为 0(整数除法)
你可以尝试使用呼吸函数,它只是一种波型函数,例如圆波、三角波或高斯波。这是一个三角波示例(取自我的教程:Arduino Breathing LED Functions):
// 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 上的 PWM 最大值))。这是打印到串行绘图仪的结果 'breathing' 配置文件:
我有问题。我正在使用 Arduino 控制我的 WS2812B,但呼吸效果有问题。我在代码中创建了一个 class,如下所示:
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 每一轮都是相同的值。
这里出了什么问题?
您需要设置全局变量:
//全局范围:
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;
然后在循环中做这样的事情:
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);
尝试更改这些值以达到您想要的效果。 第二个if中的(_maxBright - 50.0f),就是开始加速下降的那一步。将其更改为 (_maxBright - 10.0f)
最好是在纸上写一些价值示例,然后手动演练您的呼吸逻辑。我在第一眼看到的一些问题:
if (currentBrightness <= 0) ==> if (currentBrightness == 0) // truncate float to uint8_t
所以这里我们只有0的时候up,如果是1这个case就跳过了。恕我直言,逻辑必须是
if (currentBrightness == 0 || brightness > currentBrightness)
{
breathDirection = "Up";
}
else if (currentBrightness == 255 || currentBrightness >= brightness)
....
这里使用浮点数没有意义,因为端口只接受 0 到 255 之间的值。如果交付了浮点数,则通过将其转换为 uint8_t 来截断它。绘制状态图有助于这样的逻辑。除以 200 的值 < 200 始终为 0(整数除法)
你可以尝试使用呼吸函数,它只是一种波型函数,例如圆波、三角波或高斯波。这是一个三角波示例(取自我的教程:Arduino Breathing LED Functions):
// 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 上的 PWM 最大值))。这是打印到串行绘图仪的结果 'breathing' 配置文件: