Arduino如何用多维数组存储PROGMEM中不定长RC5红外命令数组?
解决方案
你遇到的报错本质是C/C++ 静态数组的语法限制:多维数组除第一维外的所有维度长度必须是编译期固定值,你的每条指令延时数组长度不固定,自然无法直接用二维数组存储。最优方案是改用PROGMEM指针数组存储所有指令数组的首地址,所有数据全程存储在Flash中,不会占用RAM资源,实现逻辑也非常简单:
步骤1:保留已生成的指令数组
你之前用脚本生成的所有repeat_Command_{编号}格式的数组无需修改,保持原样存放在PROGMEM中即可。
步骤2:批量声明指令数组 + 定义指针索引数组
你可以直接用生成指令数组的同一份脚本,批量生成以下代码:
// 先批量声明所有指令数组,让编译器识别对应符号 extern const uint16_t repeat_Command_1[] PROGMEM; extern const uint16_t repeat_Command_2[] PROGMEM; // ... 以此类推,直到你所有2000条指令都声明完成 // 定义指针数组,每个元素对应一条指令数组的首地址,整体也存在PROGMEM中 const uint16_t * const all_commands[] PROGMEM = { repeat_Command_1, repeat_Command_2, // ... 按顺序填入所有指令数组的名称 };
这里的const uint16_t * const表示指针本身和指向的内容都是只读的,符合PROGMEM的存储特性。
步骤3:遍历调用指令
遍历的时候只需先从PROGMEM中读出对应索引的指令数组指针,直接传给sendRaw函数即可:
#include <avr/pgmspace.h> // 要包含PROGMEM读写头文件 // 遍历测试所有指令 for (uint16_t i = 0; i < 2000; i++) { // 从PROGMEM读取第i条指令的数组指针 const uint16_t *cmd_array = (const uint16_t *)pgm_read_ptr(&all_commands[i]); // 调用红外发射函数,你的sendRaw应该原生支持以65535U作为结束标记的不定长数组 sendRaw(cmd_array, 36000); // 第二个参数填RC5对应的36KHz载波频率 delay(1000); // 测试用延时,可自行调整 }
这个方案完全不需要修改你已有的指令生成逻辑,也不需要复杂的实时计算,所有存储开销都在Flash上,RAM仅占用循环变量的2字节空间,完全符合Arduino的资源限制。
内容的提问来源于stack exchange,提问作者Sebastian Scholz
相关产品推荐
相关产品推荐

