【问题标题】:How to compare string from Serial.read()?如何比较来自 Serial.read() 的字符串?
【发布时间】:2014-07-25 17:33:40
【问题描述】:

我在下面有这段代码,我从this forum 得到的,我遵循了。它对我不起作用,但他们声称代码很好。我已经尝试了几种字符串比较方法,例如string.equals(string) 和标准的== 运算符,仍然没有运气。

int ledPin = 13;
String readString;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT); 
  Serial.println("serial on/off test 0021"); // so I can keep track
}

void loop() {
  while (Serial.available()) {
    delay(3);  
    char c = Serial.read();
    readString += c; 
  }
  if (readString.length() >0) {
    if (readString == "on") {
      Serial.println("switching on");
      digitalWrite(ledPin, HIGH);
    }
    if (readString == "off") {
      digitalWrite(ledPin, LOW);
    }
    readString="";
  } 
}

【问题讨论】:

  • 您首先必须确保字符串的长度相等,然后才能比较它们。使用 delay() 极其不可靠,而且浪费,使用特定字符来标记字符串的结尾。像'\n'。
  • 您可以使用Serial.readString(),而不是自己循环并构建readString。它会自动为您完成所有这些工作,甚至去掉换行符。

标签: serial-port arduino


【解决方案1】:

我可以通过在字符串比较之前简单地添加readString.trim(); 来解决昨晚的问题。这是因为在 arduino 控制台中会有 id 没有打印任何内容的换行符。

我将函数放在下面的代码中:

int ledPin = 13;
String readString;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT); 
  Serial.println("serial on/off test 0021"); // so I can keep track
}

void loop() {

  while (Serial.available()) {
    delay(3);  
    char c = Serial.read();
    readString += c; 
  }
  readString.trim();
  if (readString.length() >0) {
    if (readString == "on"){
      Serial.println("switching on");
      digitalWrite(ledPin, HIGH);
    }
    if (readString == "off")
    {
      Serial.println("switching off");
      digitalWrite(ledPin, LOW);
    }

    readString="";
  } 
}

【讨论】:

  • +1 用于从 Serial 中收集 c 上的字符,然后像 StringBuilder 一样将其存储在 readString 上。如果我使用 strcmp() 或 strncmp() 来比较 char,我会遇到问题,它一直告诉我要转换 const char*。
【解决方案2】:

为什么不使用 Serial.readString();??

试试这个..

     void setup() {
      pinMode(13, OUTPUT);
      Serial.begin(9600);
    }

    void loop(){
      if(Serial.available()){
        String ch;
        ch = Serial.readString();
        ch.trim();
        if(ch=="on"||ch=="ON"){
          digitalWrite(13, HIGH);  
        }
        else if(ch=="off"||ch=="OFF"){
          digitalWrite(13, LOW);
        }
      }
    }

【讨论】:

  • 正是我想要的。谢谢@Anim
【解决方案3】:

我只使用' '(单)而不是" "(双)

char c = Serial.read();

if (c == '1'){ //do something}  

【讨论】:

    【解决方案4】:

    新的 SafeString Arduino 库(可从库管理器中获得)使这一过程变得简单而安全。与 Arduino Strings 不同,SafeStrings 不会导致您的草图重新启动,也不会导致堆碎片化。

    详细教程见https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html

    SafeStrings 易于调试。SafeStrings 提供详细的错误消息,包括相关 SafeString 的名称,以帮助您正确运行程序。

    SafeStrings 安全可靠。 SafeStrings 永远不会导致重新启动,并且始终处于有效的可用状态,即使您的代码传递空指针或“\0”参数或超出 SafeString 的可用容量也是如此.

    SafeString 程序永远运行。 SafeStrings 完全避免内存碎片,这最终会导致您的程序失败,并且在作为参数传递时不会产生额外的副本。

    SafeString 更快。 SafeString 不会创建多个副本或短期对象,也不会对数据进行不必要的复制。

    SafeString 还具有标记/解析方法。其中一个可能详细的示例包括库中的内容,包括读取用户输入和解析命令,同时保持草图的其余部分以最大速度运行。 SafeString 方法中没有邪恶的延迟()来阻止你的草图在它的跟踪中。

    注意:在下面的示例代码中,SafeStrings 的大小很小,但代码可以处理来自用户的任意长输入。

    用户串行输入,例如
    这是一个长输入,打开和关闭等
    处理和解析都很好。

    SafeString 还具有大量调试和错误消息,可帮助您查找和修复编码问题。

    #include "SafeString.h"
    
    const size_t maxCmdLength = 3; // make SafeStrings at least large enough to hold longest cmd
    // Use SafeStrings for the commands as comparing two SafeStrings is generally faster as the lengths can be compared first.
    createSafeString(onCmdStr, maxCmdLength, "on");
    createSafeString(offCmdStr, maxCmdLength, "off");
    
    // input must be large enough to hold longest cmd + 1 delimiter
    createSafeString(input, maxCmdLength + 1); //  to read input cmd + 1 delimiter
    createSafeString(token, maxCmdLength + 1); // for parsing capacity >= input.capacity()
    
    char delimiters[] = " .,\r\n"; // space dot comma CR NL are cmd delimiters
    
    void setup() {
      Serial.begin(9600);    // Open serial communications and wait a few seconds
      SafeString::setOutput(Serial); // enable error messages and debug() output to be sent to Serial
    }
    
    void loop() {
      input.read(Serial); // read from Serial, returns true if at least one character was added to SafeString input
    
      if (input.nextToken(token, delimiters)) { // process at most one token per loop does not return tokens longer than input.capacity()
        if (token == onCmdStr) {
          Serial.println("switching on");
          digitalWrite(ledPin, HIGH)
        } else if (token == offCmdStr) {
          Serial.println("switching off");
          digitalWrite(ledPin, LOW);
        }// else  // not a valid cmd ignore
      }
    }
    

    【讨论】:

      【解决方案5】:

      我看到您尝试创建一些类似的命令行解释器进行测试;

      您可以使用Serial command line interpreter for Arduino 或只查看代码,了解它的工作原理。

      这不是答案,而是一些帮助 =)

      【讨论】:

        【解决方案6】:

        解决了你的代码是对的,你只需将 arduino 终端设置为“无行尾”,你也忘了写这个 Serial.println("switching off");

        感谢您分享您的代码,我也在使用您的代码,谢谢!!

        【讨论】:

          猜你喜欢
          • 2015-03-03
          • 2019-10-08
          • 1970-01-01
          • 2013-06-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-12-24
          相关资源
          最近更新 更多