【发布时间】: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++