【问题标题】:Arduino can't read Serial properlyArduino 无法正确读取 Serial
【发布时间】:2012-04-11 15:56:44
【问题描述】:

好的,我已经用 Arduino 从 Serial 中搜索了一个字符串,但我什至没有运气复制和粘贴示例。

我正在尝试从 Serial 中获取字符串。这是我的代码:

void setup() {
    Serial.begin(9600);
    Serial.write("Power On");
}

void loop()
{
    while(!Serial.available());

    while (Serial.available() > 0) {
      Serial.write(Serial.read());
    }
    Serial.println();
}

它是一个字符一个字符地打印出来。

我也试过

char* read(int len) {
  while (!Serial.available());
  char str[len];
  int i = 0;
  while (i < len) {
    str[i] = '\0';
    int inByte = Serial.read();
    Serial.println(inByte);
    if (inByte == -1) {
        return str;
    } else {
      str[i++] = inByte;
    }
  }
  return str;
}

它一次返回 1 个字符(serial.print(inByte) 每隔一次给出 -1)。为什么 Serial 会拆分每个字符?

如果我输入 'hello' 并调用 serial.read(),它会给出一个字符然后说什么都没有,然后给出另一个字符并说什么都没有。

【问题讨论】:

  • 串口很慢。您通常一次只得到一个字节,然后有一段时间什么都没有。你需要在你的代码中处理它,你现在不这样做。

标签: c stream serial-port arduino


【解决方案1】:

我无权访问此处的 Arduino 源文件,但由于显而易见的原因,以下代码行不会为您提供完整的字符串(如果不是那么明显,请告诉我):

int inByte = Serial.read();

另外,使用

Serial.write()

您将按字节发送字节。那是相反的

Serial.println()

您将在其中发送完整的句子。

我会尝试使用 Serial.print() 或 println() 而不是 Serial.write()。

您可以查看参考资料:

http://arduino.cc/en/Serial/Write

http://arduino.cc/en/Serial/Println

【讨论】:

    【解决方案2】:

    通过 UART 传输数据时存在延迟。尝试使用 Serial.timedRead() 代替。代码如下。

    void setup() {
        Serial.begin(9600);
        Serial.write("Power On");
    }
    
    void loop()
    {
        while(!Serial.available());
    
        while (true) {
          int byte = Serial.timedRead();
          if(byte == -1)
             break;
          Serial.write(byte);
        }
        Serial.println();
    }
    

    【讨论】:

      【解决方案3】:

      我想通了。

      当您以 9600 波特 (Serial.begin(9600);) 打开串行时,它以每秒 9600 字节的速度读取/写入。这意味着它最快可以达到每毫秒不到 10 个字节。我不知道运行速度是多少,但似乎 Arduino 收到警报并在第二个字节到达之前读取第一个字节。因此,您必须添加一个delay(1) 来“等待”“同一流”中的另一个字节到达。

      String read() {
          while (!Serial.available()); //wait for user input
          //there is something in the buffer now
          String str = "";
          while (Serial.available()) {
              str += (char) Serial.read();
              delay(1); //wait for the next byte, if after this nothing has arrived it means the text was not part of the same stream entered by the user
          }
          return str;
      }
      

      你可能会问,既然你在延迟,你怎么知道用户是否只是打字很快?你不能在这里避免它,因为串行基本上限制在一定的速度。但是,用户必须以几乎不可能的速度输入才能将两个输入混淆为一个。

      【讨论】:

        【解决方案4】:

        即使这篇文章很旧,我也会发布我的答案,以防有人在这里用谷歌搜索。

        要从序列中读取字符串,您可以使用以下命令:

        String str;
        
        while (Serial.available() > 0) {
            str = Serial.readString();
        }
        

        像魅力一样工作!

        【讨论】:

          【解决方案5】:
          String str;
          
          void setup()
          {
              Serial.begin(9600);
          }
          
          void loop ()
          {
              while (Serial.available() > 0){
                  char c = Serial.read();
                  str.concat(c);
                  if (Serial.available() == 0)
                  {
                      Serial.print(str);
                      str = "";
                      break;
                  }
              }
          }
          

          【讨论】:

            【解决方案6】:

            我编写了这个简单的串行完整消息转发器。它不需要 String 对象或之前答案中的任何延迟。

            工作原理
            它接收字符并将它们存储到缓冲区,直到接收到终止字符\n\0。然后它将整个缓冲区打印回来。

            还实现了缓冲区溢出检查,所以你不会丢失任何数据。

            此解决方案的主要优点是即使在整个阅读过程完成之前对消息内容做出反应的速度和可能性(例如,您可以在此基础上非常轻松地实现消息解析器)。

            #define LENGTH 20
            
            void setup() {
              Serial.begin(9600);
              Serial.println("Ready to read");
            }
            
            void loop() {
              if (Serial.available()) {
                char buffer[LENGTH];
                int index = 0;
                bool receiving = true;
                
                while (receiving) {
                  if (Serial.available()) {
                    char ch = Serial.read();
                    if (ch == '\n' || ch == '\0') {
                      buffer[index] = '\0';
                      receiving = false;
                    } else {
                      buffer[index++] = ch;
                      if (index == LENGTH) {
                        buffer[index] = '\0';
                        break;
                      }
                    }
                  }
                }
            
                Serial.println(buffer);
              }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-03-13
              • 2021-12-07
              • 2019-05-22
              • 2019-11-13
              • 2012-02-20
              相关资源
              最近更新 更多