资讯动态

传感器大作业报告:从选型、STM32采集到标定滤波与误差分析

发布时间:2026/9/18 19:43:32 来源:尧图企业网站定制
简介《传感器大作业报告完整版》是一份面向电子信息工程、自动化等专业学生课程设计场景的技术报告文档围绕无线温度数据采集与温控系统展开可帮助读者理解从需求分析、方案选型到硬件实现与测试的完整链路。报告主体包含温控设计思路与整体框图、总电路图硬件部分的报警模块与显示模块电路图及PCB板示意图并对比了12864与LCD1602液晶方案说明选用NPN三极管驱动蜂鸣器、DS18B20数字温度传感器实现-55℃125℃采集的原因末尾附有传感器与检测技术、单片机原理等参考文献。压缩包仅含1个doc文件约561KB轻量便于查阅与二次编辑目前已有175人学习下载。对需要撰写同类大作业报告、整理电路图纸与器件选型论证的读者而言可作为结构完整、模块清晰的参考范本。1. 传感器大作业报告为什么总是卡在数据上很多人做传感器大作业原理部分抄得工工整整框图也画得像模像样写到「实验数据与分析」这一节就动不了笔串口助手里的数字一直在跳标定曲线画出来是一团散点误差分析只能写一句「存在一定误差」。传感器大作业报告完整版.doc 这类文档真正难的地方从来不是排版而是从被测量反推器件、把模拟量和数字量稳稳读进来、标定滤波、最后把误差说清楚这条链路要能闭环。这篇文章按课程设计和实际项目里最常走的那条路把这个骨架拆开讲光电传感器、霍尔传感器、MQ 系列这些常见器件怎么选STM32 侧怎么采标定和滤波参数怎么定报告里的图表怎么出才经得起追问。正在赶课程设计的人可以照着搭需要给新人铺一条测量链路的工程师也能直接用。2. 传感器选型与测量链路从光电传感器到霍尔传感器怎么定选型选错后面所有代码都是在给错误的数据做美化。课程设计里最常见的翻车方式是先看手头有什么模块再倒过来编一个测量目标。正确的顺序是反过来的先把被测量写成一句可量化的话再去找器件。2.1 从被测量反推器件的三步法第一步把需求写成四个字段物理量、量程、精度、频带。比如「电机转速0 到 3000 转每分钟误差不超过百分之一需要分辨 50 赫兹以内的波动」。第二步按物理量和量程锁定传感器类型转速用霍尔传感器或者反射式光电传感器做脉冲计数温度用热敏电阻、DS18B20 或者 PT100位移用电阻式或者电涡流传感器气体用 MQ 系列。第三步按输出形式决定调理电路开关量直接进 GPIO 加中断计数模拟电压进 ADC数字量走 I2C 或 SPI。这一步做完你会发现很多模块根本不用买。做循迹小车五路循迹传感器的优点是能直接给出五路开关量省掉 ADC 和阈值判断但代价是只能告诉你「偏了多少路」给不出连续偏差如果你要写一个 PID 让它走得平滑连续输出的反射式光电传感器反而更合适。同理测颜色用 TCS34725 这类颜色传感器读 RGB 加 Clear 四通道原始值比用三个滤光片加光敏电阻稳定得多。做生理信号PPG 传感器的原始波形对运动伪影极其敏感报告里如果只放一条滤波后的曲线答辩时基本会被问到原始数据长什么样。提示量程要留百分之二十余量。霍尔传感器测转速时量程按最高转速的一点二倍算否则高速段脉冲会丢。2.2 常见传感器输出形式与接口对照把选型结论整理成一张表直接放进报告评阅人一眼就能看懂你的信号链路。下面这张表是按课程设计里出现频率最高的几类器件整理的。被测量典型器件输出形式接口典型响应时间磁场、转速霍尔传感器 A3144、SS49E开关量 / 模拟电压GPIO / ADC开关型微秒级可燃气体、酒精MQ-2、MQ3 酒精传感器模块模拟电压 阈值开关ADC GPIO预热后 t90 数十秒光照、颜色BH1750、颜色传感器 TCS3472516 位数字量I2C数十毫秒积分时间可调反射、遮挡反射式光电传感器开关量 / 模拟GPIO / ADC微秒级位移非接触电涡流传感器模拟电压 / 电流ADC受激励频率限制千赫兹级心率、血氧PPG 传感器数字量I2C取决于采样率设置力、力矩六维力 / 力矩传感器差分模拟 / 数字ADC / SPI数百赫兹到千赫兹门窗开合门磁传感器干接点GPIO毫秒级这里有个容易被忽略的细节MQ 系列标注的响应时间不是指上电就能用而是指充分预热后的阶跃响应。MQ-2 和 MQ3 酒精传感器的加热丝需要持续通电老化课程设计里如果只预热五分钟就采数据同一个浓度下前后两次读数能差出百分之几十。2.3 采样率与传感器响应时间的匹配采样定理说采样率要大于信号带宽的两倍但工程上两倍远远不够。我一般按带宽的五到十倍取如果传感器本身响应慢采样率再高也只是把同一个值重复采很多遍。用下面这段脚本可以同时按信号带宽和传感器响应时间反推最低采样率。# sample_rate_check.py由信号带宽和传感器响应时间反推最低采样率 def min_fs(bandwidth_hz, margin5.0, t90_sNone): 返回 (奈奎斯特下限, 工程建议值)单位 Hz fs_nyq 2.0 * bandwidth_hz # 理论下限仅作参考 fs margin * bandwidth_hz # 工程下限5~10 倍带宽 if t90_s: # 一阶系统 t90 ≈ 2.3τ等效带宽 f 1/(2πτ) tau t90_s / 2.3 fs_sensor margin / (2.0 * 3.1415926 * tau) fs max(fs, fs_sensor) # 取更严的那个约束 return fs_nyq, fs print(min_fs(50, margin10, t90_s0.01)) # 输出 (100.0, 500.0)理论上 100 Hz 够实际按 500 Hz 采第一个参数是信号带宽做转速测量时按最高转速对应的脉冲频率算margin 取 5 到 10抗混叠要求高就取 10t90_s 是器件手册里的响应时间不填就只用带宽约束。返回值里第一个数字只用于说明第二个才是实际要写进报告的采样率。如果算出来比定时器能给的采样率还高说明要么换器件要么把报告里的带宽指标往下调不要硬写一个采不到的数。2.4 供电、共地与参考电压的三处坑第一处是加热类器件的电流冲击。MQ 系列加热丝峰值电流能到 150 毫安用 USB 直接供电时母线会掉压导致同一时刻 ADC 读到的参考电压也在变。稳妥做法是模拟部分单独用一路低压差稳压器或者在固件里用内部参考电压通道做实时校正。第二处是地和参考电压。模拟地和数字地单点连接走线不要形成环路ADC 的参考电压如果有外部基准就一定要用没有的话至少用万用表实测一次 VDDA 的实际值把 3.30 这个理想值换成实测值再算物理量。很多报告里第一条标定曲线有固定偏差根源就在这里。第三处是长线引入的干扰。反射式光电传感器和门磁传感器经常要引出十几厘米的导线这段线就是天线。屏蔽双绞加一个截止频率在信号带宽十倍左右的 RC 低通能让原始数据的抖动幅度降一个量级。3. STM32 采集端最小系统ADC 扫描、I2C 数字传感器与串口上报硬件链路定了接下来是固件。这一章给一个能直接跑的最小工程模拟量和数字量各一条路径最后统一从串口上报。选择 STM32 是因为它的 ADC 加 DMA 组合在多通道扫描时最省心如果用 ESP32 配合 PlatformIO 也可以把数据发到云平台的思路是一样的只是把串口换成 MQTT。3.1 时钟、串口与工程骨架先把时钟树调到 ADC 允许的最高频率再配一路串口。串口波特率不要用 9600三通道、每通道每秒几百个点的话9600 会在上位机侧堆出延迟。常用配置是 115200、8 位数据位、1 位停止位、无校验接收端按二进制帧解析不要用文本打印。定时器触发 ADC 是这套方案的关键。让 TIM 的更新事件去触发 ADC 转换采样间隔由定时器决定跟主循环里干什么完全解耦。主循环只做两件事处理已经采满的缓冲区往串口发帧。这样即使主循环偶发卡顿采样点的时间戳依然是均匀的。3.2 ADC 加 DMA 多通道采集 MQ 系列与电位器式传感器MQ-2 这类模块的输出接到 ADC 通道电位器式的电阻式传感器接另一路配置成扫描加连续转换模式DMA 循环搬运。/* adc_dma.c三通道扫描 DMA 循环搬运避免轮询丢点 */ #define ADC_CH_NUM 3 #define BLOCK_SIZE 16 /* 每通道每次采 16 点 */ static uint16_t adc_buf[ADC_CH_NUM * BLOCK_SIZE]; void adc_dma_start(void) { /* 长度填总转换次数不是通道数这里 3 * 16 48 */ HAL_ADC_Start_DMA(hadc1, (uint32_t *)adc_buf, ADC_CH_NUM * BLOCK_SIZE); } /* 半满回调处理前半缓冲全满回调处理后半缓冲形成双缓冲 */ void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc) { process_block(adc_buf[0], BLOCK_SIZE); } void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) { process_block(adc_buf[ADC_CH_NUM * BLOCK_SIZE / 2], BLOCK_SIZE); }HAL_ADC_Start_DMA 的第三个参数最容易写错它要的是 DMA 搬运的传输单元总数等于通道数乘每通道点数。半满和全满两个回调交替触发主循环处理速度只要快于半个缓冲区的采集时间就不会丢点。process_block 里做的是去极值平均先把每通道的十六个点排序去掉最大最小各两个再求平均这一步能把开关电源带来的尖峰滤掉大半。MQ 系列还有一个必须做的换算。模块输出的是负载电阻上的电压浓度要和 Rs 与 R0 的比值挂钩公式是 Rs 等于负载电阻乘以电源电压减输出电压再除以输出电压然后查数据手册给出的对数线性关系。报告里如果只写 ADC 原始值等于没做测量。3.3 I2C 读霍尔传感器与颜色传感器的寄存器时序数字传感器看起来省事寄存器时序写错一样读不出来。以颜色传感器 TCS34725 为例它的 I2C 地址是 0x29读寄存器前要先发一个命令字节最低位为 1 表示自动递增这样一次读两个字节就得到完整的十六位数据。/* 读 TCS34725 的 16 位通道数据 */ static uint16_t tcs_read16(uint8_t reg) { uint8_t cmd 0xA0 | reg; /* 0x80命令有效0x20寄存器地址自动递增 */ uint8_t buf[2] {0}; /* HAL 库要传 7 位地址左移一位后的值 */ HAL_I2C_Master_Transmit(hi2c1, 0x29 1, cmd, 1, 100); HAL_I2C_Master_Receive(hi2c1, 0x29 1, buf, 2, 100); return (uint16_t)((buf[1] 8) | buf[0]); /* 低字节先出 */ }三处参数要盯住地址左移是因为 HAL 库要求包含读写位命令字节的 0x80 是器件规定的有效标志返回值的字节顺序是低字节在前。读写超时给 100 毫秒正常情况几毫秒就返回如果频繁超时先查上拉电阻和总线电容再查供电是否在器件允许范围内。霍尔传感器的线性型号走 ADC开关型号走外部中断用中断计数算转速时记得在中断里只做加一把换算放到主循环。3.4 上报帧格式与上位机解析二进制帧比文本帧省一半以上带宽也更容易做校验。帧结构定为两字节帧头、一字节长度、若干字节载荷、两字节 CRC。上位机侧按下面的逻辑切片。import struct FRAME_HEAD b\xaa\x55 def crc16_modbus(data: bytes) - int: Modbus CRC16初值 0xFFFF多项式 0xA001反向 crc 0xFFFF for b in data: crc ^ b for _ in range(8): crc (crc 1) ^ 0xA001 if crc 1 else crc 1 return crc 0xFFFF def parse_stream(buf: bytearray): 从串口字节流中切出完整帧返回 (载荷列表, 剩余字节) frames [] while True: idx buf.find(FRAME_HEAD) if idx 0 or len(buf) - idx 4: break length buf[idx 2] # 载荷字节数 total 2 1 length 2 # 帧头 长度 载荷 CRC if len(buf) - idx total: break # 半帧等下一批数据再拼 payload bytes(buf[idx 3: idx 3 length]) rx_crc struct.unpack(H, buf[idx 3 length: idx total])[0] if rx_crc crc16_modbus(payload): # 校验不过直接丢弃 frames.append(payload) del buf[:idx total] return frames, buf帧头用于同步找不到帧头就说明有脏数据长度字段决定这一帧要等多少字节不足时保留剩余字节等下次拼接这是处理半帧的标准做法CRC 用 Modbus 那一套初值 0xFFFF实现只需几行能挡掉绝大部分串口误码。载荷按小端序打包每个通道两个字节上位机按同样的顺序解包即可。4. 标定、滤波与误差分析让大作业报告里的曲线站得住到这里原始数据已经稳定了但它还不是物理量也还没回答「误差有多大」这个必答题。这一章的三件事做完报告里最核心的那一节就成型了。4.1 两点标定与最小二乘拟合传感器输出和物理量之间通常可以近似成一条直线标定就是确定斜率 k 和截距 b。只在两端各测一次的两点标定最快但无法评估线性度课程设计里推荐均匀取五到十个点用最小二乘拟合。import numpy as np def least_squares_calib(raw, ref): raw: ADC 原始值数组; ref: 标准仪器读数数组 k, b np.polyfit(raw, ref, 1) # 一次多项式 最小二乘直线 resid np.array(ref) - (k * np.array(raw) b) ss_res float((resid ** 2).sum()) ss_tot float(((np.array(ref) - np.mean(ref)) ** 2).sum()) r2 1 - ss_res / ss_tot # 决定系数越接近 1 线性越好 return k, b, r2, float(resid.std(ddof1)) # 残差标准差作为重复性参考 k, b, r2, s least_squares_calib([512, 1024, 2048, 2816, 3584], [5.0, 10.0, 20.0, 27.5, 35.0]) print(fk{k:.6f} b{b:.4f} R2{r2:.5f} 残差σ{s:.4f})polyfit 的第三个参数填 1 表示拟合一次曲线取 2 就是二次多项式。决定系数 R² 如果低于 0.995说明这个传感器的线性度不够报告里应该改用分段线性或者二次拟合并说明原因而不是硬用一条直线。残差标准差可以写进误差分析的重复性项里。需要提醒的是标定的参考值必须来自一个精度明显高于被测对象的标准仪器拿另一个同型号模块当基准标出来的结果只说明这两个模块一致说明不了准不准。电涡流传感器做位移标定时用千分尺或量块做基准是常规做法。4.2 滑动平均、中值滤波与一阶低通怎么选滤波不是为了把曲线变漂亮而是要在噪声抑制和响应速度之间做取舍。三种常用方法的差别如下。方法计算量抑制高斯噪声抑制脉冲噪声引入的相位滞后滑动平均低好与窗长平方根成反比差尖峰被摊平约窗长一半个采样周期中值滤波中需排序一般好能完全剔除孤点约窗长一半个采样周期一阶低通极低好系数可调差时间常数 τ 决定的指数滞后我一般的组合是先用窗口为 5 的中值滤波去掉尖峰再用一阶低通平滑。一阶低通的递推式只有一行系数由截止频率和采样周期决定。def lowpass(x, dt, fc): 一阶低通fc 为截止频率(Hz)dt 为采样周期(s) rc 1.0 / (2.0 * 3.1415926 * fc) a dt / (rc dt) # 平滑系数越小越平滑 y [x[0]] for v in x[1:]: y.append(a * v (1 - a) * y[-1]) return y截止频率取信号带宽的三到五倍比较合适。取太低阶跃响应的上升时间会被拉长到报告里写不清取太高噪声抑制不明显。需要注意的是滤波后的数据不能再用去计算响应时间的指标两者互相矛盾报告里必须分开说明。4.3 误差来源分解与不确定度估算误差分析写不深通常是只写了「存在噪声」四个字。照下面四类拆开每类给出量级内容就够扎实了。第一类是器件本身误差包括非线性、迟滞和重复性可以从手册里查也可以实测。第二类是标定引入的误差来自参考仪器的精度和拟合残差。第三类是采集链路误差包括 ADC 量化误差和参考电压的漂移量化误差按满量程除以二的十二次方再除以根号十二估算。第四类是环境误差温度、供电波动都算这一类。合成时用方和根A 类分量按多次测量的标准差除以测量次数的平方根B 类分量按最大允许误差除以根号三。报告里列出表格每一行给出误差源、类型、量值和灵敏度系数最后合成扩展不确定度取包含因子 2。这一套写下来比笼统写一句「实验误差约百分之五」有说服力得多。4.4 用 Python 出图并回填文档报告里的图要能对应到具体参数。建议固定一套绘图样式图注里写清采样率、滤波参数和标定系数图例标明通道名。import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] # 正常显示中文标签 plt.rcParams[axes.unicode_minus] False # 正常显示负号 def plot_compare(t, raw, filtered, title, ylabel): fig, ax plt.subplots(figsize(8, 4), dpi150) ax.plot(t, raw, lw0.8, alpha0.5, label原始值) ax.plot(t, filtered, lw1.2, label滤波后) ax.set_xlabel(时间 t / s); ax.set_ylabel(ylabel) ax.set_title(f{title}fs500Hz, 中值5低通10Hz) ax.grid(alpha0.3); ax.legend() fig.tight_layout(); fig.savefig(f{title}.png)dpi 设到 150 以上插进文档才不会模糊f_ 前缀的原始数据和滤波后数据画在同一张图里答辩时一眼就能看出滤波做了什么。同一批实验的所有图用同一个函数生成风格才统一。5. 传感器大作业报告成稿的可复现技巧与答辩追问点想让这份文档从「看起来还行」变成「挑不出毛病」靠的是可复现性。评阅人未必会重跑你的代码但会看你有没有留下能重跑的痕迹。5.1 数据可复现的三件套第一件是原始数据。串口收到的字节流、每次标定的参考仪器读数、每个采样点的时刻全都以 CSV 落到磁盘列名写清楚单位和量纲不要用「data1」「value2」这种列名。原始数据一旦保存后面所有图表都从它派生绝不在中间环节手改数值。第二件是脚本。标定、滤波、出图各一个脚本脚本开头用注释写清输入文件和输出文件参数集中写在文件顶部。这样换一组数据只需要改路径和参数。第三件是环境。Python 版本和关键库版本写进报告附录或者用一份 requirements 文件锁住。matplotlib 的字体配置在别的机器上经常导致中文变方框把字体设置写进脚本而不是依赖系统默认能省掉很多麻烦。5.2 答辩最容易被追问的五个点第一个问题通常是采样率怎么定的。回答要给两层信号带宽是多少传感器响应时间是多少按五到十倍余量取把前面那段计算脚本的结果直接说出来。第二个问题是标定基准是什么精度多少比被测对象高几个等级。第三个问题是滤波参数怎么选的截止频率和信号带宽是什么关系滤波对相位的影响考虑没有。第四个问题是重复性做了几次标准差多少和不确定度分析里的数字对不对得上。第五个问题是数据里那个明显的跳变是什么是真实信号还是干扰如果是干扰你的滤波为什么没滤掉。最后一个技巧把报告里每一张图的生成命令都写进附录图注里带上一行参数摘要例如采样率、滤波窗口、截止频率、标定斜率和截距。答辩的时候任何一张图被问到参数翻到附录就能念出来比现场回忆靠谱得多也让整份文档从一次性的作业变成能交付的测量记录。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价