【发布时间】:2021-02-14 02:42:19
【问题描述】:
我正在尝试用 C++ 为我的 ESP32 构建一个转速计。当我在条件之外取消注释 Serial.printf("outside rev: %d \n", rev); 时,它可以工作,但是当我评论它时,我得到的值比它们应该的值大几个数量级(没有 700 转,有 7 转)。我最好的猜测是 print 语句正在减慢 loop() 的速度,足以让 incrementRevolutions() 在下一个循环之前将全局变量 passedMagnet 从 true 切换为 false。这是有道理的,因为延迟更新passedMagnet 将允许newRevCount++; 被多次触发。但鉴于竞态条件的时间敏感性,这显然是我无法使用打印语句或逐步调试来调试的。
bool passedMagnet = true;
int incrementRevolutions(int runningRevCount, bool passingMagnet)
{
// Serial.printf("passedMagnet: %d , passingMagnet %d , runningRevCount: %d \n", passedMagnet, passingMagnet, runningRevCount);
int newRevCount = runningRevCount;
if (passedMagnet && passingMagnet)
{ //Started a new pass of the magnet
passedMagnet = false;
newRevCount++;
}
else if (!passedMagnet && !passingMagnet)
{ //The new pass of the magnet is complete
passedMagnet = true;
}
return newRevCount;
}
unsigned long elapsedTime = 0;
unsigned long intervalTime = 0;
int rev = 0;
void loop()
{
intervalTime = millis() - elapsedTime;
rev = incrementRevolutions(rev, digitalRead(digitalPin));
// Serial.printf("outside rev: %d \n", rev);
if (intervalTime > 1000)
{
Serial.printf("rev: %d \n", rev);
rev = 0;
elapsedTime = millis();
}
}
这是 Arduino 或 C++ 编程的一个已知问题吗?我该怎么做才能解决它?
【问题讨论】:
-
是的,这是一个带有“C 编程”的已知“陷阱”,特别是:未定义的行为。代码中的某个地方存在一个您没有显示的错误,它最终会破坏内存,它表现为随机行为,当添加像 print 语句这样无辜的东西时,这种行为会发生变化。您需要在代码中未显示的某处找到错误并修复它。
-
完整的代码库没有更多内容。它可以在这里找到:github.com/jamesjmtaylor/esp32-ftms-server 你对我如何找到这个错误有什么建议吗?有没有推荐的分析器或其他调试工具?
-
为什么不使用 micros() 对其进行分析?看看有没有
Serial.printf()需要多长时间,你应该知道这是否是瓶颈 -
使用 micros() 我发现循环用了 33334 微秒,
Serial.printf()和 17708 没有,所以几乎是两倍长。 -
您使用的语言不是 C。它是与自定义标准库结合使用的 C++ 编译器
标签: c++ arduino esp32 arduino-ide arduino-c++