STM32智能医疗输液点滴系统开源:代码+原理图+仿真

发布时间:2026/9/5 9:33:47
STM32智能医疗输液点滴系统开源:代码+原理图+仿真 STM32项目开源智能医疗输液点滴系统代码原理图仿真搞嵌入式这几年我一直想找一个既能练手、又真正有实际意义的完整项目。实验室里那些流水灯、温湿度计做得再多面试时也拿不出手。直到去年在医院陪床看着护士一趟趟跑过来盯着输液瓶我突然意识到输液监测这件事简直太适合用STM32做一套完整方案了。这个项目我从零开始画原理图、写驱动、调PID、跑仿真前前后后花了一个多月。现在把整套东西开源出来包含完整代码、可生产的原理图、以及Proteus仿真工程希望能帮到正在找项目的朋友。这套智能医疗输液点滴系统解决的是真实痛点传统输液完全靠人盯病人睡着了没人换药家属紧张得不敢合眼护士工作强度也大。系统通过红外对管检测滴壶内的液滴下落实时计算滴速当滴速异常或药液即将输完时能本地声光报警同时通过串口把数据推送到上位机大屏。整套系统成本极低一个STM32F103C8T6核心板加几个传感器就能跑起来。适合拿来练手的朋友有三类准备求职的嵌入式学生需要一个能写在简历上的完整项目想往医疗电子方向转的工程师可以看看医疗设备的基本设计逻辑还有对红外检测、定时器输入捕获、PWM控制这些STM32核心外设不熟的人这项目把这些知识点全串起来了。1. 系统整体设计与思路拆解1.1 需求分析医院场景下输液监控到底要解决什么做项目之前我把输液场景里的真实需求列了个清单。不是拍脑袋想功能而是从医护人员的实际工作流程倒推。护士站最关心的三个问题第一每个床位的药液还剩多少第二当前滴速是否在医嘱范围内第三药液快完的时候能不能提前预警。病人和家属关心的则更简单别出意外别一直盯着。从这个清单倒推系统功能核心就三块滴速检测、滴速控制或异常报警、液位检测。滴速检测用红外对管方案液位检测用滴壶下方的对射式红外传感器控制执行器用步进电机或直流电机带动挤压阀夹住输液管调节流速。这套架构和市面上几千块的医用输液泵逻辑几乎一致只是我们在精度和可靠性上做了取舍让它更适合学习和二次开发。1.2 方案选型为什么用STM32F103C8T6而不是其他芯片主控选型我纠结过一阵子。当时手上有ESP32、STM32F407、还有这块F103C8T6。最后选了F103C8T6核心原因有三个。一是资料和生态足够成熟。不管是在Keil里点灯还是用CubeMX配外设网上教程一抓一大把遇到问题能快速搜到解决方案。二是外设资源刚好够用。这个项目要用到定时器输入捕获测滴速、PWM输出控制电机、ADC采集备用模拟量监测、USART通信上位机交互、GPIO中断按键和报警F103C8T6的TIM1、TIM2、TIM3、TIM4全都派上了用场。三是价格确实便宜核心板十几块钱烧了不心疼。如果你手头只有F407或G431移植也不难。项目代码里我把硬件相关的初始化都放在单独的HAL层换芯片只需要改CubeMX配置和少量引脚映射。1.3 系统架构从信号采集到上位机显示的完整链路整个系统的数据流是这样的滴壶里的液滴滴落瞬间穿过红外对管的检测区域红外接收管接收到一个遮挡脉冲经比较器整形后送入STM32的TIM2通道1做输入捕获单片机根据两次捕获的时间间隔计算滴速通过一阶低通滤波平滑数据然后同时做三件事把当前滴速和设定值比较偏差超过阈值就触发声光报警并启动电机调节把滴速和液位状态打包成帧通过USART1发送给上位机把液位传感器信号送给EXTI中断一旦检测到液面低于警戒线立即进入紧急报警状态。有人可能会问为什么液滴检测不用摄像头或激光而用红外对管我实测下来红外对管在成本、响应速度、抗干扰三方面最均衡。摄像头方案识别准确但处理复杂激光方案精度高但对安装位置太敏感红外对管只要把比较器阈值调好滴速范围20-80滴/分钟都能稳定捕获。2. 核心硬件方案解析2.1 原理图设计红外检测电路的几个关键细节原理图我用的立创EDA画的开源仓库里导出了PDF和Gerber文件。整板分四块主控最小系统、液滴检测电路、液位检测电路、电机驱动与报警电路。这里重点讲液滴检测电路因为这是整套系统精度好坏的关键。红外发射管选用940nm波长的IR333接收管用与它光谱匹配的PT334。这两个管子配对使用时发射管串一个100Ω限流电阻接收管c极接3.3Ve极通过10kΩ下拉电阻接地信号从e极引出。静态时接收管导通e极电压接近高电平液滴经过时遮挡红外线接收管截止e极被拉低产生一个负脉冲。但这个负脉冲不能直接进STM32因为波形边沿不够陡而且会有抖动。我在后面加了一级LM393比较器基准电压用两个电阻分压设定在2.0V。实测效果立竿见影波形从缓慢变化的模拟信号变成标准的方波脉冲STM32的输入捕获不会误触发。这是我从做光电编码器测速的帖子里学到的经验比直接接GPIO稳定太多。液位检测的原理类似只是红外对管安装在滴壶下方两侧正常有液时接收管被液体折射影响输出电平跳变。需要注意滴壶本身是透明软管安装时要做遮光处理否则环境光会干扰检测结果。我用了热缩管加黑色电工胶布两层遮光后实测稳定性大幅提升。2.2 电机驱动与执行机构用挤压阀实现滴速控制滴速控制执行器我选了28BYJ-48步进电机驱动芯片ULN2003。为什么不用直流电机因为滴速控制需要精确调节步进电机可以按固定角度步进方便实现定量挤压。ULN2003内部是达林顿管阵列可以直接驱动5V步进电机STM32的GPIO输出3.3V电平就能驱动它。挤压阀的机械结构我用3D打印做了一个滚轮夹具步进电机转动时带动滚轮下压输液管改变管道截面积从而调节滴速。这个方案在开源硬件社区很常见缺点是响应稍慢但从学习角度完全够用。调节策略我用的是增量式PID。目标滴速由按键设定实际滴速由红外检测得到PID输出控制步进电机的步数和方向。参数我做了两组一组偏快速响应Kp35Ki8Kd15用于从静止状态快速到达目标滴速一组偏稳定Kp20Ki5Kd20用于稳态时的小幅修正。实际调参过程后面详细说。2.3 电源与外围电路从USB取电到系统供电的稳定性考虑供电部分我用了USB 5V输入经过AMS1117-3.3稳压给STM32供电电机和红外发射管直接吃5V。这里有个容易被忽略的坑步进电机启动瞬间电流尖峰能达到300mA以上如果和单片机共用LDO输出会导致单片机复位。所以我的PCB上3.3V和5V电源之间加了磁珠和100uF大电容电机驱动电源单独走线。报警电路很简单一个无源蜂鸣器加一个NPN三极管驱动GPIO输出高电平导通。我做了一个渐强报警音通过定时器PWM输出不同频率的脉冲比单纯的滴滴声更容易引起注意。指示灯用了红绿双色LED绿色表示运行正常红色闪烁表示报警。3. 软件代码设计与核心实现3.1 代码结构HAL库工程如何分层软件部分我用的是STM32CubeMX生成工程框架加上Keil MDK编写业务代码。工程目录清晰分了四个部分Core里放main.c、stm32f1xx_it.c等系统文件Drivers放HAL库BSP放板级驱动比如infrared.c、motor.c、buzzer.c、uart.cApp放应用层逻辑包括speed_detect.c、pid.c、protocol.c。分层的意义在于BSP层只负责寄存器底层的读写不关心业务逻辑App层只调用BSP提供的接口不直接操作寄存器。这样改硬件平台时只需要改BSP层App层完全不用动。这种模块化思维在正式工程项目里是基本功面试官很看重这个。main.c里的主逻辑是一个超级循环加多个中断服务函数。滴速检测在TIM2输入捕获中断里做液位报警在EXTI中断里做PID控制在TIM3定时器中断里以100Hz频率执行主循环只处理按键扫描、OLED刷新和串口数据发送。这样分时处理的好处是每个任务的实时性都能得到保证不会因为某个任务卡死影响整个系统。3.2 滴速检测输入捕获模式的配置与数据处理滴速检测是整个系统的灵魂。我用了TIM2的通道1做输入捕获上升沿触发。每个上升沿进入中断时读取当前计数器的值减去上一次的捕获值就能得到两次液滴之间的时间间隔单位是定时器时钟周期数。换算成滴速的公式是滴速(滴/分钟) 60000000 / (时间间隔 × 定时器分频系数)我这里定时器时钟是72MHz分频系数72所以计数器频率是1MHz。如果测得两次滴落间隔为60000个计数那滴速就是60000000/60000100滴/分钟。原始测量值抖动很大因为液滴下落并不是绝对匀速的。我在App层加了一阶低通滤波滤波系数0.3filtered_value 0.7 * old_value 0.3 * new_value。这个系数是我反复试出来的太小响应慢太大滤不掉抖动。体温计式的趋势平滑用在这里正合适。还有个细节是输入捕获中断里不要做太多事情否则会影响下一次捕获。我实测过中断服务函数里只做计数读取和标志位设置滤波计算放在主循环里处理这样可以最大限度避免中断丢失。3.3 PID控制步进电机的增量式控制算法PID控制这块我直接用的位置式改增量式。公式不复杂增量 Kp * (e(k) - e(k-1)) Ki * e(k) Kd * (e(k) - 2*e(k-1) e(k-2))其中e(k)是当前误差即目标滴速减去实际滴速。得到增量后判断正负决定步进电机正转还是反转绝对值大小决定电机走的步数。实际调试时发现直接让电机根据PID输出持续转动电机容易过冲。因为步进电机每一步都会真实改变输液管截面机械系统的响应滞后于电气信号。我的解决办法是给PID输出加了死区误差绝对值小于3滴/分钟时PID输出归零电机不动作误差超过20滴/分钟时输出饱和限幅防止电机一步走太多把管子完全压死。调参顺序我建议先调Kp再调Ki最后调Kd。先让系统稳定在目标值附近不振荡然后加Ki消除稳态误差最后加Kd抑制超调。这套方法在自控原理里叫临界比例度法用在嵌入式PID调参里同样适用。3.4 通信协议串口如何与上位机对接串口部分我用的是USART1波特率1152008N1。通信协议自己定义了一个简单但完备的帧格式帧头0xAA 0x55数据长度数据区校验和。数据区固定12字节包含当前滴速、目标滴速、PID输出值、液位状态、报警标志、系统运行时间。为什么不直接用文本printf输出因为上位机解析文本不方便而且文本传输容易出错。二进制帧协议虽然写起来多几行代码但解析稳定、扩展方便。配套的上位机我用Python写了个简易界面读取串口数据后实时绘制滴速曲线同时显示报警状态。Python做桌面工具比C快太多了而且用pyserial库操作串口非常简单。校准这块我要特别提醒不同滴壶的液滴体积不同同样滴速下实际输液量可能差别很大。所以我做了一个校准模式用户先让输液泵以设定滴速运行一分钟实际称量输液量然后把校正系数写进Flash保存。这样系统的计量误差可以控制在±5%以内。4. 仿真验证与Proteus联调4.1 仿真模型的搭建Proteus里的传感器模拟Proteus仿真是我前期调代码时最重要的工具。真机调试需要焊接PCB、安装传感器、准备输液架成本高迭代慢而仿真环境里改电路、调参数瞬间完成。我把原理图导入Proteus用虚拟红外对管模拟液滴下落用虚拟示波器观测波形省了大量的硬件调试时间。传感器在Proteus里怎么模拟我采用的方法是用两个数字开关模拟红外对管的通断通过定时脉冲发生器按设定频率产生脉冲信号直接接入STM32的输入捕获引脚。脉冲频率可调对应不同的滴速这样就能验证代码在不同滴速下的响应是否正确。OLED显示模块我用Proteus自带的虚拟终端代替把状态信息通过串口输出在虚拟终端里查看。仿真的价值在于它能帮你把软件逻辑先验证到八九成再上真机时就只需要关注硬件层面的问题。比如PID参数在仿真环境和真机上表现很接近因为控制对象本质都是一个惯性系统。4.2 仿真中遇到的典型问题时序与协议验证仿真过程中我踩过最大的坑是Proteus里的系统时钟。Proteus默认的STM32模型时钟频率和真实芯片有差异导致我用延时函数写的时序全部乱套。解决办法是工程里所有依赖时间的逻辑都用定时器不用软件延时。这也促使我代码写得更规范算是因祸得福。另一个坑是UART虚拟终端乱码。排查了很久发现是波特率设置问题。Proteus里的虚拟终端有自己的时钟源和STM32外设时钟不同步需要手动在虚拟终端属性里设置从外部时钟输入。这个在真实硬件上不存在但很多初学者玩仿真时经常被搞晕。碳膜电阻这块我提一句仿真里的电阻电容参数必须设置真实值比如10kΩ不能写成10k否则仿真结果和实际电路差异很大。我见过很多人在Proteus里电容阻值不填仿真通过一焊板子就废了。4.3 仿真到实物的迁移从代码到硬件调试仿真通过后我开始焊电路板。焊接顺序有讲究先焊电源部分用万用表确认3.3V输出正常再焊主控最小系统用ST-Link下载点灯程序验证GPIO最后才焊传感器和电机电路。每焊一部分就测试一部分不要一次性全焊完再上电否则出了问题极难排查。实物调试时我遇到的问题很多在仿真里根本模拟不出来。最典型的是红外对管的信号抖动。真实环境里有环境光干扰、滴壶反光、甚至人手晃过都会产生误触发电平。我在软件里加了一个简单的防抖处理连续两次捕获间隔小于5ms的信号直接丢弃判断为干扰而非真实液滴。同时把比较器的基准电压微调高了一点实测误触发率从每分钟十几次降到几乎为零。电机控制从仿真迁移到实物也遇到机械公差问题。3D打印的挤压滚轮和不同品牌输液管的配合松紧度不同每次换管子都要重新标定电机步数和滴速的对应关系。我在代码里做了一个自动标定函数先让电机从完全松开状态逐渐下压同时实时检测滴速变化当滴速首次降到目标值以下时记录步数。这个函数在现场换管后一键执行非常实用。5. 常见问题与调试经验总结5.1 滴速检测不准数值跳动大这个问题十个人里有八个会碰到。排查思路按顺序走第一步用示波器看红外检测电路的输出波形如果波形边沿不陡或幅值不够检查比较器基准电压和接收管的偏置电阻第二步检查输入捕获中断是否频繁丢失可以在中断里加一个计数器对比一秒内进入中断的次数和OLED显示值第三步检查滤波算法是否合理滤波系数太小时输出滞后明显太大时跳动依旧。我自己的经验是波形整形比软件滤波更重要。硬件波形做好了软件只要做轻微滤波就能得到平滑的滴速值。如果硬件波形一塌糊涂靠软件强行滤波系统响应会变得迟钝PID控制也容易振荡。5.2 串口通信数据错乱或丢失典型原因是帧同步没做好。我的协议在软件里做了超时重同步处理接收状态机检测到帧头后如果4ms内没收到完整帧就复位重新等待帧头。这样哪怕中间丢一两个字节下一条帧也能恢复同步不会出现连续乱码。另外注意USB转TTL模块的3.3V和5V电平问题。STM32的USART引脚是3.3V电平如果USB转TTL模块是5V供电RX引脚可能输出5V高电平长期使用会损伤STM32引脚。最好用带电平转换的模块或者给RX引脚串一个1kΩ限流电阻。5.3 电机调节时滴速反而失控这个现象多半是机械结构问题。挤压阀下压太紧时输液管被完全压死滴速直接降到0电机再反转松开一点滴速又冲上去。PID在这种情况下会反复震荡。解决办法是给电机的步进范围做软件限位把最大步数和最小步数提前标定好PID输出在这两个极限之间运动不允许越界。还有个小细节步进电机运转时会发热长时间堵转电机关节顶到限位块但PID还在输出会损坏驱动芯片。我加了一个超时保护电机持续运转3秒以上且滴速没有变化时强制停止电机并报警。5.4 编译下载时no stm32 target found的排查很多朋友拿到代码后烧录时碰到这个报错。这个提示的大意是调试器没有找到STM32芯片常见原因有四个SWDIO和SWCLK接线接反了、目标板没有供电、芯片进入了低功耗模式或读保护状态、Keil里Debug设置没选对烧录器型号。逐个排查即可绝大多数情况是前两个原因。如果芯片之前烧录过程序并且开启了读保护需要用ST-Link Utility先解除保护。新手最容易忽略的是给板子单独供电ST-Link的3.3V输出电流有限带不动整板负载时就会导致连接不稳定。6. 开源资料的获取与进一步扩展建议整个项目的代码、原理图、仿真工程、上位机源码都放在开源仓库里目录结构如下/Doc放设计文档和BOM清单/Hardware放立创EDA原理图和Gerber文件/Firmware放Keil工程源码/Simulation放Proteus仿真文件/Tool放Python上位机源码。每个部分都有README说明照着操作就行。使用前建议先看一遍设计文档了解整体结构后再打开工程。代码里的关键函数都有注释模块化程度比较高不管是直接烧录学习还是改成自己的项目都不会太痛苦。如果想让这个项目更进一步我建议往这几个方向扩展一是加WiFi模块比如ESP8266把滴速数据上传到云平台做成真正的物联网医疗监护系统二是加触控屏替代按键和OLED人机交互会舒服很多三是把电源改成电池供电加入低功耗管理提升便携性。根据我个人经验每拓展一个方向你对嵌入式系统的理解都会上一个台阶。坦白说这个项目做到量产标准还有很多路要走比如双冗余检测、系统自检、EMC设计这些都是医疗电子入门的必修课。但作为学习项目它已经把嵌入式开发的核心环节完全串联起来了。希望这份开源资料能帮到正在这条路上探索的朋友期待看到你们的二次创作。