# PSV **Repository Path**: MagicBude/PSV ## Basic Information - **Project Name**: PSV - **Description**: 轻量级周期信号验证器 - 基于变异系数统计检测真实周期信号,过滤随机干扰。适用于流量计、转速、心率等传感器应用。 - **Primary Language**: C - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-11-07 - **Last Updated**: 2025-11-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: 嵌入式, 信号处理, stm32, 传感器, 滤波器 ## README # PSV - Periodic Signal Validator > **PSV = Periodic Signal Validator(周期信号验证器)** [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Language: C](https://img.shields.io/badge/Language-C-blue.svg)](https://en.wikipedia.org/wiki/C_(programming_language)) [![Platform: Embedded](https://img.shields.io/badge/Platform-Embedded-green.svg)]() [English](README.en.md) | 简体中文 基于周期规律性检测信号质量,区分真实周期信号和随机干扰。 ## ✨ 特性 - ✅ **轻量级**:约60字节RAM,无动态内存分配 - ✅ **跨平台**:支持STM32、Arduino、Linux等 - ✅ **易集成**:3个API函数,简单易用 - ✅ **可配置**:所有参数可在config.h中调整 - ✅ **低开销**:CPU占用<1%(72MHz MCU,1kHz信号) ## 📋 目录 - [原理说明](#原理说明) - [应用场景](#应用场景) - [快速开始](#快速开始) - [API文档](#api文档) - [移植指南](#移植指南) - [参数调整](#参数调整) - [示例代码](#示例代码) ## 🔬 原理说明 ### 核心算法:周期变异系数(CV) ``` CV = 标准差 / 均值 真实周期信号:CV < 0.1 (周期非常规律) 轻微波动信号:CV = 0.1 ~ 0.15 明显波动信号:CV = 0.15 ~ 0.25 干扰信号: CV > 0.3 (周期杂乱无章) ``` ### 检测流程 ``` 每个频率脉冲到达时: ├─ 1. 频率在量程内? ──No──> 拒绝 ├─ 2. 频率变化率正常?──No──> 拒绝 ├─ 3. 周期规律性好? ──No──> 拒绝 ├─ 4. 连续稳定≥N次? ──No──> 等待更多数据 └─ Yes ──> 接受信号 ``` ## 🎯 应用场景 ### 流量传感器 - ✅ 涡街流量计(压电陶瓷) - ✅ 涡轮流量计(霍尔传感器) - ✅ 齿轮流量计(光电传感器) - ✅ 电磁流量计(频率输出) ### 转速测量 - ✅ 电机转速传感器 - ✅ 车轮转速(ABS) - ✅ 风扇转速监测 ### 生物信号 - ✅ 心率监测(PPG) - ✅ 脉搏血氧 - ✅ ECG信号处理 ### 振动监测 - ✅ 压电传感器 - ✅ 地震监测 - ✅ 设备振动分析 ## 🚀 快速开始 ### 1. 添加源文件到项目 ``` your_project/ ├── psv/ │ ├── psv.h │ ├── psv.c │ └── psv_config.h ``` ### 2. 配置平台依赖(psv_config.h) ```c /* 修改这里以适配你的平台 */ #define PSV_GET_TICK_MS() HAL_GetTick() // 改成你的时间函数 /* 设置你的频率范围 */ #define PSV_FREQ_MIN_HZ 10 // 最小频率 #define PSV_FREQ_MAX_HZ 1000 // 最大频率 ``` ### 3. 在代码中使用 ```c #include "psv.h" /* 初始化 */ psv_init(); /* 在频率采集回调中检测 */ void frequency_callback(uint32_t freq) { if (psv_check(freq)) /* 返回1=有效信号 */ { /* 有效信号,进行后续处理 */ process_valid_signal(freq); } else { /* 检测到干扰,忽略 */ } } ``` ## 📚 API文档 ### 初始化函数 ```c void psv_init(void); ``` 初始化PSV模块,清空所有状态。 ### 检测函数 ```c uint8_t psv_check(uint32_t freq_hz); ``` 检测频率信号质量。 **参数**: - `freq_hz`:当前频率(Hz) **返回值**: - `1`:有效信号 - `0`:干扰信号 ### 复位函数 ```c void psv_reset(void); ``` 复位检测状态,用于信号丢失或超时时。 ### 统计函数 ```c void psv_get_statistics(PSV_Statistics_t *stats); ``` 获取统计信息,用于调试。 **返回统计信息**: ```c typedef struct { float cv; /* 当前变异系数 */ float mean_period_us; /* 平均周期(微秒) */ float std_dev_us; /* 标准差(微秒) */ uint8_t sample_count; /* 采样数量 */ uint8_t is_locked; /* 信号是否锁定 */ } PSV_Statistics_t; ``` ## 🔧 移植指南 ### STM32 HAL ```c // psv_config.h #define PSV_GET_TICK_MS() HAL_GetTick() ``` ### FreeRTOS ```c // psv_config.h #define PSV_GET_TICK_MS() (xTaskGetTickCount() * portTICK_PERIOD_MS) ``` ### Arduino ```c // psv_config.h #define PSV_GET_TICK_MS() millis() ``` ### Linux ```c // psv_config.h #include static inline uint32_t get_tick_ms(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return ts.tv_sec * 1000 + ts.tv_nsec / 1000000; } #define PSV_GET_TICK_MS() get_tick_ms() ``` ## ⚙️ 参数调整 ### 频率范围 根据你的传感器量程设置: ```c #define PSV_FREQ_MIN_HZ 10 // 最小有效频率 #define PSV_FREQ_MAX_HZ 1000 // 最大有效频率 ``` ### CV阈值(最重要) 根据信号质量调整: | 应用场景 | 推荐阈值 | 说明 | |---------|---------|------| | 高稳定信号 | 0.10 | 严格,适合实验室 | | 标准应用 | 0.15 | 平衡,推荐 | | 波动较大 | 0.20~0.25 | 宽松,工业现场 | ```c #define PSV_PERIOD_CV_THRESHOLD 0.15f ``` ### 调试方法 1. 启用日志输出: ```c #define PSV_USE_LOG 2 // 使用printf ``` 2. 观察CV值: ``` [PSV DEBUG] CV=0.082 → 稳定信号(通过) [PSV DEBUG] CV=0.420 → 干扰信号(拒绝) ``` 3. 根据实际数据调整阈值 ## 📖 示例代码 ### 示例1:涡街流量计 ```c #include "psv.h" void vortex_flowmeter_init(void) { psv_init(); /* 配置定时器输入捕获... */ } void TIM_Capture_IRQHandler(void) { uint32_t freq = calculate_frequency(); /* 计算频率 */ if (psv_check(freq)) /* PSV检测 */ { /* 有效信号,更新流量 */ update_flow_rate(freq); } } ``` ### 示例2:电机转速 ```c #include "psv.h" void motor_speed_init(void) { psv_init(); } void hall_sensor_callback(uint32_t rpm) { if (psv_check(rpm)) { display_motor_speed(rpm); } } ``` ### 示例3:心率监测 ```c #include "psv.h" void heart_rate_init(void) { psv_init(); } void ppg_sensor_callback(uint32_t bpm) { if (psv_check(bpm)) /* 过滤运动干扰 */ { display_heart_rate(bpm); } } ``` ### 示例4:Linux信号仿真 ```c #include "psv.h" /* 在PC上验证PSV算法 */ int main() { psv_init(); /* 生成模拟信号并检测 */ for (int i = 0; i < 100; i++) { uint32_t freq = generate_signal(); // 生成测试信号 if (psv_check(freq)) { printf("频率 %u Hz: 有效\n", freq); } } /* 查看统计信息 */ PSV_Statistics_t stats; psv_get_statistics(&stats); printf("准确率: %.1f%%\n", calculate_accuracy(&stats)); } ``` **完整示例**:查看 `examples/` 目录 ## 🐛 常见问题 ### Q1: 稳定信号也被拒绝? **A**: 提高 `PSV_PERIOD_CV_THRESHOLD`(如0.20) ### Q2: 干扰信号未被过滤? **A**: 降低 `PSV_PERIOD_CV_THRESHOLD`(如0.10) ### Q3: 响应太慢? **A**: 降低 `PSV_STABLE_COUNT_MIN`(如改为2) ### Q4: 如何调试? **A**: 启用日志(`PSV_USE_LOG=2`),观察CV值 ## 📊 性能指标 | 指标 | 数值 | |-----|------| | RAM占用 | ~60字节 | | Flash占用 | ~1.5KB | | CPU占用 | <1%(72MHz,1kHz信号) | | 响应延迟 | 0.5~1秒(首次锁定) | ## 📄 许可证 本项目采用 MIT 许可证 - 详见 [LICENSE](LICENSE) 文件 ## 🤝 贡献 欢迎提交Issue和Pull Request! ## 🌟 Star支持 如果这个项目对您有帮助,请给个⭐Star支持一下! ## 📮 贡献与反馈 - 💡 **提交Issue**:[Issues](../../issues) - 🔀 **Pull Request**:欢迎贡献代码 - 📧 **问题讨论**:欢迎在Issues中讨论 ## 🙏 致谢 感谢所有贡献者和使用者! --- **版本**: v1.0.0 **更新**: 2025-11-07 **状态**: ✅ 生产可用 **许可**: MIT License