如何修改Arduino RGB LED代码消除绿色,实现黄至红渐变?
解决Arduino RGB LED黄到红渐变出现绿色的问题及优化代码
问题根源分析
你的代码出现绿色及异常颜色的核心原因有4点:
- RGB数组赋值不完整:
hsi_to_rgb函数计算出r、g、b后,仅将b存入rgb[2],r和g完全未写入数组,导致这两个通道使用随机垃圾值输出。 - 红色通道未被控制:
setColor函数仅操作了greenPin和bluePin,完全漏掉了redPin,红色通道根本未工作。 - 色相范围错误:循环遍历0-360全色相,会经过绿色(120°左右)等无关颜色,而黄到红的色相区间仅为60°(黄色)到0°(红色)。
- 共阳LED反转不完整:共阳LED需反转所有通道的PWM值,但你仅处理了green和blue,红色通道未反转。
修复后的完整代码
int redPin = 9; int greenPin = 10; int bluePin = 11; #define COMMON_ANODE void setup() { pinMode(redPin, OUTPUT); pinMode(greenPin, OUTPUT); pinMode(bluePin, OUTPUT); } int rgb[3]; // HSI转RGB函数修复版 void hsi_to_rgb(float H, float S, float I) { int r, g, b; H = fmod(H, 360); // 确保色相在0-360范围内 H = 3.14159 * H / 180.0; // 转换为弧度 // 饱和度和亮度 clamp 到0-1区间 S = constrain(S, 0.0, 1.0); I = constrain(I, 0.0, 1.0); if (H < 2.09439) { // 0°-120°区间(红-黄-绿) r = 255 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H)); g = 255 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H))); b = 255 * I / 3 * (1 - S); } else if (H < 4.188787) { // 120°-240°区间(绿-青-蓝) H -= 2.09439; g = 255 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H)); b = 255 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H))); r = 255 * I / 3 * (1 - S); } else { // 240°-360°区间(蓝-紫-红) H -= 4.188787; b = 255 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H)); r = 255 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H))); g = 255 * I / 3 * (1 - S); } // 修复:将计算结果存入RGB数组 rgb[0] = constrain(r, 0, 255); rgb[1] = constrain(g, 0, 255); rgb[2] = constrain(b, 0, 255); } // 修复后的颜色设置函数 void setColor(int red, int green, int blue) { #ifdef COMMON_ANODE red = 255 - red; green = 255 - green; blue = 255 - blue; #endif analogWrite(redPin, red); analogWrite(greenPin, green); analogWrite(bluePin, blue); } void loop() { // 仅在黄(60°)到红(0°)的色相区间渐变 for (int h = 60; h >= 0; h--) { hsi_to_rgb(h, 1, 1); setColor(rgb[0], rgb[1], rgb[2]); delay(20); } }
更简洁的优化方案(无需HSI转换)
黄到红的渐变本质是红色保持最大值,绿色从255线性降到0,蓝色始终为0,直接用线性变化实现更高效,代码更简洁:
int redPin = 9; int greenPin = 10; int bluePin = 11; #define COMMON_ANODE void setup() { pinMode(redPin, OUTPUT); pinMode(greenPin, OUTPUT); pinMode(bluePin, OUTPUT); } void setColor(int red, int green, int blue) { #ifdef COMMON_ANODE red = 255 - red; green = 255 - green; blue = 255 - blue; #endif analogWrite(redPin, red); analogWrite(greenPin, green); analogWrite(bluePin, blue); } void loop() { // 绿色从255降到0,红色保持255,蓝色0 for (int greenVal = 255; greenVal >= 0; greenVal--) { setColor(255, greenVal, 0); delay(20); } }
内容的提问来源于stack exchange,提问作者Igne
相关产品推荐
相关产品推荐

