字符串比较产生不好的结果
String comparison yields bad results
我阅读并打印了我的序列号以确保条目正确无误。当 "red"
"green"
或 "blue"
(输入时不带引号)none 比较有效。打印的线条显示正确的颜色。硬件检查最后 else
是否正确闪烁颜色。
我尝试了 if (myColor == "red")
和 if (myColor.equals("red")
以及 none 的颜色。
我替换了 String x="red"
然后 if (x.equals("red"))
并且它按预期工作。我知道问题出在串口读取 myColor
。我只是不知道如何让它发挥作用。
代码:
int redPin=8;
int greenPin=9;
int bluePin=10;
String myColor;
String msg="What color do you want? ";
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(redPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(greenPin, OUTPUT);
}
void loop() {
Serial.println(msg);
while (Serial.available()==0){
}
myColor=Serial.readString();
Serial.println(myColor); //check to see that it was entered correctly
if (myColor == "red"){
digitalWrite(redPin, LOW);
digitalWrite(bluePin, HIGH);
digitalWrite(greenPin, LOW);
}
else if (myColor == "green"){
digitalWrite(redPin, LOW);
digitalWrite(bluePin, LOW);
digitalWrite(greenPin, HIGH);
}
else if (myColor == "blue"){
digitalWrite(redPin, LOW);
digitalWrite(bluePin, HIGH);
digitalWrite(greenPin, LOW);
}
else {
for (int x = 0; x < 3; x++){
digitalWrite(redPin, HIGH);
delay (500);
digitalWrite(redPin, LOW);
delay (500);
digitalWrite(bluePin, HIGH);
delay (500);
digitalWrite(bluePin, LOW);
delay (500);
digitalWrite(greenPin, HIGH);
delay (500);
digitalWrite(greenPin, LOW);
delay(500);
}
}
}
将您的检查代码更改为:
String x = String("[") + myColor + String("]");
Serial.println(x);
Serial.println(myColor.length());
您的字符串中很可能包含 其他 内容,例如换行符或 space。如果是这样,您将看到如下输出:
[red ]
[ red]
[red
]
而不是 single-line [red]
。第二个println
也是输出长度校验,确保red
匹配3
,blue
匹配4
,以此类推。
最后两件事:
我倾向于先关闭当前输出,然后再打开相关输出。它 可能 不是必需的,但它来自不喜欢同时打开多个输出的系统。这意味着,对于蓝色,您可以执行如下操作,其中其他两个首先被驱动为低电平,然后 蓝色被驱动为高电平:
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, HIGH);
您的 red
代码块目前与 blue
相同,您可能应该改为:
digitalWrite(bluePin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(redPin, HIGH);
关于上面的第一个要点,您可以通过一些重构来简化您的代码,例如引入一个函数来选择打开哪个引脚:
void offOffOn(int offA, int offB, int on) {
digitalWrite(offA, LOW);
digitalWrite(offB, LOW);
digitalWrite(on, HIGH);
}
然后你的 loop()
部分变得更短(还有一个“压缩” else
子句):
if (myColor == "red") {
offOffOn(greenPin, bluePin, redPin);
} else if (myColor == "green") {
offOffOn(redPin, bluePin, greenPin);
} else if (myColor == "blue") {
offOffOn(redPin, greenPin, bluePin);
} else {
int allPins[] = { redPin, bluePin, greenPin };
size_t pinCount = sizeof(allPins) / sizeof(*allPins);
for (int count = 0; count < pinCount * 3; ++count) {
digitalWrite(allPins[idx % pinCount], HIGH); delay (500);
digitalWrite(allPins[idx % pinCount], LOW); delay (500);
}
}
readString
是一个不应该使用的糟糕函数。
它使代码 运行 变慢(响应缓慢)并按时间分隔消息。
默认情况下,它等待 1 秒直到没有数据到达,然后再等待 returns。之后 returns 发送的所有内容。
如果你依次发送行"red"
和"green"
,myColor
将是"red\ngreen\n"
,除非你慢慢地间隔超过1秒。
即使您收到一行,末尾仍会有一个尾随 new-line 字符。
你应该使用 readStringUntil
:
myColor = Serial.readStringUntil('\n');
这将使您的代码响应更快,并且 returns 没有 new-line 字符的行。
只需确保串行监视器仅发送 new-line 字符(“换行”选项)。
我阅读并打印了我的序列号以确保条目正确无误。当 "red"
"green"
或 "blue"
(输入时不带引号)none 比较有效。打印的线条显示正确的颜色。硬件检查最后 else
是否正确闪烁颜色。
我尝试了 if (myColor == "red")
和 if (myColor.equals("red")
以及 none 的颜色。
我替换了 String x="red"
然后 if (x.equals("red"))
并且它按预期工作。我知道问题出在串口读取 myColor
。我只是不知道如何让它发挥作用。
代码:
int redPin=8;
int greenPin=9;
int bluePin=10;
String myColor;
String msg="What color do you want? ";
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(redPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(greenPin, OUTPUT);
}
void loop() {
Serial.println(msg);
while (Serial.available()==0){
}
myColor=Serial.readString();
Serial.println(myColor); //check to see that it was entered correctly
if (myColor == "red"){
digitalWrite(redPin, LOW);
digitalWrite(bluePin, HIGH);
digitalWrite(greenPin, LOW);
}
else if (myColor == "green"){
digitalWrite(redPin, LOW);
digitalWrite(bluePin, LOW);
digitalWrite(greenPin, HIGH);
}
else if (myColor == "blue"){
digitalWrite(redPin, LOW);
digitalWrite(bluePin, HIGH);
digitalWrite(greenPin, LOW);
}
else {
for (int x = 0; x < 3; x++){
digitalWrite(redPin, HIGH);
delay (500);
digitalWrite(redPin, LOW);
delay (500);
digitalWrite(bluePin, HIGH);
delay (500);
digitalWrite(bluePin, LOW);
delay (500);
digitalWrite(greenPin, HIGH);
delay (500);
digitalWrite(greenPin, LOW);
delay(500);
}
}
}
将您的检查代码更改为:
String x = String("[") + myColor + String("]");
Serial.println(x);
Serial.println(myColor.length());
您的字符串中很可能包含 其他 内容,例如换行符或 space。如果是这样,您将看到如下输出:
[red ]
[ red]
[red
]
而不是 single-line [red]
。第二个println
也是输出长度校验,确保red
匹配3
,blue
匹配4
,以此类推。
最后两件事:
我倾向于先关闭当前输出,然后再打开相关输出。它 可能 不是必需的,但它来自不喜欢同时打开多个输出的系统。这意味着,对于蓝色,您可以执行如下操作,其中其他两个首先被驱动为低电平,然后 蓝色被驱动为高电平:
digitalWrite(redPin, LOW); digitalWrite(greenPin, LOW); digitalWrite(bluePin, HIGH);
您的
red
代码块目前与blue
相同,您可能应该改为:digitalWrite(bluePin, LOW); digitalWrite(greenPin, LOW); digitalWrite(redPin, HIGH);
关于上面的第一个要点,您可以通过一些重构来简化您的代码,例如引入一个函数来选择打开哪个引脚:
void offOffOn(int offA, int offB, int on) {
digitalWrite(offA, LOW);
digitalWrite(offB, LOW);
digitalWrite(on, HIGH);
}
然后你的 loop()
部分变得更短(还有一个“压缩” else
子句):
if (myColor == "red") {
offOffOn(greenPin, bluePin, redPin);
} else if (myColor == "green") {
offOffOn(redPin, bluePin, greenPin);
} else if (myColor == "blue") {
offOffOn(redPin, greenPin, bluePin);
} else {
int allPins[] = { redPin, bluePin, greenPin };
size_t pinCount = sizeof(allPins) / sizeof(*allPins);
for (int count = 0; count < pinCount * 3; ++count) {
digitalWrite(allPins[idx % pinCount], HIGH); delay (500);
digitalWrite(allPins[idx % pinCount], LOW); delay (500);
}
}
readString
是一个不应该使用的糟糕函数。
它使代码 运行 变慢(响应缓慢)并按时间分隔消息。
默认情况下,它等待 1 秒直到没有数据到达,然后再等待 returns。之后 returns 发送的所有内容。
如果你依次发送行"red"
和"green"
,myColor
将是"red\ngreen\n"
,除非你慢慢地间隔超过1秒。
即使您收到一行,末尾仍会有一个尾随 new-line 字符。
你应该使用 readStringUntil
:
myColor = Serial.readStringUntil('\n');
这将使您的代码响应更快,并且 returns 没有 new-line 字符的行。
只需确保串行监视器仅发送 new-line 字符(“换行”选项)。