不使用delay()实现时移?Arduino电位器波形延迟故障求助
问题分析与解决方案
原代码核心问题
- calc函数逻辑错误:
- 原代码每次调用
calc()都会把缓冲区所有元素覆盖为当前输入uk,完全无法实现延迟效果。 - 访问
x[k]属于数组越界(数组下标范围是0到k-1),会导致内存访问错误,这是延迟波形无输出的直接原因。
- 原代码每次调用
- 变量类型不匹配:
- 输入
uk是unsigned int类型,但缓冲区x是int类型,可能导致模拟读数(0-1023)被错误转换。 k作为缓冲区长度,应该用整数类型(如uint16_t),避免浮点数运算带来的精度问题。
- 输入
- 构造参数错误:
- 初始化
delayBox1时传入的延迟时间是0.3秒,与需求的0.5秒不符。
- 初始化
修正后的完整代码
unsigned int data; const float sample_time = 0.01f; const float delay_time = 0.5f; uint32_t start_Time; uint32_t MicroSampleTime; class delayBox { public: delayBox(float delay_time, float Ts); ~delayBox(); void calc(); public: unsigned int uk; // 当前输入 unsigned int yk; // 延迟输出 private: unsigned int* buffer; // 延迟缓冲区 uint16_t buffer_len; // 缓冲区长度(延迟样本数) }; delayBox* delayBox1; void setup() { Serial.begin(115200); // 传入正确的延迟时间0.5秒 delayBox1 = new delayBox(delay_time, sample_time); MicroSampleTime = static_cast<uint32_t>(sample_time * 1e6); start_Time = micros() + MicroSampleTime; } void loop() { data = analogRead(A0); delayBox1->uk = data; delayBox1->calc(); Serial.print(data); Serial.print(" "); Serial.println(delayBox1->yk); // 非阻塞延时逻辑(保持原逻辑) while (!((start_Time - micros()) & 0x80000000)); start_Time += MicroSampleTime; } delayBox::delayBox(float delay_time, float Ts) { // 计算需要的样本数,强制转换为整数 buffer_len = static_cast<uint16_t>(delay_time / Ts); // 分配缓冲区内存,类型匹配为unsigned int buffer = new unsigned int[buffer_len]; // 初始化缓冲区为0 for (uint16_t i = 0; i < buffer_len; ++i) { buffer[i] = 0; } } void delayBox::calc() { // 缓冲区移位:将所有元素向前移动一位,丢弃最旧的元素 for (uint16_t i = 0; i < buffer_len - 1; ++i) { buffer[i] = buffer[i + 1]; } // 将当前输入放入缓冲区末尾 buffer[buffer_len - 1] = uk; // 输出缓冲区最前面的元素(即k个样本前的输入) yk = buffer[0]; } delayBox::~delayBox() { // 释放缓冲区内存,避免内存泄漏 delete[] buffer; }
关键修正点说明
- 缓冲区逻辑:
calc()函数改为移位缓冲区:每次将缓冲区元素向前移动一位,把当前输入放到缓冲区最后,然后取出缓冲区第一个元素作为延迟输出,实现k = delay_time/sample_time个样本的延迟(即0.5秒)。
- 类型修正:
- 缓冲区
buffer改为unsigned int类型,与输入uk、模拟读数类型一致,避免数据转换错误。 buffer_len用uint16_t类型,确保是正整数,符合数组长度要求。
- 缓冲区
- 内存管理:
- 析构函数中添加
delete[] buffer,避免Arduino长时间运行后的内存泄漏。
- 析构函数中添加
- 参数修正:
- 初始化
delayBox1时传入delay_time(0.5秒),匹配需求。
- 初始化
修改后,串口绘图仪将正常显示电位器波形和延迟0.5秒的波形,且全程不使用delay()函数。
内容的提问来源于stack exchange,提问作者o01
相关产品推荐
相关产品推荐

