Arduino 中的 LED 环 - 如何在 Processing IDE 到 select 颜色中制作界面
LED ring in Arduino - How to make an interface in Processing IDE to select a color
我有 2 个不同的 LED 环。 (一个有 16 个 LED,另一个有 24 个)
我想通过处理 IDE 创建一个界面,在那里我可以 select 一种颜色并将这种颜色发送到 selected 环。这是arduino代码:
#include <FastLED.h>
#define LED_PIN1 3
#define LED_PIN2 12
#define NUM_LEDS1 16
#define NUM_LEDS2 24
CRGB leds1[NUM_LEDS1];
CRGB leds2[NUM_LEDS2];
int r,g,b;
boolean state = false;
void setup() {
FastLED.addLeds<WS2812, LED_PIN1, GRB>(leds1, NUM_LEDS1);
FastLED.addLeds<WS2812, LED_PIN2, GRB>(leds2, NUM_LEDS2);
Serial.begin(9600);
}
void loop() {
String returnedInput = rgbInput();
String red = returnedInput.substring(0,3); //get 3 values like 255
String green = returnedInput.substring(4,7);
String blue = returnedInput.substring(8,11);
Serial.println(red);
Serial.println(green);
Serial.println(blue);
int r = red.toInt();
int g = green.toInt();
int b = blue.toInt();
if (Serial.available()){
char val = Serial.read();
if(val == '2') { //selects the second LED ring
if(state == false) {
state = true;
for(int i = 0 ; i < 24 ; i++ ){
leds2[i] = CRGB(r, g, b); //turn on all the LEDs on the ring to the selected color
FastLED.show();
FastLED.clear();
FastLED.show();
}}}
}}
String rgbInput() {
//prompt for input
Serial.println("ready");
while(!Serial.available()) {
//if 0, it keeps waiting for the user to enter sth.
}
String userInput = Serial.readStringUntil("\n");
return userInput;
}
我为第二个 LED 写了这个,如果我能管理这个,我会为另一个做同样的事情,但它不起作用。
这里是处理代码:
import controlP5.*; //import ControlP5 library
import processing.serial.*;
Serial port;
ControlP5 cp5; //create ControlP5 object
PFont font;
PFont font2;
color col;
Serial serialMonitor;
String prompt;
ColorPicker cp;
void setup(){ //Same as setup in arduino
size(900, 900); //Window size, (width, height)
port = new Serial(this, "COM4", 9600); //Change this to your port
cp5 = new ControlP5(this);
font = createFont ("Georgia Bold", 20);
font2 = createFont ("Georgia Bold",15);
cp = cp5.addColorPicker("PICKER")
.setPosition(500,100)
.setColorValue(color(255,128,0,128))
;
Group configGroup = cp5.addGroup("CONFIGURATION")
.setPosition(90,100)
.setWidth(150)
.setHeight(30)
.setFont(font2)
.setBackgroundColor(color(0,0))
;
cp5.addButton("PICK_ALL") // The button
.setPosition(10, 10) // x and y relative to the group
.setSize(160, 150) // (width, height)
.setFont(font)
.setGroup(configGroup) // add it to the group
;
cp5.addButton("PICK_ONE") // The button
.setPosition(10, 200) // x and y relative to the group
.setSize(160, 150) // (width, height)
.setFont(font)
.setGroup(configGroup) // add it to the group
;
}
void draw(){ //Same as loop in arduino
background(150, 0 , 150); //Background colour of window (r, g, b) or (0 to 255)
}
public void controlEvent(ControlEvent c){
if(c.isFrom(cp)){
int r = int(c.getArrayValue(0));
int g = int(c.getArrayValue(1));
int b = int(c.getArrayValue(2));
int a = int(c.getArrayValue(3));
col = color(r,g,b,a);
}
}
void keyPressed(){
while(serialMonitor.available() > 0)
{
prompt = serialMonitor.readStringUntil (10);
}
println(keyCode);
String sendColor = nf(int(red(col)),3) + "," + nf(int(green(col)),3) + "," + nf(int(blue(col)),3);
println(sendColor);
serialMonitor.write(sendColor);
}
void PICKER(){
port.write('2');
}
void PICK_ALL(){
port.write('t');
}
void PICK_ONE(){
port.write('l');
}
我不太清楚如何获取 RGB 值并在 CRGB 函数中使用它们。使用使用 3 个引脚的单个 RGB LED 时要容易得多。但是我无法将它实现到仅使用 1 个引脚的 LED 环。
这里是拾色处理界面。我可以 select 颜色,但 Arduino 上的 LED 环没有任何变化。
可靠的串行通信并非易事。理想情况下,您可以让自己的二进制通信协议设置一个字节数据包,其中 header 描述了实际有多少后续字节有数据,甚至可能是 checksum.
字符串可以帮助您入门,您使用 nf()
让数据更易于解析真是太好了。
一个潜在的陷阱可能是将一个字符串放在一起 (rgbInput()
) 和一次读取一个字符 (char val = Serial.read();
) 之间的切换。
我建议将问题分解成更小的更简单的部分,testing/debugging 每个部分,然后一次一个地将这些部分重新组合在一起以避免集成错误。
例如,主要的挑战似乎是串行通信,所以我会编写 Processing 和 Arduino 草图以确保在添加 LED 控制之前可靠地工作。
让我们选择 \n 终止字符串选项,即使它发送了一个多余的额外字符(例如 port.write("2\n");
),它也会使缓冲更简单:
- 总是缓冲直到换行
trim()
换行字符串
- 如果修剪后的字符串的长度为 1,则它是一个命令(如“2”、'l'、't'),否则它是一个颜色三元组
这是一个使用上述想法的基本 Arduino 草图(以及您的一些代码;)):
void setup() {
Serial.begin(9600);
}
void loop() {
// check if there are at least two characters to receive
if(Serial.available() > 1){
// buffer the full string until a new line character
String returnedInput = Serial.readStringUntil('\n');
// remove white space (new line char)
returnedInput.trim();
// if it's a single command
if(returnedInput.length() == 1){
char state = returnedInput.charAt(0);
switch(state){
case '2':
Serial.println("parsed 2 command");
break;
case 't':
Serial.println("parsed t command");
break;
case 'l':
Serial.println("parsed l command");
break;
default:
Serial.print("unknown state:");
Serial.println(state);
break;
}
}
// if it's a RGB triplet
else if(returnedInput.length() == 11){
String redString = returnedInput.substring(0, 3); //get 3 values like 255
String greenString = returnedInput.substring(4, 7);
String blueString = returnedInput.substring(8, 11);
int r = redString.toInt();
int g = greenString.toInt();
int b = blueString.toInt();
// constrain values to bytes
r = constrain(r, 0, 255);
g = constrain(g, 0, 255);
b = constrain(b, 0, 255);
// do something with the values (e.g. store globally, etc.)
Serial.print("parsed RGB: #");
Serial.print(r, HEX);
Serial.print(g, HEX);
Serial.print(b, HEX);
Serial.println();
}
// otherwise error message ?
else{
Serial.print("Uknown command: ");
Serial.println(returnedInput);
}
}
}
这应该处理带有新行终止符的字符串消息,并根据修剪后的长度解析单个字符命令和 11 个字符的 RRR、GGG、BBB 字符串。
可以直接用Arduino的Serial Monitor测试
在您的 Processing sketch 中,不清楚为什么有两个串行端口(port
和 serialMonitor
)。
这里是您的 Processing sketch 的一个稍微修改的版本,它发送几个单字符命令或颜色字符串:
import controlP5.*; //import ControlP5 library
import processing.serial.*;
PFont font;
PFont font2;
// Arduino serial port
Serial port;
// colour picker values to send to Arduino
int r;
int g;
int b;
// GUI variables
ControlP5 cp5; //create ControlP5 object
ColorPicker cp;
void setup() { //Same as setup in arduino
size(900, 900); //Window size, (width, height)
try {
port = new Serial(this, "/dev/tty.usbserial-A104WS3R", 9600); //Change this to your port
// buffer until new line: this plugs in nicely with serialEvent()
port.bufferUntil('\n');
}catch(Exception e) {
println("error opening serial");
e.printStackTrace();
}
cp5 = new ControlP5(this);
font = createFont ("Georgia Bold", 20);
font2 = createFont ("Georgia Bold", 15);
cp = cp5.addColorPicker("PICKER")
.setPosition(500, 100)
.setColorValue(color(255, 128, 0, 128))
;
Group configGroup = cp5.addGroup("CONFIGURATION")
.setPosition(90, 100)
.setWidth(150)
.setHeight(30)
.setFont(font2)
.setBackgroundColor(color(0, 0))
;
cp5.addButton("PICK_ALL") // The button
.setPosition(10, 10) // x and y relative to the group
.setSize(160, 150) // (width, height)
.setFont(font)
.setGroup(configGroup) // add it to the group
;
cp5.addButton("PICK_ONE") // The button
.setPosition(10, 200) // x and y relative to the group
.setSize(160, 150) // (width, height)
.setFont(font)
.setGroup(configGroup) // add it to the group
;
}
void draw() { //Same as loop in arduino
background(150, 0, 150); //Background colour of window (r, g, b) or (0 to 255)
}
public void controlEvent(ControlEvent c) {
if (c.isFrom(cp)) {
r = int(c.getArrayValue(0));
g = int(c.getArrayValue(1));
b = int(c.getArrayValue(2));
}
}
void keyPressed() {
if(port == null){
println("no serial, ignoring");
return;
}
String sendColor = nf(r, 3) + "," + nf(g, 3) + "," + nf(b, 3) + '\n';
println("sending to Arduino:", sendColor);
port.write(sendColor);
}
void PICKER() {
println("PICKER");
if (port != null) port.write("2\n");
}
void PICK_ALL() {
println("PICK_ALL");
if (port != null) port.write("t\n");
}
void PICK_ONE() {
println("PICK_ONE");
if (port != null) port.write("l\n");
}
void serialEvent(Serial s){
println("from Arduino:", s.readString());
}
总体注意错误检查位:使用 Serial 时总是一个好主意 :)
一旦按预期工作,您就可以组合 FastLED
控件。
这里有一个建议:
#include <FastLED.h>
#define LED_PIN1 3
#define LED_PIN2 12
#define NUM_LEDS1 16
#define NUM_LEDS2 24
CRGB leds1[NUM_LEDS1];
CRGB leds2[NUM_LEDS2];
// ring 1 color
int r1,g1,b1;
// ring 2 color
int r2,g2,b2;
// toggle wether to update r1,g1,b1 or r2,g2,b2 when a new colour arrives
boolean updateRing1 = true;
void setup() {
// setup serial
Serial.begin(9600);
// setup LEDs
FastLED.addLeds<WS2812, LED_PIN1, GRB>(leds1, NUM_LEDS1);
FastLED.addLeds<WS2812, LED_PIN2, GRB>(leds2, NUM_LEDS2);
}
void loop() {
handleSerial();
driveLEDRings();
}
void handleSerial(){
// check if there are at least two characters to receive
if(Serial.available() > 1){
// buffer the full string until a new line character
String returnedInput = Serial.readStringUntil('\n');
// remove white space (new line char)
returnedInput.trim();
// if it's a single command
if(returnedInput.length() == 1){
char state = returnedInput.charAt(0);
switch(state){
case '2':
Serial.println(F("parsed 2 command"));
break;
case 't':
Serial.println(F("parsed t command: switching to ring #1"));
updateRing1 = true;
break;
case 'l':
Serial.println(F("parsed l command: switching to ring #2"));
updateRing1 = false;
break;
default:
Serial.print(F("unknown state:"));
Serial.println(state);
break;
}
}
// if it's a RGB triplet
else if(returnedInput.length() == 11){
String redString = returnedInput.substring(0, 3); //get 3 values like 255
String greenString = returnedInput.substring(4, 7);
String blueString = returnedInput.substring(8, 11);
int r = redString.toInt();
int g = greenString.toInt();
int b = blueString.toInt();
// constrain values to bytes
r = constrain(r, 0, 255);
g = constrain(g, 0, 255);
b = constrain(b, 0, 255);
// do something with the values (e.g. store globally, etc.)
Serial.print(F("parsed RGB: #"));
Serial.print(r, HEX);
Serial.print(g, HEX);
Serial.print(b, HEX);
Serial.println();
// handle ring colour update
if(updateRing1){
r1 = r;
g1 = g;
b1 = b;
}else{
r2 = r;
g2 = g;
b2 = b;
}
}
// otherwise error message ?
else{
Serial.print("Uknown command: ");
Serial.println(returnedInput);
}
}
}
void driveLEDRings(){
//update ring 1
for(int i = 0 ; i < NUM_LEDS1; i++){
leds1[i] = CRGB(r1, g1, b1);
}
//update ring 2
for(int i = 0 ; i < NUM_LEDS2; i++){
leds2[i] = CRGB(r2, g2, b2);
}
// display
FastLED.show();
}
注意:以上代码未使用有线 RGB LED 进行测试,因此它可能无法正常工作,但希望它能说明这个想法。 (您应该仔细检查波特率、引脚、RGB 颜色通道等)
如果以上使用串行监视器按预期工作,您可以返回测试处理接口草图。
另外请记住,9600 是一个很低的波特率。
您应该使用更高的波特率(例如 115200、57600)进行测试,如果它稳定,则使用它们来避免在缓冲串行数据时延迟驱动 LED。
一般来说,尽可能避免/尽量减少阻塞 (while) 循环。
总的来说,我们的想法是 delete/remove 代码中不需要的任何内容来深入解决问题:孤立地解决问题。一旦它被调试并可靠地工作,一次添加新代码,在每次添加后进行测试(否则你可能会引入更多错误而不是更难发现/修复的错误)。
我有 2 个不同的 LED 环。 (一个有 16 个 LED,另一个有 24 个) 我想通过处理 IDE 创建一个界面,在那里我可以 select 一种颜色并将这种颜色发送到 selected 环。这是arduino代码:
#include <FastLED.h>
#define LED_PIN1 3
#define LED_PIN2 12
#define NUM_LEDS1 16
#define NUM_LEDS2 24
CRGB leds1[NUM_LEDS1];
CRGB leds2[NUM_LEDS2];
int r,g,b;
boolean state = false;
void setup() {
FastLED.addLeds<WS2812, LED_PIN1, GRB>(leds1, NUM_LEDS1);
FastLED.addLeds<WS2812, LED_PIN2, GRB>(leds2, NUM_LEDS2);
Serial.begin(9600);
}
void loop() {
String returnedInput = rgbInput();
String red = returnedInput.substring(0,3); //get 3 values like 255
String green = returnedInput.substring(4,7);
String blue = returnedInput.substring(8,11);
Serial.println(red);
Serial.println(green);
Serial.println(blue);
int r = red.toInt();
int g = green.toInt();
int b = blue.toInt();
if (Serial.available()){
char val = Serial.read();
if(val == '2') { //selects the second LED ring
if(state == false) {
state = true;
for(int i = 0 ; i < 24 ; i++ ){
leds2[i] = CRGB(r, g, b); //turn on all the LEDs on the ring to the selected color
FastLED.show();
FastLED.clear();
FastLED.show();
}}}
}}
String rgbInput() {
//prompt for input
Serial.println("ready");
while(!Serial.available()) {
//if 0, it keeps waiting for the user to enter sth.
}
String userInput = Serial.readStringUntil("\n");
return userInput;
}
我为第二个 LED 写了这个,如果我能管理这个,我会为另一个做同样的事情,但它不起作用。
这里是处理代码:
import controlP5.*; //import ControlP5 library
import processing.serial.*;
Serial port;
ControlP5 cp5; //create ControlP5 object
PFont font;
PFont font2;
color col;
Serial serialMonitor;
String prompt;
ColorPicker cp;
void setup(){ //Same as setup in arduino
size(900, 900); //Window size, (width, height)
port = new Serial(this, "COM4", 9600); //Change this to your port
cp5 = new ControlP5(this);
font = createFont ("Georgia Bold", 20);
font2 = createFont ("Georgia Bold",15);
cp = cp5.addColorPicker("PICKER")
.setPosition(500,100)
.setColorValue(color(255,128,0,128))
;
Group configGroup = cp5.addGroup("CONFIGURATION")
.setPosition(90,100)
.setWidth(150)
.setHeight(30)
.setFont(font2)
.setBackgroundColor(color(0,0))
;
cp5.addButton("PICK_ALL") // The button
.setPosition(10, 10) // x and y relative to the group
.setSize(160, 150) // (width, height)
.setFont(font)
.setGroup(configGroup) // add it to the group
;
cp5.addButton("PICK_ONE") // The button
.setPosition(10, 200) // x and y relative to the group
.setSize(160, 150) // (width, height)
.setFont(font)
.setGroup(configGroup) // add it to the group
;
}
void draw(){ //Same as loop in arduino
background(150, 0 , 150); //Background colour of window (r, g, b) or (0 to 255)
}
public void controlEvent(ControlEvent c){
if(c.isFrom(cp)){
int r = int(c.getArrayValue(0));
int g = int(c.getArrayValue(1));
int b = int(c.getArrayValue(2));
int a = int(c.getArrayValue(3));
col = color(r,g,b,a);
}
}
void keyPressed(){
while(serialMonitor.available() > 0)
{
prompt = serialMonitor.readStringUntil (10);
}
println(keyCode);
String sendColor = nf(int(red(col)),3) + "," + nf(int(green(col)),3) + "," + nf(int(blue(col)),3);
println(sendColor);
serialMonitor.write(sendColor);
}
void PICKER(){
port.write('2');
}
void PICK_ALL(){
port.write('t');
}
void PICK_ONE(){
port.write('l');
}
我不太清楚如何获取 RGB 值并在 CRGB 函数中使用它们。使用使用 3 个引脚的单个 RGB LED 时要容易得多。但是我无法将它实现到仅使用 1 个引脚的 LED 环。
这里是拾色处理界面。我可以 select 颜色,但 Arduino 上的 LED 环没有任何变化。
可靠的串行通信并非易事。理想情况下,您可以让自己的二进制通信协议设置一个字节数据包,其中 header 描述了实际有多少后续字节有数据,甚至可能是 checksum.
字符串可以帮助您入门,您使用 nf()
让数据更易于解析真是太好了。
一个潜在的陷阱可能是将一个字符串放在一起 (rgbInput()
) 和一次读取一个字符 (char val = Serial.read();
) 之间的切换。
我建议将问题分解成更小的更简单的部分,testing/debugging 每个部分,然后一次一个地将这些部分重新组合在一起以避免集成错误。
例如,主要的挑战似乎是串行通信,所以我会编写 Processing 和 Arduino 草图以确保在添加 LED 控制之前可靠地工作。
让我们选择 \n 终止字符串选项,即使它发送了一个多余的额外字符(例如 port.write("2\n");
),它也会使缓冲更简单:
- 总是缓冲直到换行
trim()
换行字符串- 如果修剪后的字符串的长度为 1,则它是一个命令(如“2”、'l'、't'),否则它是一个颜色三元组
这是一个使用上述想法的基本 Arduino 草图(以及您的一些代码;)):
void setup() {
Serial.begin(9600);
}
void loop() {
// check if there are at least two characters to receive
if(Serial.available() > 1){
// buffer the full string until a new line character
String returnedInput = Serial.readStringUntil('\n');
// remove white space (new line char)
returnedInput.trim();
// if it's a single command
if(returnedInput.length() == 1){
char state = returnedInput.charAt(0);
switch(state){
case '2':
Serial.println("parsed 2 command");
break;
case 't':
Serial.println("parsed t command");
break;
case 'l':
Serial.println("parsed l command");
break;
default:
Serial.print("unknown state:");
Serial.println(state);
break;
}
}
// if it's a RGB triplet
else if(returnedInput.length() == 11){
String redString = returnedInput.substring(0, 3); //get 3 values like 255
String greenString = returnedInput.substring(4, 7);
String blueString = returnedInput.substring(8, 11);
int r = redString.toInt();
int g = greenString.toInt();
int b = blueString.toInt();
// constrain values to bytes
r = constrain(r, 0, 255);
g = constrain(g, 0, 255);
b = constrain(b, 0, 255);
// do something with the values (e.g. store globally, etc.)
Serial.print("parsed RGB: #");
Serial.print(r, HEX);
Serial.print(g, HEX);
Serial.print(b, HEX);
Serial.println();
}
// otherwise error message ?
else{
Serial.print("Uknown command: ");
Serial.println(returnedInput);
}
}
}
这应该处理带有新行终止符的字符串消息,并根据修剪后的长度解析单个字符命令和 11 个字符的 RRR、GGG、BBB 字符串。
可以直接用Arduino的Serial Monitor测试
在您的 Processing sketch 中,不清楚为什么有两个串行端口(port
和 serialMonitor
)。
这里是您的 Processing sketch 的一个稍微修改的版本,它发送几个单字符命令或颜色字符串:
import controlP5.*; //import ControlP5 library
import processing.serial.*;
PFont font;
PFont font2;
// Arduino serial port
Serial port;
// colour picker values to send to Arduino
int r;
int g;
int b;
// GUI variables
ControlP5 cp5; //create ControlP5 object
ColorPicker cp;
void setup() { //Same as setup in arduino
size(900, 900); //Window size, (width, height)
try {
port = new Serial(this, "/dev/tty.usbserial-A104WS3R", 9600); //Change this to your port
// buffer until new line: this plugs in nicely with serialEvent()
port.bufferUntil('\n');
}catch(Exception e) {
println("error opening serial");
e.printStackTrace();
}
cp5 = new ControlP5(this);
font = createFont ("Georgia Bold", 20);
font2 = createFont ("Georgia Bold", 15);
cp = cp5.addColorPicker("PICKER")
.setPosition(500, 100)
.setColorValue(color(255, 128, 0, 128))
;
Group configGroup = cp5.addGroup("CONFIGURATION")
.setPosition(90, 100)
.setWidth(150)
.setHeight(30)
.setFont(font2)
.setBackgroundColor(color(0, 0))
;
cp5.addButton("PICK_ALL") // The button
.setPosition(10, 10) // x and y relative to the group
.setSize(160, 150) // (width, height)
.setFont(font)
.setGroup(configGroup) // add it to the group
;
cp5.addButton("PICK_ONE") // The button
.setPosition(10, 200) // x and y relative to the group
.setSize(160, 150) // (width, height)
.setFont(font)
.setGroup(configGroup) // add it to the group
;
}
void draw() { //Same as loop in arduino
background(150, 0, 150); //Background colour of window (r, g, b) or (0 to 255)
}
public void controlEvent(ControlEvent c) {
if (c.isFrom(cp)) {
r = int(c.getArrayValue(0));
g = int(c.getArrayValue(1));
b = int(c.getArrayValue(2));
}
}
void keyPressed() {
if(port == null){
println("no serial, ignoring");
return;
}
String sendColor = nf(r, 3) + "," + nf(g, 3) + "," + nf(b, 3) + '\n';
println("sending to Arduino:", sendColor);
port.write(sendColor);
}
void PICKER() {
println("PICKER");
if (port != null) port.write("2\n");
}
void PICK_ALL() {
println("PICK_ALL");
if (port != null) port.write("t\n");
}
void PICK_ONE() {
println("PICK_ONE");
if (port != null) port.write("l\n");
}
void serialEvent(Serial s){
println("from Arduino:", s.readString());
}
总体注意错误检查位:使用 Serial 时总是一个好主意 :)
一旦按预期工作,您就可以组合 FastLED
控件。
这里有一个建议:
#include <FastLED.h>
#define LED_PIN1 3
#define LED_PIN2 12
#define NUM_LEDS1 16
#define NUM_LEDS2 24
CRGB leds1[NUM_LEDS1];
CRGB leds2[NUM_LEDS2];
// ring 1 color
int r1,g1,b1;
// ring 2 color
int r2,g2,b2;
// toggle wether to update r1,g1,b1 or r2,g2,b2 when a new colour arrives
boolean updateRing1 = true;
void setup() {
// setup serial
Serial.begin(9600);
// setup LEDs
FastLED.addLeds<WS2812, LED_PIN1, GRB>(leds1, NUM_LEDS1);
FastLED.addLeds<WS2812, LED_PIN2, GRB>(leds2, NUM_LEDS2);
}
void loop() {
handleSerial();
driveLEDRings();
}
void handleSerial(){
// check if there are at least two characters to receive
if(Serial.available() > 1){
// buffer the full string until a new line character
String returnedInput = Serial.readStringUntil('\n');
// remove white space (new line char)
returnedInput.trim();
// if it's a single command
if(returnedInput.length() == 1){
char state = returnedInput.charAt(0);
switch(state){
case '2':
Serial.println(F("parsed 2 command"));
break;
case 't':
Serial.println(F("parsed t command: switching to ring #1"));
updateRing1 = true;
break;
case 'l':
Serial.println(F("parsed l command: switching to ring #2"));
updateRing1 = false;
break;
default:
Serial.print(F("unknown state:"));
Serial.println(state);
break;
}
}
// if it's a RGB triplet
else if(returnedInput.length() == 11){
String redString = returnedInput.substring(0, 3); //get 3 values like 255
String greenString = returnedInput.substring(4, 7);
String blueString = returnedInput.substring(8, 11);
int r = redString.toInt();
int g = greenString.toInt();
int b = blueString.toInt();
// constrain values to bytes
r = constrain(r, 0, 255);
g = constrain(g, 0, 255);
b = constrain(b, 0, 255);
// do something with the values (e.g. store globally, etc.)
Serial.print(F("parsed RGB: #"));
Serial.print(r, HEX);
Serial.print(g, HEX);
Serial.print(b, HEX);
Serial.println();
// handle ring colour update
if(updateRing1){
r1 = r;
g1 = g;
b1 = b;
}else{
r2 = r;
g2 = g;
b2 = b;
}
}
// otherwise error message ?
else{
Serial.print("Uknown command: ");
Serial.println(returnedInput);
}
}
}
void driveLEDRings(){
//update ring 1
for(int i = 0 ; i < NUM_LEDS1; i++){
leds1[i] = CRGB(r1, g1, b1);
}
//update ring 2
for(int i = 0 ; i < NUM_LEDS2; i++){
leds2[i] = CRGB(r2, g2, b2);
}
// display
FastLED.show();
}
注意:以上代码未使用有线 RGB LED 进行测试,因此它可能无法正常工作,但希望它能说明这个想法。 (您应该仔细检查波特率、引脚、RGB 颜色通道等)
如果以上使用串行监视器按预期工作,您可以返回测试处理接口草图。
另外请记住,9600 是一个很低的波特率。 您应该使用更高的波特率(例如 115200、57600)进行测试,如果它稳定,则使用它们来避免在缓冲串行数据时延迟驱动 LED。 一般来说,尽可能避免/尽量减少阻塞 (while) 循环。
总的来说,我们的想法是 delete/remove 代码中不需要的任何内容来深入解决问题:孤立地解决问题。一旦它被调试并可靠地工作,一次添加新代码,在每次添加后进行测试(否则你可能会引入更多错误而不是更难发现/修复的错误)。