STM32智能输液监护系统:闭环PID调速与Proteus仿真实践 说实话做输液的监护设备这个念头最初并不是因为什么高尚的理由纯粹是在医院陪床时被折腾怕了。夜里守着输液瓶眼皮打架又不敢真睡生怕药液走空了回血或者滴速不对又得按铃叫护士。那时候就在想这种需要人一直盯着的事本来就应该交给机器去干。所以就有了这个开源项目的初版而这次要分享给大家的是全面重构之后的升级版。这套STM32智能输液监护调控系统整体包含完整的代码、原理图和仿真工程硬件上以STM32F103C8T6为主控实现了红外对管滴速检测、步进电机/蠕动泵调速、OLED实时显示、按键参数设置、蜂鸣器报警以及蓝牙上位机实时监控。升级版最大的变化是把原本的开环控制改成了闭环PID调节也就是说系统不再只是发现速度慢了就拧一下电机而是会持续监测滴速动态调整让速度始终稳定在你设定的范围内。这篇博文我会把整个项目从设计思路、核心原理到实际调试中踩过的坑一次性讲透。1. 为什么做这个项目从输液盯守痛点说起在正式讲技术细节之前我觉得有必要先聊聊这个项目最根本的出发点。如果不理解输液监护到底在解决什么问题你就算照着原理图把板子焊出来也不知道每个模块为什么要这样设计。1.1 初版做完后的遗憾与升级版目标我的第一版输液监护系统其实做得比较粗糙。当时的功能很简单红外对管检测滴速超限了报警然后手动按按键调速。但实际使用一段时间后发现这套逻辑有很大问题。输液过程中瓶内液面下降会导致压强变化再加上患者手臂稍微动一下挤压了输液管滴速就会发生漂移。开环系统只能发现问题之后报警然后等人来手动调整根本没法做到持续稳定。滴速一会在40滴/分钟过一会儿又掉到25滴/分钟家属还是得频繁过来看。所以升级版的目标非常明确系统要能自己判断滴速是否偏离设定值并且自动调整执行机构让滴速稳定在设定值附近。同时我希望能通过手机实时看到当前的滴速和剩余液量估算而不只是蹲在输液架旁边看OLED小屏幕。围绕这两个目标升级版做了以下几个关键改动引入闭环PID调速算法电机转速根据滴速偏差自动调节增加蓝牙通信模块实时上传滴速、温度、报警状态等数据优化滴速检测算法加入滤波和防抖避免液滴挂壁造成的误计数重新设计电源电路解决电机启动瞬间拉低单片机电压导致复位的问题补充Proteus仿真工程让没拿到实物板子的朋友也能跑起来调程序1.2 升级版技术指标与功能清单在开源资料包的README文件里我列了一份完整的参数表这里先贴出来大家对这个项目的边界和性能会有一个直观概念功能项参数/说明主控MCUSTM32F103C8T672MHz主频64KB Flash滴速检测对射式红外传感器脉冲计数法量程5-150滴/分钟控制方式位置式PID闭环输出PWM驱动电机执行机构28BYJ-48步进电机5V驱动或微型蠕动泵12V驱动显示0.96寸OLED显示设定滴速/实际滴速/温度/报警状态温度监测DS18B20实时监测药液温度液位检测光电液位传感器低液位触发报警通信接口HC-08蓝牙模块通过手机APP/串口助手监控供电12V DC适配器或3节18650电池串联板上降压至5V/3.3V报警方式有源蜂鸣器LED闪烁低液位/滴速超限/电机堵转均触发严格来说这套系统定位是辅助监护和学习研究不是拿到医院去替代正式医疗设备的。它的核心价值在于把自动检测-闭环控制-远程监控这条完整链路跑通想基于此做产品化的朋友还需要做大量的可靠性设计和安规认证。这一点我在后面讲硬件选型时还会再强调。2. 硬件原理图拆解每个模块的选型逻辑与接口设计硬件方案是整个系统的地基。很多初学者容易犯的错是直接照搬开发板的外设电路完全不考虑实际工况。但输液监护这种场景有几个特殊需求是开发板满足不了的传感器要能稳定检测透明液体、电机驱动要考虑堵转和急停、电源要抗得住电机启动时的压降。这一章我把原理图按功能模块拆开讲。2.1 主控选型与最小系统设计主控没什么悬念选了STM32F103C8T6。这颗芯片在开源项目里几乎是万金油一样的存在价格便宜、资料多到爆炸、72MHz主频完全够用而且有足够的定时器和通信外设来处理多路传感器和蓝牙协议。最小系统设计时需要注意几个细节。首先是晶振电路我用的是8MHz无源晶振两个20pF负载电容这个取值算是标准配置。如果想省事STM32也支持内部HSI时钟但精度和稳定性都不如外部晶振而滴速检测对时间精度要求很高所以可靠起见还是上了外部晶振。其次是复位电路10kΩ上拉电阻加100nF对地电容经典的RC复位可靠且便宜。还有一个容易忽略的是BOOT0引脚我用10kΩ电阻下拉到地确保从Flash正常启动别让芯片莫名其妙进了ISP模式。另外一个比较重要的设计决策是所有数字传感器的GPIO都加了串联电阻做保护。比如DS18B20的数据线串了330Ω电阻万一接线接反了这个电阻能限制电流避免烧坏单片机引脚。设备是给不太懂电路的人使用的保护措施多一点没有坏处。2.2 滴速检测传感器原理与信号调理滴速检测是整个系统的感知核心原理说起来其实很简单输液器的滴壶两侧安装一组对射式红外发光管和接收管药液滴落经过红外光束时接收管收到的光强会发生变化产生一个脉冲信号。单片机检测这个脉冲的间隔就能换算出当前的滴速。但实际做的时候就发现事情没那么简单。滴壶是透明的塑料外壳药液本身也是半透明的加上周围环境光干扰接收管输出的信号波形非常脏。如果用单片机直接读取这个模拟信号会出现大量误触发——一滴液滴还没完全落下残余液体挂在滴壶壁上又晃了一下信号就上下抖动了多次导致多计数了好几滴。我的解决方案是加一级信号整形电路。接收管的输出先经过LM393比较器通过电位器设置一个比较阈值信号超过阈值才输出低电平否则保持高电平。这样就把模拟量的光强变化变成了干净的数字方波信号。比较器还带了一点点迟滞效果能有效滤除信号边沿的毛刺。这个电路在原图的传感器部分占的位置不大但实际效果提升非常明显。如果你手头没有LM393用NPN三极管搭一个开关电路也能凑合但抗干扰能力会差一些不推荐。2.3 执行机构选择步进电机还是蠕动泵控制药液滴速本质上是在控制输液管对药液的阻力。市面上常见的方案有两种一种是挤压式用电机带动偏心轮压迫输液管改变管道的截面积另一种是泵送式用蠕动泵的滚轮推动药液前进。升级版的原理图里我把两种方案都做了兼容。默认推荐的是28BYJ-48步进电机也就是常见的5V四相五线步进电机配合ULN2003驱动板。它的优势是便宜、驱动简单、控制精确通过改变转速就能调节对输液管的压迫频率。但缺点是体积偏大、噪音比较明显而且这种电机是减速型的转动速度本身不快如果不接减速机构直接驱动偏心轮可能转速不够。如果追求更稳定的流量控制可以考虑微型蠕动泵配合DRV8833这类电机驱动芯片。蠕动泵的流量和转速线性度很好而且药液只接触泵管不会污染泵体更符合卫生要求。但蠕动泵的价格会贵不少而且对泵管的质量要求高劣质泵管用久了会变形导致流量不准。我在实物验证的时候用的是28BYJ-48方案整个机构的装配思路是这样的把步进电机固定在一个小支架上电机轴上装一个凸轮凸轮转动时压迫输液管实现流速调节。这个结构在Proteus仿真里没法体现所以仿真部分我只做了控制逻辑和显示逻辑电机用虚拟信号代替。这一点要提前说明仿真毕竟代替不了真实的传动机构验证。2.4 显示、按键、报警与蓝牙通信外围交互这里相对常规但有几个选型细节值得说说。显示模块用的0.96寸I2C接口OLEDSSD1306驱动。选择I2C而不是SPI是因为只占两个IO口而且接线少整机装配时少四根杜邦线就少一份松动风险。OLED的功耗也很低整机电池供电时优势明显。有人可能担心OLED寿命问题确实有烧屏风险但在这种固定显示内容的场景下问题不大。按键我用了三个独立按键一个设置/确认一个加一个减。长按设置进入参数修改模式短按切换调节项逻辑写成了状态机代码里注释很清楚。之所以不用矩阵键盘是因为总共就三个按键没必要增加电路复杂度和代码量。我见过有人给这种小项目上了4x4矩阵键盘完全没必要纯属给自己找麻烦。报警部分用的是有源蜂鸣器。注意一定要选有源的内部自带振荡源单片机只要给它高电平就会响而无源蜂鸣器需要单片机输出特定频率的PWM驱动代码复杂且容易出错。这个坑我已经帮大家踩过了直接选有源蜂鸣器就好。蓝牙模块我选了HC-08而不是烂大街的HC-05。原因是HC-08基于CC2541芯片支持蓝牙4.0 BLE功耗比HC-05的蓝牙2.0低很多电池供电场景更友好。不过两者的AT指令集不同网上HC-05的资料更多一些如果你是第一次用蓝牙模块用HC-05上手会更顺畅代码和协议部分几乎不用改因为两者都是串口透传对单片机来说没区别。2.5 电源设计在隔离与纹波之间找平衡系统用了12V电源适配器供电板上做了两级降压12V降到5V再有5V降到3.3V。12V转5V用的是LM2596降压模块。这是一颗经典的开关降压芯片效率比线性稳压高得多发热也小。之所以不用7805是因为整个系统在满负载工作时步进电机OLED传感器电流需求可能接近500mA如果用7805线性降压12V输入情况下功耗差有3.5W散热片得做多大才能压得住LM2596的效率能做到80%以上发热问题就小很多。5V转3.3V则用了AMS1117-3.3这颗线性稳压芯片负责给单片机、传感器等数字电路供电电流需求不大线性稳压的纹波反而更干净对ADC等敏感模块有利。电源设计上最关键的细节是电机电源和单片机电源要分开走线。步进电机启动瞬间电流会突然增大导致电源电压瞬间跌落。如果电机和单片机共用一根电源线这个压降会直接传导到单片机供电端轻则导致ADC采样漂移重则整机复位重启。所以我在原理图上做了星型接地——电机驱动、传感器、单片机各自的电源和地线单独从输入端引出互不干扰连接处集中在一个点。这个细节初版没有吃了大亏升级版专门做了修正。3. 固件架构与关键算法实现硬件只是骨架固件才是这个系统真正的灵魂。这一章应该说是整个项目里含金量最高的部分——滴速检测怎么做到准、PID怎么调才稳、通信怎么设计才不容易出错我都会展开讲。3.1 工程文件组织模块化比一坨代码重要得多这个项目的代码是基于STM32标准外设库写的没上HAL库。原因有两个一是这个项目的定时器、外部中断、PWM等外设使用比较深入标准库的寄存器操作更直观性能也有保证二是网上基于标准库的参考代码最多大家遇到问题更容易检索到解决方案。工程文件组织是这样的User/ ├── main.c // 主函数状态机循环 ├── stm32f10x_it.c // 中断服务函数 ├── delay.c/h // 时间延时 ├── bsp_sensor.c/h // 红外滴速检测DS18B20 ├── bsp_motor.c/h // 步进电机驱动 ├── bsp_oled.c/h // OLED显示 ├── bsp_key.c/h // 按键扫描 ├── bsp_beep.c/h // 蜂鸣器报警 ├── pid.c/h // PID控制算法 └── bsp_uart.c/h // 串口蓝牙透传主函数里的循环用的是状态机思路而不是简单的顺序执行。程序状态包括开机自检状态、正常运行状态、参数设置状态、报警状态。每个状态都有对应的处理函数状态切换条件写在主循环里。这样做的好处是逻辑清晰增加新功能时不会把代码绕成一团乱麻。3.2 滴速检测算法如何把红外脉冲变成稳定滴速滴速检测的底层是硬件电路整形把红外接收管的模拟信号变成了方波脉冲。在固件层面要做的事情是精确测量两个脉冲之间的时间间隔。我用了定时器输入捕获的方式。STM32的TIM2配置为输入捕获模式捕获通道接红外整形电路的输出上升沿触发。当捕获中断发生时读取当前计数器的值减去上一次捕获时的值就得到了两个液滴之间的时间间隔单位是微秒。有了这个间隔滴速的计算公式就是// 滴速 1分钟(60000000微秒) / 单滴间隔(微秒) speed_drop_per_min 60000000.0f / (float)drop_interval_us;这段公式很简单但实际调试时我发现如果直接拿这个数值去显示屏幕上跳得厉害。因为两次液滴间隔本身就存在自然波动再加上偶尔的检测干扰实时滴速可能从40跳到60又瞬间掉回30。如果用这个乱跳的值去驱动PID系统会频繁调节电机机构一直在抖反而无法稳定。解决办法是做了滑动平均值滤波。我维护了一个长度为10的环形缓冲区每算出一滴的间隔就丢进缓冲区取最近10次间隔的平均值来计算滴速。这个滤波思路相当于一个低通滤波器把高频波动滤掉很多折线图看起来就平滑多了。如果检测到两次脉冲间隔大于3秒说明要么输液管堵了要么药液已经走完。这时候程序会直接报警并关闭电机防止空转把输液管磨坏。还有一个边界情况某些药液在滴落时会有挂壁现象液滴不会垂直掉落而是沿壁滑下一小段导致红外光束被遮挡的时间变长甚至产生二次遮挡。针对这种情况我加入了一个最小间隔判定如果间隔小于50ms直接丢弃视为无效脉冲。这个值可以根据实际传感器结构调整但50ms是一个不错的起始值。3.3 PID闭环调速从差不多到稳稳稳住升级版最核心的改进就是加了PID闭环。先说一下控制对象的关系PID的输入是设定滴速和实际滴速的偏差输出是电机转速对应的PWM占空比而步进电机转速快慢又会影响对输液管的压迫力度最终改变药液滴速。位置式PID的公式是大家熟悉的那种float PID_Calc(PID_TypeDef *pid, float target, float measure) { float error target - measure; pid-integral error; if (pid-integral pid-integral_max) pid-integral pid-integral_max; // 积分限幅 if (pid-integral -pid-integral_max) pid-integral -pid-integral_max; pid-derivative error - pid-last_error; pid-output pid-Kp * error pid-Ki * pid-integral pid-Kd * pid-derivative; pid-last_error error; return pid-output; }有几个参数整定的经验是这次项目调试中最花时间的部分。首先是积分限幅因为输液控制有个特点电机的调节范围是有限的PWM占空比只能在某个区间内变化如果不限制积分项一旦出现持续偏差积分会一直累积到很大导致回复时严重超调甚至电机一下顶到最大转速把输液管压死。我把积分上限设为PWM上限的20%实测效果好很多。其次是P参数的调整。这个系统调节的滞后性比较明显——你让电机转快一点要过好几秒才能看到滴速实际变化因为机械传动需要时间。P参数如果调得太大系统会觉得误差一直很大拼命调节结果等效果传来时已经过头了滴速会在设定值周围来回震荡。我的做法是先用纯P控制从小到大慢慢加Kp观察滴速响应曲线等它出现等幅震荡时记住这个Kp临界值然后用临界比例度法的经验公式去推算实际Kp、Ki和Kd。公式细节一般控制论教材都有这里不重复了。最后是输出平滑。PID算出来的输出值我做了斜率限制每次更新PWM时新值和旧值之差不超过最大变化量。这就好比开车你不会一脚把油门踩到底而是缓缓加速。放到这个场景里电机转速的调节应该是渐进的否则管子突然被大力压迫药液流的太快产生的冲击可能让患者静脉感到不适。3.4 上位机通信协议设计蓝牙通信看起来就是把单片机串口和手机蓝牙连上然后收发数据但如果你不做任何协议约束直接往串口丢数据用不了两天就会发现数据经常错乱。原因很简单串口的收发是流式的接收端不知道你这一段数据从哪开始、到哪结束。如果发送端一次发了滴速40\n而接收端从中间开始解析就有可能读到速40\n滴直接解析失败。我的解决方法是自定义了一个简单的帧协议帧头(0xAA 0x55) 命令字 数据长度 数据体 CRC8校验单片机每隔1秒钟主动向手机发送一帧状态数据内容包括当前滴速、设定滴速、PID输出值、温度、液位状态、报警状态。手机端收到一帧数据后先校验帧头再校验CRC校验通过才解帧用。反馈命令比如修改设定滴速的格式也是这套只是数据方向反过来。这套协议在蓝牙串口助手里能看到清晰的报文排错也方便。实际调试时我还发现一个容易忽略的点单片机端串口发送函数会在循环里频繁调用但蓝牙模块的波特率是固定的你如果发太快模块缓冲区可能溢出导致数据帧被截断。我的做法是发送前加了一个简单的等待发送完成判断等串口TXE标志位置位才继续发下一字节。4. Proteus仿真搭建与调试经验仿真里的坑比实物还多很多初学者拿到这个项目后第一件事就是先打开Proteus仿真看看。这个习惯很好因为仿真可以帮你快速理解程序逻辑尤其是没有实物板子的时候。但Proteus仿真STM32远没有仿真51单片机那么省心各种细节配置不对就是黑屏或者程序跑飞。这一章我专门写一下仿真的搭建过程和踩坑记录。4.1 仿真工程搭建步骤与关键配置Proteus仿真工程的核心是把STM32的hex文件加载进去并连好外围电路。在这个项目里我搭的外设比实物简单一些因为Proteus库里的传感器模型是理想化的没法模拟真实的红外脉冲信号。所以仿真里我是用一个可调脉冲发生器来模拟滴速信号通过改变脉冲频率看系统能不能正确计算出滴速并执行调节逻辑。搭建步骤大致是这样的在Proteus里新建工程从元件库添加STM32F103C8T6、OLED、按键、蜂鸣器、虚拟脉冲发生器等元件。把STM32的PB0引脚连接到虚拟信号发生器的输出端这个引脚在实物中接的是红外整形电路输出。双击STM32芯片在Program File里加载Keil编译生成的hex文件。进入仿真后给虚拟信号发生器设置一个固定频率比如1Hz相当于60滴/分钟然后观察OLED显示值是否接近60。这里有一个Proteus仿真STM32的经典坑晶振配置。STM32在Proteus里默认使用内部RC时钟速度可能不准。有一个简单的方法在STM32的属性里把CrystalFreq设置成8MHz然后外部晶振电路不画直接用内部PLL倍频到72MHz。有点奇怪的是有些版本Proteus的这个属性设置并不生效实际仿真速度会偏慢。遇到这种情况排查思路是先确认程序里SystemInit是否正确配置了RCC再检查Proteus属性设置。我把这个排查过程写在工程的说明文档里了照着一步步查基本能解决。4.2 虚拟示波器与串口监测观察内部运行逻辑Proteus仿真的一大优势是能看到内部信号。举个例子在实物上调试红外脉冲整形电路时我只能用示波器探头去点接收管的输出脚但在Proteus里我可以直接在单片机引脚上挂一个虚拟示波器观察PWM波形的占空比变化验证PID输出是否正确。调试PID参数时我会把PWM输出的虚拟示波器画面和滴速虚拟仪表画面放在一起对比。当虚拟脉冲发生器模拟的滴速偏离设定值后PWM占空比应该朝反方向调整。如果波形一直在剧烈震荡说明Kp偏大如果调整得很慢半天不回归说明Kp偏小或者积分作用太弱。这个观察方法在实物上其实很难做到因为实物调试时你看不到内部变量的实时变化只能看OLED上的最终结果。所以仿真不仅是学习工具更是一个高效的调参工具。顺便提醒一句Proteus仿真里OLED这类I2C设备仿真速度会明显变慢因为它需要模拟I2C时序。如果发现仿真很卡顿可以把OLED显示刷新率降低一些或者暂时注释掉显示刷新函数先把核心逻辑调通再恢复显示。4.3 仿真和实物的差距哪些能仿真哪些不能老实说这个项目的Proteus仿真并不能完整覆盖所有功能因为仿真模型和真实物理世界之间存在本质区别。我在README里也做了说明仿真能验证的主要是MCU的GPIO配置、定时器配置是否正确滴速计算逻辑、PID算法、状态机逻辑是否能正确运行串口通信协议是否能正确收发数据仿真无法验证的包括真实红外传感器在环境光干扰下的信号质量步进电机带负载时的真实力矩和速度响应电源在动态负载下的纹波和瞬态表现机械结构装配后产生的摩擦、形变等非线性因素所以我的建议是先通过仿真把逻辑这关过了再打板做实物这样能省下大量用仿真器单步调试程序的时间。但指望仿真能把所有问题都暴露出来是不现实的两者的调试方法论完全不同。5. 从画板到实物的踩坑复盘这一章我记录的都是一些常规文档里不会告诉你的真实问题。这些问题在原理图上是看不出来的只有拿到实物、通上电、开始和真实物理世界交互时才会暴露。我把它们原原本本写出来希望各位少走弯路。5.1 红外对管的幽灵信号第一个坑就出在最基础的传感器上。刚把板子焊好我接了红外对管测试发现示波器上接收管的输出波形乱七八糟就算滴壶里没有液体流动也会出现不规则的脉冲。一开始我还以为是程序问题查了半天后来用万用表测量接收管两端电压才发现问题根源强环境光中的红外成分被接收管误检测为有效信号。输液场景下经常有阳光或日光灯照射这些光源中含有大量红外频率的光会对红外接收管造成严重的直流偏置干扰。解决办法有两层硬件上用黑色热缩管套住红外对管的管身只留一个小的窗口让光路对准滴壶中心相当于给传感器加了一个遮光罩软件上把滴速计算的脉冲间隔最小值提高同时在主循环里加入一个自校准逻辑——上电后先读取一段时间的接收管信号自动学习当前环境光下的基线电平然后把比较器阈值设置在这个基线之上。这两层措施叠加下来误触发的概率大大降低。5.2 电机启动导致单片机频繁复位这是初版就存在、到升级版才彻底解决的问题。最初我把步进电机的ULN2003驱动板和单片机共用一组5V供电一上电启动电机OLED画面就开始闪烁偶尔还白屏。测了一下电源纹波发现电机每走一步5V线上就出现一个几百毫伏的跌落尖峰。步进电机绕组的感性负载很强电流突变时会产生反电动势直接传导到了电源线上。升级版我在硬件上做了两个改进。第一是电源走线改成了星型拓扑电机驱动和单片机从电源输入端分开取电。第二是在电机电源两端并联了一个470μF的大电解电容和一个104陶瓷电容用来吸收电流尖峰。大电容负责储能补电小电容负责滤高频干扰。这个组合几乎成了直流电机驱动的标配原理就是利用电容的充放电特性给瞬间的大电流需求提供缓冲避免电压跌落传导到敏感电路。5.3 蓝牙模块一连接就掉线HC-08蓝牙模块的调试也花了不少时间。现象是手机能搜索到模块也能配对成功但连接上之后一两秒钟就会自动断开或者是连接之后收不到任何数据。排查了很久最终发现两个问题叠加在一起。第一个问题出在波特率不匹配。HC-08出厂默认波特率是9600但我的代码里初始化的串口波特率是115200两者对不上数据自然没法正常收发。实际上串口波特率不匹配时接收端会收到一堆乱码或者根本检测不到有效起始位而丢失所有数据。解决办法是用USB转TTL模块连接蓝牙模块先通过AT指令把HC-08的波特率改成115200再装回板子上之后通信就顺畅了。第二个问题是供电电流不足。HC-08在广播和连接瞬间的峰值电流接近40mA如果板上的3.3V稳压芯片输出能力偏弱电压会被拉低模块就会复位重新广播表现就是连接不稳定。我给蓝牙模块单独加了一个100μF的电容做储能问题得到明显改善。如果你手里的蓝牙模块连接特别不稳定先别怀疑代码量一下供电电压是第5步要做的事很多时候就是这个电不够的问题。6. 开源资料怎么用文件结构、编译烧录与二次开发路径最后这部分写给刚拿到资料包的朋友。很多人下载开源项目之后不知道从哪里开始看起文件一大堆又没个引导。我按自己整理资料的习惯把整个工程分成了几个目录每个文件是干嘛的都在文档里写了说明。这里再单独讲一下使用顺序和二次开发思路。6.1 资料包结构说明与快速上手路径下载解压后你会看到这样的目录结构STM32-Infusion-Monitor-Upgrade/ ├── Doc/ │ ├── 项目说明文档.pdf │ └── 硬件接口说明.md ├── Hardware/ │ ├── 原理图.pdf │ └── 原理图源文件.SchDoc ├── Firmware/ │ ├── Keil工程目录 │ ├── 源码目录 │ └── 编译好的hex文件 ├── Simulation/ │ ├── Proteus仿真工程.pdsprj │ └── 仿真说明.md └── README.md建议的上手路径是先看README对整个项目有一个全貌了解然后打开Doc目录下的硬件接口说明搞清楚哪个引脚接哪个外设接下来打开Proteus仿真工程把程序跑起来体验一下整体逻辑最后再去看Firmware里的源码。不要一开始就一头扎进代码里否则容易被细节淹没。6.2 从仿真到实物的进阶建议如果你打算把这个项目做成实物要准备的东西包括STM32F103C8T6最小系统板或自己画的PCB、红外对管模块、28BYJ-48步进电机及ULN2003驱动板、0.96寸OLED、HC-08蓝牙模块、DS18B20温度传感器、蜂鸣器、若干电阻电容、12V电源适配器。总成本大概在80-120元之间并不贵。搭建的顺序建议是先在面包板上搭最小系统把OLED点亮再逐步接入传感器、电机、蓝牙。每一部分单独调试通过后再整合这样出问题时排查范围能控制得很小。编译烧录方面使用ST-Link V2下载器用SWD四线接口VCC、GND、SWDIO、SWCLK连接板子在Keil的Flash配置里选ST-Link点击下载即可。这里有个新手很容易踩的坑如果下载时提示找不到目标设备先检查ST-Link和板子之间的接线是否牢固再确认板子供电是否正常不要一上来就怀疑芯片坏了。固件烧录成功之后先用USB转TTL把蓝牙模块连到电脑通过AT指令初始化波特率然后用手机蓝牙助手连接模块测试上位机通信是否正常。全部就绪后把输液器滴壶装到红外对管中间用注射器往滴壶里注水模拟药液滴落就能看到OLED上滴速开始跳动了。这一步能跑通你的小系统就算真正工作了。6.3 基于源代码做二次开发的几条路线这套系统我已经把底层写好了如果你想在这个基础上做自己的项目有几条比较顺的路线可以参考。一个是接WiFi模块把数据上报到IoT平台。现在HC-08蓝牙的通信距离只有10米左右基本要求手机在旁边才能监控。如果你把蓝牙模块换成ESP8266或ESP-01S通过AT指令接入路由器再把数据通过MQTT协议发布到公共的物联网平台就能做到全球范围内远程监控家属在公司都能看到老人的输液情况。硬件上只需要改一个模块的接线和串口驱动协议层要自己写MQTT客户端代码量不大。一个是增加语音提示模块。用SYN6288或XFS5152这类语音合成模块接在串口或I2C上就能在报警时播报药液即将输完请及时处理这类语音提示。对老人来说蜂鸣器嘀嘀嘀的报警音容易听不明白语音提示显然更友好。我测试过SYN6288效果挺好唯一要注意的是模块需要独立供电不推荐直接从单片机3.3V脚取电电流不够会导致语音卡顿或芯片复位。还有一个方向是记录输液历史数据。这个系统的实时监控已经做到了但如果需要回看过去几个小时的滴速变化曲线目前的存储空间不够用。你可以把数据通过串口上传到上位机软件在PC端做数据可视化和趋势分析甚至可以训练一个简单的模型来预测需要更换药液的时间。这个方向偏软件但结合系统本身的数据输出能力是很好的扩展点。6.4 关于开源我的一些真实想法最后说点掏心窝的话。为什么我愿意把代码、原理图和仿真全部开源因为我自己学STM32的时候就是从别人的开源项目一点点扒起来的。当时很多资料是不完整的要么只有代码没有原理图要么有原理图但代码缺东少西遇到一个问题要在好几个论坛之间来回横跳才能拼凑出答案。这种痛苦我相信每个嵌入式学习者都经历过。所以我在整理这个项目资料的时候特意把所有能想到的细节都写进了文档包括那些我觉得很简单所以不用说的东西。我始终认为一个开源项目的价值不仅在于它实现了什么功能更在于后来者能不能从中真正学到东西。如果你能通过这个项目把STM32的定时器、外部中断、PID控制、串口通信这些知识点串起来那我开源这个项目的意义就达到了。最后再分享一个小技巧做这类单片机项目的时候一定要养成随时写文档的习惯。不要等整个项目做完了再回头补那时候很多细节早就忘了。我在每个模块调试完的当天就把遇到的问题、解决思路、验证结果记录到Markdown文件里。等到写项目说明文档的时候就是把这些零散记录整理一遍而已完全不会觉得累。这个习惯在开源社区里也很受欢迎——一个带完整调试日志的README比一百行代码很完美的描述有用的多。