
简介这份PDF是2021年全国大学生电子设计竞赛本科组H题「用电器分析识别装置」的完整赛题文档面向备战电赛的高校学生与指导教师帮助读者快速掌握题目任务、指标约束与评分细则。资源包共1个PDF文件约315KB内容为官方试题原文涵盖学习与分析识别两种工作模式、5mA至10.0A电流范围、不少于7种电器识别、自制1号电器等基本要求以及学习功能、大小电流共用识别、工作电流不大于15mA等发挥部分并附评分标准与框图说明。已有1890人学习下载适合作为方案设计与指标拆解的第一手依据。读者可据此梳理电流互感器采样、特征参量筛选、微控制器编程与无线传输显示等关键技术点对照评分表规划电路与程序设计明确理论分析与测试结果撰写方向为系统搭建和赛前演练提供清晰的任务边界与验收标准。1. 用电器分析识别装置H题从电流波形到电器身份的完整拆解第一次拿到「用电器分析识别装置」这个题目时很多人会下意识地往「智能插座」方向想——测个功率、看个电流然后判断这是不是电吹风。但真正动手之后你会发现难点根本不在测量而在区分。两台功率相近的电器比如电风扇和空气净化器稳态电流有效值可能只差几十毫安靠单一功率阈值根本分不开。这个题目的核心是通过电流波形中隐藏的谐波特征、启动瞬态和功率因数差异把「用电器的电气指纹」提取出来再交给分类器做身份判定。它适合谁适合做过单片机采集、想往信号特征工程方向走的人也适合参加电子设计类题目、需要一套可复现识别链路的同学。整套方案不依赖昂贵设备一个电流互感器加一个采样电阻配合一块带 ADC 的主控板就能跑通。下面按「先立理论、再搭硬件、再做特征、再训分类器、最后避坑」的顺序把这条链路完整讲一遍。2. 电流波形里到底藏着什么从采样到特征量的理论底座2.1 为什么只看功率一定翻车假设你面前有两台设备一台标称 60W 的电风扇一台标称 55W 的空气净化器。用功率计读出来的稳态有功功率分别是 58.3W 和 54.7W差距不到 4W。如果环境温度变化导致风扇转速微调这个差距还会进一步缩小。更麻烦的是很多电器的功率会随负载波动比如吹风机在不同档位之间切换功率跨度可能从 200W 跳到 1800W。所以单一功率阈值只能做「粗筛」不能做「识别」。真正稳定的区分依据来自电流波形的形状。不同电器内部的电路拓扑不同电阻类负载电热丝电流波形接近正弦感性负载电机电流滞后于电压波形有相位差开关电源类负载充电器、LED 灯电流波形是尖峰脉冲谐波含量极高。这些差异在时域上表现为波形畸变在频域上表现为各次谐波幅值比例不同。2.2 用电流互感器把波形「搬」进 ADC 量程常见做法是使用电流互感器CT配合采样电阻把一次侧的大电流按比例转换成二次侧的小电压。以 1000:1 的 CT 为例一次侧流过 1A 时二次侧输出 1mA。这个电流流过一个 100Ω 的采样电阻得到 0.1V 的电压信号。如果主控 ADC 的参考电压是 3.3V单极性采样还需要加一个偏置电路把信号抬到 1.65V 附近保证负半周也能被采到。具体电路参数可以这样定采样电阻取 100Ω偏置电阻用两个 10kΩ 等值电阻分压得到 1.65V再通过一个电压跟随器缓冲后接入 ADC。CT 二次侧并联一个 100Ω 的 burden 电阻把电流转成电压。注意这个 burden 电阻不能太大否则会破坏 CT 的线性度也不能太小否则信号幅度不够信噪比下降。提示CT 的相位误差在 50Hz 附近通常最小但如果你要分析高次谐波相位误差会随频率升高而增大。选型时优先看 datasheet 里的相位误差曲线别只看变比。2.3 采样率与采样窗口怎么定要分析到 21 次谐波1050Hz根据奈奎斯特采样定理采样率至少要到 2100Hz。但工程上一般取 10 倍以上余量所以采样率定在 4kHz 到 10kHz 之间比较稳妥。我一般会选 6.4kHz这样每个 50Hz 工频周期正好采 128 个点做 FFT 时窗口长度取 128 的整数倍频谱泄漏最小。采样窗口长度取 10 个工频周期也就是 200ms对应 1280 个采样点。这个长度足够覆盖启动瞬态和稳态过程。如果你只想看稳态特征可以等电器运行 2 秒后再开始采样跳过启动冲击。但启动瞬态本身也是重要特征——电机类负载启动电流可能是稳态的 3 到 5 倍而电阻类负载几乎无冲击。2.4 从时域到频域FFT 之后取哪些量对 1280 点做 FFT得到 640 个频点分辨率是 5Hz。我们只关心 50Hz 及其整数倍附近的频点。具体取 1 到 21 次谐波的幅值然后做归一化把各次谐波幅值除以基波幅值得到谐波含有率。这样做的目的是消除绝对幅值的影响让不同功率等级的同类电器也能被归到同一类。除了谐波含有率还要算三个时域特征电流有效值、波峰因数峰值除以有效值、功率因数有功功率除以视在功率。波峰因数对开关电源类负载特别敏感因为它们的电流是尖峰脉冲波峰因数可能到 2.5 以上而电阻类负载的波峰因数接近 1.414。3. 硬件选型与采集固件把 1280 个点稳定送进内存3.1 主控与 ADC 的搭配逻辑如果只是做实验STM32F103 系列就够用它的 ADC 最高 1MHz 采样率12 位分辨率配合 DMA 可以无 CPU 干预地搬运数据。但要注意F103 的 ADC 在最快采样率下有效位数会下降实际能稳定到 10 位左右。如果对精度要求高可以选带外部 ADC 的方案比如 ADS8688 这类 16 位 8 通道芯片通过 SPI 读取。我一般会这样搭配主控用 STM32F407主频 168MHzADC 用外部 16 位芯片采样率设 6.4kHzDMA 缓冲区开 1280 个半字。定时器触发 ADC 转换保证采样间隔严格均匀。均匀采样是 FFT 的前提如果采样间隔抖动频谱会糊掉。3.2 定时器触发与 DMA 搬运的配置代码下面是一段基于 HAL 库的初始化代码展示如何用 TIM2 触发 ADC再用 DMA 把数据搬到缓冲区。// 定时器 TIM2 配置6.4kHz 触发频率 // 假设 APB1 定时器时钟为 84MHz // 预分频器设为 0自动重装载值 84MHz / 6.4kHz - 1 13124 htim2.Instance TIM2; htim2.Init.Prescaler 0; htim2.Init.CounterMode TIM_COUNTERMODE_UP; htim2.Init.Period 13124; htim2.Init.ClockDivision TIM_CLOCKDIVISION_DIV1; HAL_TIM_Base_Init(htim2); // ADC 配置外部触发触发源选 TIM2 TRGO hadc1.Instance ADC1; hadc1.Init.Resolution ADC_RESOLUTION_12B; hadc1.Init.ScanConvMode DISABLE; hadc1.Init.ContinuousConvMode DISABLE; hadc1.Init.ExternalTrigConv ADC_EXTERNALTRIGCONV_T2_TRGO; hadc1.Init.DataAlign ADC_DATAALIGN_RIGHT; HAL_ADC_Init(hadc1); // DMA 配置循环模式半字宽度缓冲区 1280 点 hdma_adc1.Instance DMA2_Stream0; hdma_adc1.Init.Channel DMA_CHANNEL_0; hdma_adc1.Init.Direction DMA_PERIPH_TO_MEMORY; hdma_adc1.Init.PeriphInc DMA_PINC_DISABLE; hdma_adc1.Init.MemInc DMA_MINC_ENABLE; hdma_adc1.Init.PeriphDataAlignment DMA_PDATAALIGN_HALFWORD; hdma_adc1.Init.MemDataAlignment DMA_MDATAALIGN_HALFWORD; hdma_adc1.Init.Mode DMA_CIRCULAR; hdma_adc1.Init.Priority DMA_PRIORITY_HIGH; HAL_DMA_Init(hdma_adc1); __HAL_LINKDMA(hadc1, DMA_Handle, hdma_adc1); // 启动 HAL_ADC_Start_DMA(hadc1, (uint32_t*)adc_buffer, 1280); HAL_TIM_Base_Start(htim2);这段代码的关键点有三个。第一Period值决定了采样率计算公式是定时器时钟 / (Prescaler1) / (Period1)这里 84MHz 除以 13125 正好是 6400Hz。第二ADC 的ContinuousConvMode要关掉否则它会自己连续转换不受定时器控制。第三DMA 用循环模式这样缓冲区满了之后会自动从头覆盖不会触发中断风暴。你只需要在需要分析的时候把缓冲区里的 1280 个点拷出来就行。3.3 偏置校准与量程映射ADC 读到的原始值是 0 到 4095对应 0 到 3.3V。但我们的信号是围绕 1.65V 波动的交流信号所以要先减去偏置对应的码值。偏置码值怎么定在电器断电时采 1000 个点取平均就是零电流时的 ADC 读数记为offset。之后每次采样实际电压等于(raw - offset) * 3.3 / 4096。再根据 CT 变比和 burden 电阻把电压换算成一次侧电流。假设 CT 变比 1000:1burden 电阻 100Ω那么一次侧电流I V_adc / 100Ω * 1000。注意这里的单位是安培如果 ADC 读到的电压是 0.1V对应一次侧电流就是 1A。注意偏置电压会随温度漂移长时间运行后要重新校准。我一般会在固件里加一个「零电流检测」逻辑如果连续 10 个周期的有效值都低于阈值就自动更新 offset。4. 特征工程与分类器把波形变成可判别的向量4.1 谐波含有率的计算与归一化拿到 1280 个采样点后先做去均值处理然后加汉宁窗再做 FFT。汉宁窗的作用是减少频谱泄漏代价是主瓣变宽但对我们只关心整数次谐波幅值的场景来说这个代价可以接受。FFT 之后取 50Hz 对应的频点索引。假设采样率 6400HzFFT 点数 1280频率分辨率是 5Hz。50Hz 对应第 10 个频点100Hz 对应第 20 个以此类推。取第 1 到 21 次谐波的幅值记为A1到A21。然后计算谐波含有率Hn An / A1其中n从 2 到 21。这样得到一个 20 维的谐波特征向量。再加上三个时域特征电流有效值Irms、波峰因数Crest Ipeak / Irms、功率因数PF P / (Vrms * Irms)。总共 23 维特征。4.2 用 Python 做特征提取的参考实现下面这段 Python 代码展示了从原始采样数据到特征向量的完整流程。假设raw_data是一个长度为 1280 的列表sample_rate是 6400ct_ratio是 1000burden是 100。import numpy as np def extract_features(raw_data, sample_rate6400, ct_ratio1000, burden100): # 去均值 data np.array(raw_data, dtypefloat) data data - np.mean(data) # 电压换算ADC 码值转电压再转一次侧电流 # 假设 ADC 是 12 位参考电压 3.3V voltage data * 3.3 / 4096 current voltage / burden * ct_ratio # 时域特征 irms np.sqrt(np.mean(current ** 2)) ipeak np.max(np.abs(current)) crest ipeak / irms if irms 0 else 0 # 加汉宁窗 window np.hanning(len(current)) windowed current * window # FFT fft_result np.fft.rfft(windowed) fft_mag np.abs(fft_result) # 频率分辨率 freq_res sample_rate / len(current) # 取 1 到 21 次谐波幅值 harmonics [] for n in range(1, 22): freq 50 * n idx int(round(freq / freq_res)) if idx len(fft_mag): harmonics.append(fft_mag[idx]) else: harmonics.append(0) # 谐波含有率归一化 a1 harmonics[0] if harmonics[0] 0 else 1e-9 hcr [h / a1 for h in harmonics[1:]] # 2 到 21 次 # 功率因数需要额外测量电压这里用占位值 # 实际系统中需要同步采集电压波形 pf 0.95 # 占位 feature_vector [irms, crest, pf] hcr return np.array(feature_vector)这段代码的逻辑很直接先去均值消除直流偏置再把 ADC 码值映射回一次侧电流。时域特征里irms反映负载大小crest反映波形尖峰程度pf反映相位关系。频域特征里hcr是归一化后的谐波含有率消除了绝对幅值影响。最终拼接成一个 23 维向量。参数说明sample_rate必须和实际采样率一致否则频点索引会错位。ct_ratio和burden要根据硬件实际值填写填错会导致电流幅值整体缩放虽然对归一化后的谐波含有率影响不大但会影响irms和crest的绝对值。4.3 分类器选型为什么我优先用轻量级模型特征向量只有 23 维样本量也不会太大通常每种电器采几十到几百个样本这种场景下深度学习模型容易过拟合。我一般会先试三种轻量级分类器KNN、SVM 和随机森林。KNN 的优点是无需训练新增样本直接加进去就行适合快速验证。缺点是预测时要遍历所有训练样本如果样本量到几千推理速度会下降。SVM 在中小样本上表现稳定尤其是 RBF 核对非线性边界拟合能力强。随机森林对特征尺度不敏感还能输出特征重要性方便你判断哪些谐波含有率对区分贡献最大。实际部署时如果主控是 MCUSVM 的推理可以用查表法或者定点数近似随机森林则可以直接把树结构转成 if-else 语句。KNN 在 MCU 上不太现实因为要存所有训练样本。4.4 训练与验证的划分策略采集数据时每种电器至少采 200 个样本其中 150 个做训练50 个做测试。注意训练集和测试集要来自不同的采集批次避免同一批次的数据泄漏。比如上午采的做训练下午采的做测试这样能检验模型对时间漂移的鲁棒性。如果准确率低于 85%优先检查特征提取环节FFT 的频点索引对不对谐波含有率有没有归一化偏置校准有没有做。其次检查样本标签有没有标错。最后才考虑换模型。5. 避坑与排查那些让识别率一夜回到解放前的细节5.1 现象同一台电器上午识别对下午识别错原因偏置电压随温度漂移导致 ADC 读数整体偏移FFT 后低频段出现虚假峰值谐波含有率失真。解决在固件里加自动零漂校准。每次采样前先判断当前有效值是否低于阈值比如 10mA如果是就更新 offset。同时在特征提取前做去均值处理消除残余直流。5.2 现象电机类电器启动瞬间被误判为开关电源原因电机启动时电流冲击大波形畸变严重波峰因数可能超过 2.0接近开关电源的特征。解决不要用启动瞬间的数据做分类。等电器运行 2 秒后取稳态窗口再分析。如果必须识别启动瞬态那就单独训练一个「启动阶段分类器」用启动后 0 到 500ms 的数据做特征。5.3 现象小功率电器比如 5W LED 灯识别率极低原因小功率电器的电流信号幅度小经过 CT 和 burden 电阻后ADC 读到的电压可能只有几毫伏信噪比太低谐波特征被噪声淹没。解决提高 burden 电阻值或者换用更高变比的 CT。但要注意burden 电阻太大会导致 CT 铁芯饱和波形削顶。折中方案是加一级可编程增益放大器PGA在小信号时自动放大。5.4 现象FFT 后谐波幅值忽大忽小重复性差原因采样率与工频不同步导致每次采样的起始相位随机FFT 结果受相位影响。解决用电压过零点触发采样。先采电压波形检测过零点然后在过零点后固定延时启动电流采样。这样每次采样的起始相位一致FFT 结果稳定。5.5 现象分类器在训练集上准确率 99%测试集只有 60%原因过拟合。特征维度 23样本量如果只有几十个模型会记住训练样本的噪声。解决增加样本量或者降低特征维度。可以用主成分分析PCA把 23 维降到 5 到 8 维再训练分类器。另外交叉验证要用 k-fold不要只做一次划分。6. 进阶技巧用增量学习让识别装置越用越准前面讲的都是离线训练、在线推理的套路。但实际部署后你会遇到训练集里没见过的电器。这时候如果直接判为「未知」用户体验很差。更好的做法是加一个增量学习机制当分类器对某个样本的置信度低于阈值时把它标记为「待确认」同时保存特征向量。用户确认电器类型后把这个样本加入训练集重新训练模型。在 MCU 上重新训练 SVM 不太现实但可以只更新 KNN 的样本库。KNN 的增量更新极其简单把新样本的特征向量和标签追加到数组里就行。推理时遍历所有样本取最近的 k 个邻居投票。代价是内存占用随样本量线性增长但 23 维浮点向量1000 个样本也才 92KBSTM32F407 的 192KB RAM 完全放得下。具体实现时我会把样本库存在外部 Flash 里开机时加载到 RAM。每次新增样本先写 Flash再更新 RAM 里的数组。Flash 擦写寿命有限所以不要每次采样都写而是攒够 10 个新样本再批量写入。验证增量学习效果的方法很简单先用 5 种电器训练初始模型然后拿第 6 种电器测试应该判为「未知」。确认标签后加入样本库再拿第 6 种电器的其他样本测试应该能正确识别。重复这个过程观察识别率是否随样本增加而上升。我自己的习惯是每新增一种电器至少采 50 个样本再更新模型样本太少容易引入噪声。另外增量学习只适合 KNN 这类懒惰学习算法SVM 和随机森林要重新训练在 MCU 上不现实。如果主控是树莓派这类 Linux 平台那就可以用 scikit-learn 的partial_fit做在线学习但那是另一个量级的硬件成本了。希望帮到你。本文还有配套的精品资源点击获取