【问题标题】:Arduino Serial Output Dropping CharactersArduino 串行输出丢失字符
【发布时间】:2013-06-23 01:21:17
【问题描述】:

当我尝试为我的 Arduino Uno 编写一些代码时,这里有一个奇怪的串行输出。

我有这个原型代码:

MyClass myclass;

void setup()
{
   Serial.Begin(9600);
   Serial.println("Starting...");
}

void loop()
{
   int status = myclass.DoWork();
   Serial.println("Status: " + status);
}

class MyClass 
{
   int DoWork()
   {
      Serial.println("Doing some work...");
      return 1;
   }
}

现在运行时我得到以下输出:

开始...

做一些工作......

属性:1

所以奇怪的部分是“状态:1”缺少前几个字符。这是因为我在对象中不正确地使用串行还是什么?

我注意到当我引用另一个也像 MyClass 一样使用串行的库时,我得到了其他奇怪的输出行为......所以我认为我做错了什么。

编辑:最后证明这实际上是一个内存问题。我包含的一个库非常大,它正在消耗可用内存。我通过添加更多调试语句发现了这一点,并发现损坏根据字符串长度和位置转移。通过使用 F() 函数,我将字符串移动到闪存中(例如,我现在运行 Serial.println(F("Starting...")); 它已经纠正了奇怪的输出。

【问题讨论】:

  • 发送时字符非常不太可能丢失。接收器更有可能丢弃它们。我们看不到它。
  • 可能是您溢出了串行缓冲区吗?尝试在循环()中执行延迟(5),看看是否有区别。
  • 我认为您应该删除您的“编辑”评论,并使其成为您“自动接受”的答案。 SO 不仅用于解决您的问题,还可以为可能有一天会遇到您的问题的其他人提供提示。

标签: serial-port arduino


【解决方案1】:

您不能在 C++ 中添加字符串和整数。如果编译失败,对你来说会更好:

Serial.println("Status: " + status);

相反,编译器猜测了一些东西。它猜错了。使用这个:

Serial.print("Status :");
Serial.println(status);

或者为了完全控制输出数字和字符串,学习使用 C 字符串格式化,sprintf()

【讨论】:

  • 或者OP可以使用strncpy()
  • strncpy() 只会复制字符串。它不会自动将 int 格式化为 char[]
  • 我不是专家,但我对 ARDUINO 字符串类(不是 C++ 类)的阅读表明“状态:”+ 状态表达式会自动将 int 转换为字符串,然后创建一个新字符串,它是“状态”字符串和新字符串的组合。也就是说,我更喜欢像你一样将它分解为 print/println —— 自动转换和新的 String 对象似乎会以一种会导致麻烦的方式进入堆。
  • 这可能已经发生了,除了 "Status :" 不是字符串,而是 C char[]。如果代码是 println(String("Status :") + String(status)),那么转换和 concat 就可以了。如果代码是 println(String("Status :") + status) 您可能希望编译器会猜到要做什么。函数 println(String s) 不存在。所以编译器必须找到匹配的函数和转换才能得到 char[]。它会做什么,将 int 转换为 String,执行加法并将总和转换为 char[]?或者它会将字符串转换为 char[],然后执行添加?
  • 正如我所说,它是原型代码。我相信 bobwki 是正确的,尽管我读过的文档表明您可以添加它们。
【解决方案2】:

最后证明这实际上是一个内存问题。我包含的一个库非常大,它正在消耗可用内存。我通过添加更多调试语句发现了这一点,并发现损坏根据字符串长度和位置转移。通过使用 F() 函数,我将字符串移动到闪存中(例如,我现在运行 Serial.println(F("Starting...")); 它已经纠正了奇怪的输出。

【讨论】:

  • 这实际上是不正确的。虽然使用 F() 宏可以解决您的问题,但原因不是因为内存问题,而是因为上面 @jdr5ca 强调的类型转换问题。 "abcdef" 的类型为 const char *。将整数添加到const char * 的结果是移动指针,实质上是从字符串中删除字符。 "abcdef" + 2 == "cdef"F("abcdef") 具有类型 const __FlashStringHelper *,即它是不同的类型。
  • 嘿@GotWoods,我找到了你的问题,因为我遇到了同样的问题。我正在使用类型转换print("intValue: " + (String)theInt),它工作了一段时间但今晚崩溃了(不知道为什么)。我重构了我所有的 Serial 活动以遵循 @jdr5ca 的回答,这就像一个魅力。
【解决方案3】:

另一种可能的解释。

我正在运行 minicom 进行监控,我通常喜欢它在重置我的设备后自动重新连接。

好吧,我昨晚最小化了一个运行 minicom 的终端,今天我启动了一个新实例,该实例也以某种方式连接到了同一个串行端口(如果可能的话)。

我认为 minicom 的两个实例每个都大致随机读取约 50% 的串行字符,给我留下了相当混乱的文本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-03
    • 1970-01-01
    • 2013-01-25
    • 1970-01-01
    • 2014-08-23
    • 1970-01-01
    相关资源
    最近更新 更多