简体   繁体   English

Arduino 无法正确读取串行

[英]Arduino can't read Serial properly

Alright, I've googled getting a string from Serial with Arduino and I've had no luck even copy and pasting examples.好吧,我用 Arduino 搜索了 Serial 中的一个字符串,但我什至没有成功复制和粘贴示例。

I'm trying to get a string from the Serial.我正在尝试从串行获取字符串。 Here's my code:这是我的代码:

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

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

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

And it's printing out character by character.它正在逐个字符地打印出来。

I also tried我也试过

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

And it returns 1 character at a time (serial.print(inByte) gives -1 every other time).它一次返回 1 个字符(serial.print(inByte) 每隔一次返回 -1)。 Why is the Serial splitting each character?为什么串行拆分每个字符?

If I enter 'hello' and I call serial.read() it gives a character then says there's nothing, then gives another character and says there's nothing.如果我输入 'hello' 并调用 serial.read() 它给出一个字符然后说没有任何东西,然后给出另一个字符并说没有任何东西。

I figured it out.我想到了。

When you open a Serial with 9600 baud ( Serial.begin(9600); ), it's reading/writing at 9600 bytes per second.当您以 9600 波特( Serial.begin(9600); )打开串行时,它以每秒 9600 字节的速度读取/写入。 That means at fastest it can get just under 10 bytes per millisecond.这意味着它最快可以达到每毫秒不到 10 个字节。 I don't know what the operating speed is, but it seems like the Arduino gets alerted of and reads the first byte before the second one arrives.我不知道运行速度是多少,但似乎 Arduino 收到警报并在第二个字节到达之前读取第一个字节。 So, you must add a delay(1) to "wait" for another byte in the "same stream" to arrive.因此,您必须添加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;
}

You may ask, well since you're delaying how do you know if the user is just typing very fast?你可能会问,既然你在延迟,你怎么知道用户是否只是打字很快? You can't avoid it here, since the Serial is essentially limited at a certain speed.你不能在这里避免它,因为串行基本上限制在一定的速度。 However, the user must be typing virtually-impossibly-fast for two inputs to be confused as one.但是,用户必须以几乎不可能的速度打字才能将两个输入混淆为一个。

I don't have access to the Arduino source files here, but the following line of code won't give you a full String for obvious reasons (let me know if it's not that obvious):我无法在此处访问 Arduino 源文件,但以下代码行由于显而易见的原因不会为您提供完整的字符串(如果不那么明显,请告诉我):

int inByte = Serial.read();

Also, using另外,使用

Serial.write()

you'll be sending byte per byte.您将按字节发送字节。 That's the oposite from那是相反的

Serial.println()

in which you'll be sending full sentences.您将在其中发送完整的句子。

I would try working with Serial.print() or println() rather then Serial.write().我会尝试使用 Serial.print() 或 println() 而不是 Serial.write()。

You can check out the references:您可以查看参考资料:

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

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

Even though this post is old, I'll post my answer in case someone googles their way here.即使这篇文章很旧,我也会发布我的答案,以防有人在这里用谷歌搜索他们的方式。

For reading strings from the serial you can use the following:要从串行读取字符串,您可以使用以下内容:

String str;

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

Works like a charm!奇迹般有效!

It exists delay when transferring data via UART.通过UART传输数据时存在延迟。 Have a try with Serial.timedRead() instead.尝试使用 Serial.timedRead() 代替。 The code is as below.代码如下。

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

I wrote this simple Serial full message repeater.我写了这个简单的串行完整消息转发器。 It does not require a String object or any kind of delaying as in previous answers.它不需要String对象或前面的答案中的任何类型的延迟。

How it works这个怎么运作
It receives characters and stores them to buffer until terminating character \\n or \\0 is received.它接收字符并将它们存储到缓冲区,直到接收到终止字符\\n\\0 Then it prints the whole buffer back.然后它打印整个缓冲区。

There is also implemented buffer overflow check, so you don't lose any data.还实现了缓冲区溢出检查,因此您不会丢失任何数据。

The main advantage of this solution is the speed and possibility to react to the message content even before the whole reading procedure is complete (for example, you can implement a message parser on top of this very easily).该解决方案的主要优点是即使在整个读取过程完成之前也可以对消息内容做出反应的速度和可能性(例如,您可以非常轻松地在此基础上实现消息解析器)。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM