字符串比较产生不好的结果

问题描述

我从序列号中读取并打印以确保输入正确。当"red" "green""blue"(键入不带引号)时,所有比较均不起作用。印刷线显示正确的颜色。对所有硬件进行检查,最后一个else会正确闪烁颜色。

我尝试了if (myColor == "red")if (myColor.equals("red"),但没有一种颜色起作用。

我替换了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(greenPin,HIGH);
    }
    else if (myColor == "blue"){
        digitalWrite(redPin,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());

您的字符串中很有可能包含 other 之类的东西,例如换行符或空格。如果是这样,您将看到类似以下的输出:

[red ]
[ red]
[red
]

而不是单行[red]。第二个println也要输出用于验证的长度,以确保red匹配3blue匹配4,依此类推。>


最后两件事:

  • 在打开相应的输出之前,我倾向于先关闭电流输出。 可能不是必需的,但它是由不希望同时具有多个输出的系统刻录引起的。这意味着,对于蓝色,您将执行以下操作,其中其他两个首先被驱动为低,然后 蓝色被驱动为高:

    digitalWrite(redPin,LOW);
    digitalWrite(greenPin,LOW);
    digitalWrite(bluePin,HIGH);
    
  • 您用于red的代码块当前与blue相同,您可能应该使用以下代码:

    digitalWrite(bluePin,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,greenPin);
} else if (myColor == "blue") {
    offOffOn(redPin,greenPin,bluePin);
} else {
    int allPins[] = { redPin,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秒钟,直到没有数据到达,然后再返回。之后,它将返回已发送的所有内容。

如果您一次又一次发送"red""green"线,则myColor将是"red\ngreen\n",除非您间隔不超过1秒缓慢进行。
即使您只收到一行,结尾处仍然会有一个换行符。

您应该使用readStringUntil

myColor = Serial.readStringUntil('\n');

这将使您的代码具有更高的响应速度,并返回没有换行符的行。
只需确保“串行”监视器仅发送换行符即可(“ Newline”选项)。