【问题标题】:sprintf causing timing-issues?sprintf 导致时间问题?
【发布时间】:2020-09-12 20:44:09
【问题描述】:

我在使用 sprintf 时遇到了一个奇怪的问题。

我需要一个 char 数组,看起来像这样:g;cmd;arg;e;,其中 arg 得到前导零,所以它总是 3 个字符长,而 cmd 得到前导零,所以它总是 15 个字符长。 例如,如果 cmd = 20 且 arg = 3749,我需要一个如下所示的 char 数组:g;020;000000000003749;e;。 arg 和 cmd 都是整数。

我最初以非常低效的方式完成了这项工作,但我使用 sprintf 将其更改为更简单的方式,因为我需要我的代码更快。我的初始代码和我的更改都可以在 on github 找到。

我当前的实现如下所示:

#define cmdMsgLength 3
#define argMsgLength 15
#define totalFormatedMsgLength (2+cmdMsgLength+1+argMsgLength+3)
#define msgFormater "g;%03d;%015d;e;"

char msgToSendFormated[totalFormatedMsgLength];
void sendMsg(int _cmd, int _arg) {
 sprintf(msgToSendFormated, msgFormater, _cmd, _arg);
 Serial.print(msgToSendFormated);
}

这似乎运作良好,直到我的 uC 还必须控制 4 个 ESC。老实说,我找不到两者之间的任何关系,但似乎这种实现会导致 ESC 出现问题,当然时间非常重要。 ESC 的编程正确,但是当使用 Arduino 函数servo.writeMicroseconds 来驱动它们时,它们似乎是随机的。经过大量测试后,似乎只有对我的代码的这种更改才引起了问题。由于这段代码非常简单,而且旧代码(查看 github 链接)也使用了 Serial.print,我认为 sprintf 是罪魁祸首。

是否已知 sprintf 会导致此类时间问题?会不会是别的?

【问题讨论】:

  • 你在长度计算中没有忘记空终止符吗?
  • @JVApen,在这种情况下是否需要空终止符? sprintf 对我来说是新的,但是由于代码实际上通过 uart 发送了我期望的内容,我认为我正确地实现了它。你是说 msgToSendFormated 应该大 1 个字符吗?
  • sprintf 会写,据我所知,是的,这确实是我要说的
  • @JVApen 确实有效。我应该多研究一下 sprintf 。非常感谢!
  • 如果您所做的只是将其发送到 Serial 中,那么只需连续使用多个 Serial.print 语句并将其发送出去会更快,代码效率更高。由于串行数据被缓冲并且速度很慢,实际传输将是相同的,接收器永远不会知道差异。这将是更多的行,但更小的代码。 sprintf 是一个非常昂贵的函数。

标签: arduino microcontroller arduino-c++


【解决方案1】:

正如 JVApen 指出的,sprintf 总是写一个空终止符。由于 msgToSendFormated 不够长,所以我会溢出。设置char msgToSendFormated[totalFormatedMsgLength + 1]; 解决了这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-08
    • 2017-01-08
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    • 2022-01-13
    • 2022-08-04
    相关资源
    最近更新 更多