Arduino UNO命令行界面(CLI)实现:轻量级串口交互指南
为什么需要Arduino命令行界面?
在Arduino开发中,经常需要实时调试:读取传感器数值、控制电机动作、修改运行时变量、设置数字电位器参数等。通过串口监视器输入文本命令是最直观的交互方式。本文介绍一个简洁、高效、内存占用极小的命令行解析器,可在几分钟内集成到任何Arduino项目中。
核心设计特点
- 轻量级:使用C风格字符串而非String对象,节省宝贵的SRAM
- 自然语法:命令格式为
命名 参数1 参数2...,支持空格/逗号分隔 - 交互友好:支持退格键编辑、命令回显、错误提示
- 模块化:所有代码封装在
CommandLine.h单文件中,包含即用 - 可扩展:通过简单的if-else链添加新命令,大量命令可改用哈希表或switch-case优化
快速集成步骤
- 在Arduino IDE中创建新标签页,命名为
CommandLine.h - 将完整代码复制粘贴进去
- 在主程序中包含:
#include "CommandLine.h" - 在
loop()中调用两个核心函数:void loop() { bool received = getCommandLineFromSerialPort(CommandLine); if (received) DoMyCommand(CommandLine); }
核心代码架构解析
1. 缓冲区与解析器配置
#define COMMAND_BUFFER_LENGTH 25 // 命令缓冲区长度
char CommandLine[COMMAND_BUFFER_LENGTH + 1];
const char *delimiters = " , \n"; // 分隔符:空格、逗号、换行
2. 串口命令获取 getCommandLineFromSerialPort()
异步读取串口数据,处理退格键(\b)、回车(\r)、换行(\n),组装完整命令行至缓冲区,遇到结束符返回true。自动转小写统一大小写。
3. 参数解析辅助函数
// 读取下一个数字参数
int readNumber() {
char *numTextPtr = strtok(NULL, delimiters);
return atoi(numTextPtr);
}
// 读取下一个单词参数
char *readWord() {
return strtok(NULL, delimiters);
}
利用C标准库strtok()实现令牌化解析,首次调用传入字符串指针,后续调用传NULL继续解析。
4. 命令分发执行 DoMyCommand()
使用strtok()提取命令名,通过strcmp()匹配预定义命令令牌,调用对应处理函数,支持add、sub等示例命令,未知命令调用nullCommand()报错。
内置示例命令
| 命令 | 格式 | 功能 | 示例 |
|---|---|---|---|
add | add 数1, 数2 | 两数相加 | add 5, 10 → > The sum is = 15 |
sub | sub 数1, 数2 | 两数相减 | sub 10, 5 → > The difference is = 5 |
添加自定义命令指南
- 在
CommandLine.h顶部定义命令令牌常量:const char *myCommandToken = "mycmd"; //Modify here - 实现命令处理函数:
int myCommand() { int arg1 = readNumber(); char *arg2 = readWord(); // 业务逻辑... return result; } - 在
DoMyCommand()中添加分支:if (strcmp(ptrToCommandName, myCommandToken) == 0) { result = myCommand(); print2("> Result: ", result); }
调试宏与实用技巧
定义了print2(label, value)宏,一行代码打印标签和值,极大简化调试输出:
#define print2(x,y) (Serial.print(x), Serial.println(y))
// 使用示例:
print2("sensorVal = ", sensorVal);
// 输出:sensorVal = 512
进阶优化方向
- 命令哈希表:命令超过20个时,用哈希表替代if-else链,O(1)查找
- 参数预解析:在
DoMyCommand中统一解析所有参数到argv[]数组 - 命令行历史:添加上下键浏览历史命令功能
- 自动补全:Tab键提示可用命令
- 脚本支持:从SD卡读取批处理命令文件执行
完整代码获取
完整CommandLine.h源码包含在文章代码区,已添加详细注释标记//Modify here指示自定义位置。直接复制到新标签页即可使用,无需额外库依赖。
制造工艺