Arduino无法正确读取Serial

时间:2012-03-28 04:15:30

标签: c stream serial-port arduino

好吧,我用google搜索了一下来自Serial with Arduino的字符串,我甚至没有运气,甚至没有复制和粘贴示例。

我正在尝试从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()它会给出一个字符,然后说什么都没有,然后给另一个字符并且说什么都没有。

6 个答案:

答案 0 :(得分:11)

我明白了。

当您打开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;
}

您可能会问,因为您推迟了如何知道用户是否只是打字速度非常快?你不能在这里避免它,因为Serial基本上限制在一定的速度。但是,用户必须以几乎不可能的速度输入,以便将两个输入混淆为一个。

答案 1 :(得分:2)

我这里没有访问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 :(得分:1)

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

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

String str;

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

像魅力一样!

答案 3 :(得分:0)

通过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();
}

答案 4 :(得分:0)

我写了这个简单的串行完整消息转发器。它不需要 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);
  }
}

答案 5 :(得分:-3)

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;
        }
    }
}