我最近开始为 Arduino 编码。代码中的这些错误正在杀死我。由于 Arduino 中没有硬件调试器,serial.print() 是我唯一的选择。您为调试 Arduino 代码而实施的方法/实践是什么?
如何调试 Arduino 草图?
模块化是你的朋友。编写你的主循环通过调用函数来完成它的事情,这些函数调用函数,......直到你的函数变得简单的级别。从主循环开始,下一层,制作存根函数;要么为空:
function foo(){
;
}
或假的:
function read_temperature(){
return(95);
}
,除了返回调用级别所需的任何内容以使其能够继续之外,什么都不做。当该级别工作时,向下移动一个级别并开始填写同样调用存根函数的简单代码。逐步取消存根一个函数,直到你有一个工作的应用程序。
要调试返回错误值的函数,或者创建一个不受应用程序其余部分影响的函数,您可以构建脚手架 - 一个简单的草图,只为函数提供一些示例值,并在函数内打印出参数值和一些中间值,直到您深入了解函数的哪一部分失败。我什至制作了在终端上提示我返回值的伪造函数。(显然,这种技术只有在系统能够承受我们人类相对冰川速度的情况下才能工作!脚手架的另一种用途。)
存根特别适合代替与硬件接口的功能,允许您在必须深入研究数据表、时序问题和其他可能会停止的细节(例如,没有零件!)之前启动应用程序你的进步。
说到时序问题,在程序中的特定点切换输出引脚,例如进入和退出 ISR,会在 Arduino 引脚处为您提供方波,其频率或占空比可以让您深入了解内部时序你的程序。直接端口 I/O 形式,例如,
PORTC ^= 0x01;
, 会扭曲时间小于调用digitalWrite()
。如果您手边有一个示波器,或者其中一个能够测量频率和/或占空比的数字万用表,这很有用。
同样,您可以使用模拟输出引脚从程序内部将数值输出到仪表,而不会过多地干扰时序或使用串行 I/O 功能使代码膨胀。在这里也使用直接 I/O 形式。
我使用 Serial.print() 并让 LED 闪烁。
这几乎就是你能做的。
此外,我确保代码可读且易于理解。将事情分解为简单的步骤并为每个步骤创建函数,这样您就可以查看事件的确切顺序。
3 其他技术:
通过在每个阶段缓慢测试来构建程序的功能,这样您一次只面对一小部分错误。
围绕命令解释器构建程序,这样您就可以像 这里一样一次处理部分。
在重要的时间跳出并使用示波器。
Visual Studio的Visual Micro插件提供Arduino Debug。包括源代码跟踪和中断还允许“监视”和/或修改表达式和变量。