【问题标题】:Serial.readBytesUntil() gives garbage value and cause setup() function act like loop.Serial.readBytesUntil() 给出垃圾值并导致 setup() 函数像循环一样。
【发布时间】:2015-11-08 23:56:04
【问题描述】:

我正在尝试使用 Serial.readBytesUntil() 函数读取字符串。我的代码在这里:

char *name_arr;
char *test = "Serial.begin is Ready";

void setup(){
  Serial.begin(9600);
  Serial.println(test);
}

void loop(){
  if (Serial.readBytesUntil('\r', name_arr, 10)){    
     Serial.println(name_arr);
     Serial.println();
  }
}

当我只给一个数字作为串行输入时,什么都不会发生。Serial.println() 函数什么也不打印。

但是当我输入超过两个数字(如 15,12 等)时,它开始在无限循环中打印垃圾值。

如果我提供像“asd”这样的字符输入,或者将此代码用于循环()而不是之前的代码: void loop(){ while (Serial.available()>0){ Serial.readBytesUntil('\r', name_arr, 10); Serial.println(name_arr); Serial.println(); }

然后它会打印除前两个字符之外的整个字符串“test”。但 test 仅在 setup 函数中打印:

似乎 setup() 函数一次又一次地运行。

如何将字符串输入保存在字符数组中(不在字符串类中)?

函数如何重新运行设置函数以及为什么不打印初始两位数?

【问题讨论】:

    标签: arrays arduino serial-port


    【解决方案1】:

    readBytesUntil 将在第二个参数中存储字节(参见here),但您只声明了一个指针,而不是一个数组。指针默认指向地址 0,因此 readBytesUntil 将字符存储在地址 0 处。糟糕,非常糟糕。这导致了重置,看起来setup 不断地运行。

    您需要将声明更改为:

    char name_array[11];
    

    另外,不要忘记 C 风格的字符串(即 char 数组)需要以 NUL 结尾。 readBytesUntil 返回它读取的字符数,您可以使用该返回值来终止字符串:

    size_t num_read = Serial.readBytesUntil('\r', name_arr, sizeof(name_arr)-1 ));
    name_arr[ num_read ] = '\0'; // a zero byte, ASCII NUL
    

    这就是它没有正确打印的原因。请注意,声明为 NUL 增加了一个字节(“11”,而不是“10”),readBytesUntil 的第三个参数是数组大小减 1。

    总草图:

    char name_arr[11];
    char *test = "Serial.begin is Ready";
    
    void setup(){
      Serial.begin(9600);
      Serial.println(test);
    }
    
    void loop(){
      while (Serial.available()) {
        size_t num_read = Serial.readBytesUntil('\r', name_arr, sizeof(name_arr)-1 );
        name_arr[num_read] = '\0';
        Serial.println(name_arr);
        Serial.println();
      }
    }
    

    【讨论】:

    • Thnx 很多,现在可以正常打印了。除了它再次打印没有第一个数字。就像我输入“anklon”..然后它会打印“anklon”。没关系,但在此之后,它会自动打印“nklon”。它不打印 name_arr[0] 字符:3
    • 您没有发布新代码,但我能够重现它。您是否在num_read = Serial.readBytes... 之后对字符串进行了 NUL 终止?我在上面添加了整个草图
    • 是的,我添加了 NULL 终止。我的代码其实和你的一样。
    • 在您的串行监视器窗口中,右下角的下拉菜单是否显示“NL 和 CR”?就在波特率下拉菜单的左侧。这将导致它打印两件事:您输入的行,直到 NL,然后是串行监视器发送的额外 CR 的空行。如果那里没有name_arr[num_read]='\0',则第二个打印显示“nklon”,因为 CR 踩到了“a”。你确定上传正常吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-10
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    相关资源
    最近更新 更多