#include "ecg_generator.h" #include #include #include "esp_log.h" // 初始化ECG生成器 void ecg_generator_init(ecg_generator_t *generator, float sample_rate) { if (generator == NULL) return; memset(generator, 0, sizeof(ecg_generator_t)); // 设置默认参数 generator->heart_rate = 75.0f; // 心率75次/分 generator->amplitude = 1.0f; // 幅值1.0V generator->sample_rate = sample_rate; generator->is_running = false; // 固定波形参数 (保持正常ECG比例) generator->p_amp_ratio = 0.2f; // P波幅度比例 generator->q_amp_ratio = 0.3f; // Q波幅度比例 generator->r_amp_ratio = 1.0f; // R波幅度比例 generator->s_amp_ratio = 0.4f; // S波幅度比例 generator->t_amp_ratio = 0.4f; // T波幅度比例 // 固定时间参数 (保持正常ECG时序) generator->p_width = 0.03f; // P波宽度 generator->qrs_width = 0.01f; // QRS波群宽度 generator->t_width = 0.05f; // T波宽度 } // 设置心率 void ecg_generator_set_heart_rate(ecg_generator_t *generator, float heart_rate) { if (generator == NULL) return; // 限制心率范围 if (heart_rate < 30.0f) heart_rate = 30.0f; if (heart_rate > 200.0f) heart_rate = 200.0f; generator->heart_rate = heart_rate; } // 设置幅值(直接输入mV值,内部自动转换为DAC输出值) void ecg_generator_set_amplitude(ecg_generator_t *generator, float amplitude_mv) { if (generator == NULL) return; // 硬件衰减系数:约38倍 (根据实际测量:0.132V → 5mV) // 对应关系:amplitude(V) × 38 ≈ 示波器显示值(mV) const float attenuation_factor = 38.0f; // 将mV除以衰减系数得到DAC输出值 float dac_amplitude = amplitude_mv / attenuation_factor; generator->amplitude = dac_amplitude; } // 开始生成 void ecg_generator_start(ecg_generator_t *generator) { if (generator == NULL) return; generator->is_running = true; generator->sample_count = 0; } // 停止生成 void ecg_generator_stop(ecg_generator_t *generator) { if (generator == NULL) return; generator->is_running = false; } // 重置生成器 void ecg_generator_reset(ecg_generator_t *generator) { if (generator == NULL) return; generator->sample_count = 0; } // 获取下一个样本 - 修正时间参数为相对比例 float ecg_generator_get_next_sample(ecg_generator_t *generator) { if (generator == NULL || !generator->is_running) { return 0.0f; } // 计算RR间期 (秒) float rr_interval = 60.0f / generator->heart_rate; // 计算当前时间 float t = (float)generator->sample_count / generator->sample_rate; // 周期内时间 float t_mod = fmodf(t, rr_interval); // 归一化时间到0-1范围(相对于RR间期的比例) float t_norm = t_mod / rr_interval; // 计算各波幅度 float p_amp = generator->amplitude * generator->p_amp_ratio; float q_amp = generator->amplitude * generator->q_amp_ratio; float r_amp = generator->amplitude * generator->r_amp_ratio; float s_amp = generator->amplitude * generator->s_amp_ratio; float t_amp = generator->amplitude * generator->t_amp_ratio; // 时间参数(相对于RR间期的比例) - 根据Python代码修正 float p_time_ratio = 0.125f; // P波位置:12.5% float q_time_ratio = 0.3125f; // Q波位置:31.25% float r_time_ratio = 0.3375f; // R波位置:33.75% float s_time_ratio = 0.3625f; // S波位置:36.25% float t_time_ratio = 0.625f; // T波位置:62.5% // 宽度参数(相对于RR间期的比例) - 修正QRS宽度使其充分重叠 float p_width_ratio = 0.0375f; // P波宽度:0.03/0.8 = 3.75% float qrs_width_ratio = 0.0125f; // QRS宽度:增加到2.5%,确保Q、R、S充分重叠 float t_width_ratio = 0.0625f; // T波宽度:0.05/0.8 = 6.25% // P波 - 修正后的计算 float p = p_amp * expf(-(t_norm - p_time_ratio) * (t_norm - p_time_ratio) / (2.0f * p_width_ratio * p_width_ratio)); // QRS波群 - 修正后的计算 float q = -q_amp * expf(-(t_norm - q_time_ratio) * (t_norm - q_time_ratio) / (2.0f * qrs_width_ratio * qrs_width_ratio)); float r = r_amp * expf(-(t_norm - r_time_ratio) * (t_norm - r_time_ratio) / (2.0f * qrs_width_ratio * qrs_width_ratio)); float s = -s_amp * expf(-(t_norm - s_time_ratio) * (t_norm - s_time_ratio) / (2.0f * qrs_width_ratio * qrs_width_ratio)); float qrs = q + r + s; // T波 - 修正后的计算 float t_wave = t_amp * expf(-(t_norm - t_time_ratio) * (t_norm - t_time_ratio) / (2.0f * t_width_ratio * t_width_ratio)); // 组合波形 float ecg_value = p + qrs + t_wave; // 调试信息:每1000个样本输出一次最大值 static float max_ecg_value = 0.0f; static uint32_t debug_counter = 0; debug_counter++; if (fabsf(ecg_value) > max_ecg_value) { max_ecg_value = fabsf(ecg_value); } if (debug_counter >= 1000) { ESP_LOGI("ECG_DEBUG", "Max ECG value before offset: %.3fV", max_ecg_value); debug_counter = 0; max_ecg_value = 0.0f; } // 添加偏置电压,将ECG波形平移到DAC有效范围 // ECG波形范围约为 -amplitude 到 +amplitude // 需要平移到 0 到 2*amplitude,然后限制在DAC范围内 float offset = generator->amplitude; // 偏置电压 ecg_value = ecg_value + offset; // 限制在DAC有效范围内 (0V 到 2.048V) if (ecg_value < 0.0f) ecg_value = 0.0f; if (ecg_value > 2.048f) ecg_value = 2.048f; generator->sample_count++; return ecg_value; }