1. 项目概述与核心思路最近几年全球性的公共卫生事件让很多人开始关注医疗资源的可及性问题。作为一名长期混迹于开源硬件和嵌入式开发领域的爱好者我注意到在特定紧急情况下一些基础的、维持生命的医疗设备如呼吸机其供应可能会面临巨大压力。这促使我思考能否利用我们手边常见的电子元件和开源技术构建一个原理性的、低成本的呼吸辅助装置原型请注意这绝对不是一个可以替代正规医疗设备的成品而是一个纯粹用于教育、研究和极端紧急情况下如专业设备完全无法获得时最后手段的实验性探索项目。它的核心价值在于揭示呼吸机的基本工作原理并为技术社区提供一个讨论和学习的起点。这个项目的核心目标是验证一个想法使用高性价比、易获取的组件实现呼吸机最基础的功能——周期性地、可控地为模拟肺部提供一定体积的空气。我选择了乐鑫的ESP32作为主控一方面是因为其强大的双核处理能力和丰富的周边接口如PWM、ADC、I2C等非常适合实时控制另一方面其内置的Wi-Fi/蓝牙模块为未来的远程监控或数据上报留下了可能性。驱动部分我选用了在3D打印机和CNC领域非常成熟的NEMA 17步进电机搭配DVR8825驱动模块以确保推杆动作的精确性和可重复性。执行机构则是一个手动复苏球AMBU bag通过一个由步进电机驱动的“铲斗”机构来挤压模拟人工通气。整个系统的成本在我采购时控制在了100欧元以内约合人民币700多元所有材料均来自常见的线上电商平台或本地五金店。这充分体现了开源硬件和DIY精神在降低技术门槛和成本方面的巨大潜力。在开始之前我必须再次强调安全警告本项目构建的设备不具备任何医疗认证不能用于临床治疗缺乏关键的安全机制如压力监控、氧浓度监测、故障冗余等。它仅适用于学术研究、原理演示或在绝对没有其他选择且由专业人士进行风险评估后的极端场景。请务必以审慎和负责任的态度对待这个项目。2. 核心硬件选型与设计解析2.1 主控制器为什么是ESP32在众多微控制器中选择ESP32是经过深思熟虑的。首先呼吸机的控制逻辑虽然不复杂但需要稳定的定时循环和实时响应。ESP32的240MHz双核处理器允许我将核心控制逻辑如步进电机脉冲生成、传感器读取放在一个核心上而将用户界面UI更新、网络通信等任务放在另一个核心上避免了任务阻塞导致控制周期不稳定。其次其丰富的GPIO口可以轻松连接两个步进电机驱动器、多个传感器和显示屏。最后内置的Wi-Fi意味着未来可以很容易地添加远程监控功能例如通过网页或手机APP查看呼吸频率、潮气量估算值和设备状态这在原型开发阶段对于调试和演示非常有用。注意在医疗设备设计中可靠性是第一位的。虽然ESP32性能强大但其作为消费级芯片工作温度范围、长期稳定性、抗电磁干扰能力等方面与工业级或医疗级芯片有差距。在本实验项目中我们接受这种折衷但在任何严肃的应用中必须选用经过认证的专用医疗控制器。2.2 动力与传动系统步进电机的精确控制呼吸机需要精确控制每次推送的空气体积潮气量和推送的速度吸气流速。直流电机编码器的方案可能更安静、更平滑但成本和控制复杂度较高。舵机则通常行程有限。NEMA 17步进电机是一个折中的优秀选择它提供开环位置控制无需额外的位置传感器就能实现精确的角位移进而转换为直线位移成本低廉扭矩充足且有成熟的驱动生态。我使用了两个NEMA 17电机采用并联同步驱动的方式。最初尝试单电机时发现挤压AMBU气囊到所需体积例如成人需要的500ml末端需要较大的扭矩单电机在低速高扭矩下容易失步或过热。使用双电机并联驱动同一根丝杆通过联轴器连接可以分摊负载提高系统的可靠性和推力。驱动芯片选用DVR8825它支持最高1/32微步能让电机运行更平稳减少振动和噪音这对于需要长时间稳定运行的设备很重要。传动机构采用了常见的3D打印机线性模组方案两根8mm的光轴作为导轨搭配直线轴承确保移动平台平稳直线运动一根8mm导程的T型丝杆将电机的旋转运动转换为平台的直线运动。通过计算我们可以精确地将步进电机的步数转换为平台的直线位移从而精确控制挤压AMBU气囊的深度间接控制送气量。位移与潮气量估算 假设丝杆导程为8mm即电机转一圈平台移动8mm。电机采用1/16微步每转需要200*163200步。那么每步对应的直线位移是 8mm / 3200 0.0025mm/步。 AMBU气囊的挤压体积与挤压深度并非线性关系需要通过实验标定。我们可以先让电机从初始位置气囊饱满运行到完全压瘪位置记录总步数S_total。然后通过测量或查阅AMBU规格书得知气囊完全压瘪时排出的气体体积V_total例如1500ml。那么一个粗略的线性估算关系是目标潮气量V_tidal对应的步数S_target (V_tidal / V_total) * S_total。在实际操作中必须在平台上安装一个限位开关或霍尔传感器作为“归零”参考点每次启动都从该点开始计算步数以保证一致性。2.3 “肺”模型AMBU手动复苏球AMBUArtificial Manual Breathing Unit气囊是急救领域的标准装备本身就是一个完整的手动呼吸辅助设备。我们用它作为我们的“执行终端”和“气体储存/输送单元”有几个好处1) 它自带单向阀系统能保证气体单向流动防止患者呼出的气体回流污染气源2) 它结构简单可靠易于消毒和更换3) 其压缩特性压力-体积关系相对稳定便于标定。在我们的设计中AMBU被固定在一个支架上其气囊部分位于一个可移动的“铲斗”下方。当步进电机驱动平台向前运动时铲斗会挤压气囊将气体通过管路推出。我们需要根据目标患者的潮气量需求来调整铲斗的最大行程。不同型号的AMBU成人、儿童、婴儿其气囊容量不同需要分别标定。2.4 传感与用户交互为了构建一个相对完整的原型我添加了以下模块霍尔传感器用于建立移动平台的“原点”。在平台运动路径的起点和终点或仅起点安装霍尔传感器和磁铁。设备启动时电机会先反向运动直至触发原点传感器以此作为所有位置计算的基准。这消除了因失步造成的累积误差。温度传感器在步进电机外壳上粘贴DS18B20等数字温度传感器。步进电机在低速、高扭矩下长时间工作容易发热。设置一个温度阈值如70°C当超过时触发蜂鸣器报警并暂停运行防止电机损坏。旋转编码器或电位器用于现场调节参数。我使用了两个模拟电位器分别连接到ESP32的ADC引脚一个映射为呼吸频率如10-30次/分钟另一个映射为潮气量估算值。这样可以在不连接电脑的情况下快速调整。TFT显示屏使用一块SPI接口的TTGO T-Display集成ESP32和屏幕可以实时显示当前频率、潮气量、电机温度、运行状态等信息极大提升了交互性。蜂鸣器用于声音报警提示设备故障如电机过热、无法归零等。3. 机械结构设计与组装要点整个机械结构的设计灵感来源于CoreXY或H-Bot型的3D打印机其目标是实现一个坚固、稳定、低摩擦的直线运动平台。3.1 框架与材料主体框架采用10mm厚的DM板中密度纤维板切割而成。DM板成本低易于加工激光切割或CNC且有足够的刚性。关键承重和连接部位使用5mm厚的亚克力板进行加固。所有结构件通过CAD软件如Fusion 360设计好导出DXF文件进行切割。设计原则刚性优先呼吸机动作会产生周期性的反作用力框架必须足够坚固避免晃动或共振否则会影响挤压精度并产生噪音。可维护性AMBU需要经常更换或消毒其固定方式应设计为快速装拆。电机和电子部分的盖板也应易于打开。安全间距所有运动部件如丝杆、联轴器必须有防护罩防止衣物或头发被卷入。高压电路部分12V电源应与低压控制电路ESP32做好隔离。3.2 运动平台与铲斗移动平台是核心运动部件。它由一块切割的DM板作为基板上面安装两个直线轴承座套在两根平行的8mm光轴上。一个丝杆螺母座连接T型丝杆。铲斗支架。铲斗本身是3D打印的PLA材料其形状需要与AMBU气囊的曲面贴合以实现均匀、平稳的挤压。铲斗的弧度需要经过几次打印测试来优化目标是挤压过程中气囊不会向两侧滑脱。平台的运动范围由丝杆的有效行程和机械限位决定。需要在CAD设计中精确计算确保铲斗能从完全离开气囊的位置运动到将气囊完全压瘪的位置且不与其他结构发生干涉。3.3 电机安装与同步两个NEMA 17电机分别安装在框架的两侧通过柔性联轴器与丝杆的两端连接。确保两根丝杆的螺纹旋向相同并且电机转向设置正确才能使两个电机协同工作一个“推”一个“拉”避免形成扭矩对抗。电机安装座需要设计得足够牢固并预留散热孔。组装校准步骤先组装框架确保各面板垂直、平行。安装光轴使用角尺确保两根光轴绝对平行这是平台运动顺畅的关键。安装丝杆手动旋转丝杆检查其与光轴的平行度。将安装好直线轴承和螺母座的平台套入光轴和丝杆手动推动平台应感觉全程顺滑无卡顿。如果卡顿需重新调整光轴或丝杆的平行度。最后安装电机和联轴器。联轴器能吸收少量的同轴度误差但安装时仍应尽量使电机轴与丝杆轴对中。4. 电路连接与电源管理4.1 系统接线图整个系统的电路可以分为低压控制部分和高压驱动部分。低压控制部分5V/3.3VESP32开发板核心控制器。TTGO T-Display通过SPI总线CLK, MOSI, MISO, DC, CS, RST连接ESP32的对应GPIO。霍尔传感器两个输出信号接ESP32的数字输入引脚内部上拉磁铁靠近时输出低电平。DS18B20温度传感器数据线接ESP32的一个数字引脚需要接一个4.7kΩ上拉电阻到3.3V。电位器两个中间抽头分别接ESP32的ADC引脚如GPIO34, GPIO35两端分别接3.3V和GND。有源蜂鸣器信号线接ESP32的一个数字引脚通过一个三极管或MOSFET驱动因为ESP32引脚驱动能力有限。高压驱动部分12V12V 3A直流电源为整个系统供电。注意其功率是否足够两个步进电机在堵转时电流可能达到1.5A每个加上其他损耗3A电源是基本要求建议留有裕量。DC-DC降压模块将12V降压至5V为ESP32、显示屏和其他传感器供电。非常重要切勿直接用12V电源连接ESP32两个DVR8825驱动模块VMOT接12V电源正极。GND接12V电源负极并与ESP32的GND共地。1B, 1A, 2A, 2B分别接两个步进电机的四相线。STEP接ESP32的脉冲输出引脚如GPIO12, GPIO14。DIR接ESP32的方向控制引脚如GPIO13, GPIO15。ENABLE接ESP32的一个引脚可用于使能或休眠电机低电平有效。关键设置DVR8825上的电流调节电位器需要根据你的电机额定电流来设置。用万用表测量VREF引脚电压计算公式I_rms V_ref * 2。例如电机额定电流1.2A则设置V_ref 0.6V。电流设置过小会导致电机力不足失步设置过大会导致电机和驱动器严重发热。4.2 电源安全与抗干扰去耦电容在12V电源输入端和每个DVR8825的VMOT引脚附近并联一个100μF的电解电容和一个0.1μF的陶瓷电容以滤除电源噪声和电机启停产生的电压尖峰。地线分离与单点共地电机驱动的大电流回路会产生严重的地噪声。布线时尽量将电机驱动部分12V地的走线与控制部分3.3V/5V地的走线分开最后在电源入口处或DC-DC模块的GND点进行单点连接。信号隔离如果条件允许可以在ESP32的STEP/DIR信号线和DVR8825之间加入光耦隔离模块彻底阻断电机侧噪声对控制电路的干扰。这对于提高系统稳定性非常有益。5. 核心软件逻辑与代码实现软件部分的核心是创建一个稳定、可调的定时控制循环精确地控制步进电机完成“吸气-呼气”周期。5.1 开发环境与库使用Arduino IDE进行开发需要安装以下库AccelStepper这是一个非常优秀的步进电机控制库它支持加减速曲线能让我们电机的启动和停止更平滑减少对机械结构的冲击。TFT_eSPI用于驱动TTGO T-Display的屏幕。OneWire和DallasTemperature用于驱动DS18B20温度传感器。Blynk可选用于实现物联网远程监控。5.2 主程序状态机程序的核心是一个状态机通常包含以下几个状态STATE_HOMING归零状态。上电或复位后控制电机向后退直到触发“原点”霍尔传感器。找到原点后将电机位置计数器清零。STATE_IDLE空闲状态。等待用户启动。在此状态下屏幕更新参数读取电位器值更新目标频率和潮气量。STATE_INSPIRATION吸气状态。控制电机正向旋转驱动铲斗挤压AMBU气囊。运动的目标位置由当前设定的潮气量计算得出。运动速度由设定的吸气时间或吸气流速决定。AccelStepper库可以设置一个目标位置和最大速度它会自动计算加速度并平滑运行到位。STATE_PAUSE_AT_TOP吸气末暂停。有些呼吸模式需要屏气这个状态就是维持当前位置短暂时间。STATE_EXPIRATION呼气状态。控制电机快速反向旋转回到原点或一个略高于原点的位置避免持续挤压气囊。呼气过程通常是被动的依靠患者肺的弹性回缩力所以电机可以较快速度返回。STATE_PAUSE_AT_BOTTOM呼气末暂停。等待设定的呼气时间结束然后开启下一个呼吸周期。状态之间的切换由定时器中断或millis()函数进行精确的时间控制。呼吸周期T_total 60 / 呼吸频率。然后根据设定的吸呼比I:E Ratio例如1:2分配吸气时间T_insp和呼气时间T_exp。5.3 关键代码片段解析#include AccelStepper.h // 定义步进电机引脚 #define MOTOR_STEP_PIN 12 #define MOTOR_DIR_PIN 13 #define MOTOR_ENABLE_PIN 25 // 低电平使能 // 定义霍尔传感器引脚 #define HOME_SENSOR_PIN 26 // 定义电机参数 #define MOTOR_STEPS_PER_REV 200 #define MICROSTEPS 16 #define LEAD_SCREW_PITCH 8.0 // 丝杆导程单位mm // 计算电机每步对应的平台直线位移 (mm) const float mm_per_step LEAD_SCREW_PITCH / (MOTOR_STEPS_PER_REV * MICROSTEPS); // 全局变量 AccelStepper stepper(AccelStepper::DRIVER, MOTOR_STEP_PIN, MOTOR_DIR_PIN); long target_position_steps 0; long home_position_steps 0; bool is_homed false; void setup() { Serial.begin(115200); pinMode(HOME_SENSOR_PIN, INPUT_PULLUP); pinMode(MOTOR_ENABLE_PIN, OUTPUT); digitalWrite(MOTOR_ENABLE_PIN, LOW); // 使能电机 // 配置步进电机参数 stepper.setMaxSpeed(1000); // 最大速度单位步/秒 stepper.setAcceleration(500); // 加速度单位步/秒^2 // 注意这里的速度需要根据实际机械结构和需求调整。速度太快可能导致失步或振动。 // 执行归零 performHoming(); } void loop() { // 1. 读取电位器更新目标频率和潮气量 updateParametersFromPotentiometers(); // 2. 根据当前状态执行相应操作 switch (current_state) { case STATE_IDLE: updateDisplay(); // 刷新屏幕显示 break; case STATE_INSPIRATION: if (stepper.distanceToGo() 0) { // 到达吸气目标位置 current_state STATE_PAUSE_AT_TOP; pause_start_time millis(); } break; case STATE_PAUSE_AT_TOP: if (millis() - pause_start_time pause_time_top_ms) { current_state STATE_EXPIRATION; stepper.moveTo(home_position_steps); // 移动回原点 } break; case STATE_EXPIRATION: if (stepper.distanceToGo() 0) { current_state STATE_PAUSE_AT_BOTTOM; pause_start_time millis(); } break; case STATE_PAUSE_AT_BOTTOM: if (millis() - pause_start_time pause_time_bottom_ms) { // 开始新的呼吸周期 calculateNextBreath(); // 根据新参数计算目标位置 current_state STATE_INSPIRATION; stepper.moveTo(target_position_steps); } break; } // 3. 必须持续调用 run() 函数电机才会运动 stepper.run(); // 4. 检查温度等安全监控 checkSafety(); } void performHoming() { Serial.println(开始归零...); stepper.setSpeed(-200); // 设置一个适中的归零速度负方向 while (digitalRead(HOME_SENSOR_PIN) HIGH) { // 传感器未触发继续向负方向移动 stepper.runSpeed(); } // 传感器触发停止 stepper.stop(); delay(50); // 缓慢离开传感器寻找精确的触发边沿 stepper.setSpeed(50); while (digitalRead(HOME_SENSOR_PIN) LOW) { stepper.runSpeed(); } // 现在传感器刚好释放位置设为0 stepper.setCurrentPosition(0); home_position_steps 0; is_homed true; Serial.println(归零完成。); stepper.moveTo(0); // 回到零点 }代码要点说明AccelStepper库的moveTo()和run()组合是实现非阻塞运动控制的关键。moveTo()设置目标run()在loop()中持续调用驱动电机平滑运动。归零逻辑采用了“触碰-回退”的方式以提高重复定位精度。所有时间控制都使用millis()进行非阻塞比较避免使用delay()阻塞整个程序。吸气目标位置target_position_steps需要通过潮气量标定实验得出的公式进行计算。5.4 物联网功能扩展Blynk通过集成Blynk库可以将设备数据同步到手机APP。创建一个简单的仪表板显示实时呼吸频率、估算潮气量、电机温度并可以设置频率和潮气量参数。更重要的是可以实现报警功能例如当设备在运行中超过设定时间仍未触发原点传感器可能卡住ESP32可以通过Wi-Fi向Blynk服务器发送事件Blynk再推送通知到手机或发送邮件。// 示例Blynk报警触发 if (motor_stalled) { Blynk.logEvent(device_alert, 呼吸机电机堵转请立即检查); // 同时触发本地蜂鸣器 digitalWrite(BUZZER_PIN, HIGH); }6. 系统标定、测试与安全考量6.1 潮气量标定这是最关键的一步建立“步进电机步数”与“输出气体体积”之间的关系。准备一个校准用的“肺模型”一个已知容积的密闭容器如2升的校准用呼吸袋或一个带刻度的玻璃钟罩。将AMBU出口通过管路连接到这个容器。在程序中让电机从原点开始运行一个固定的、较大的步数例如对应完全压瘪气囊记录这个步数S_full。测量容器内增加的气体体积V_full。计算比例系数K V_full / S_full(ml/步)。此后要输送目标潮气量V_tidal所需的步数就是S_tidal V_tidal / K。重要提示这个线性关系是近似的。实际上气囊在不同压缩阶段的体积变化率不同。为了更精确可以进行多点标定制作一个查找表。例如每挤压100步记录一次体积最终建立一个“步数-体积”曲线。6.2 呼吸模式测试使用一个简单的肺模拟器例如用一个带小孔泄气的密闭气囊模拟肺的顺应性和阻力进行测试。测试1频率与潮气量准确性。设置不同的频率12, 15, 20次/分和潮气量300ml, 500ml用秒表和校准过的肺模型测量实际输出与设定值对比计算误差。测试2吸呼比。通过高速摄像或传感器记录铲斗运动验证吸气时间和呼气时间是否符合设定的吸呼比如1:2。测试3长时间运行稳定性。让设备连续运行数小时监控电机温度、位置是否漂移、机械结构有无松动。6.3 安全机制与局限性必须清醒认识到本原型机的局限性并尽可能添加软件安全机制压力安全缺失真正的呼吸机有高压报警防止气压伤和低压报警防止管路脱落。本设备没有压力传感器无法监测气道压力。这是最致命的缺陷。冗余设计缺失核心控制器、电机、电源都是单点。一旦故障设备立即停止。氧浓度控制本设备推送的是环境空气约21%氧浓度。对于需要高氧支持的患者无法调节。软件安全逻辑堵转检测在STATE_INSPIRATION状态如果电机持续运行超过最大预期时间仍未到达目标位置应触发报警并停止。温度监控持续读取电机温度超过阈值如70°C则降频运行或停机报警。通信看门狗如果使用了Blynk可以设置软件看门狗当网络中断或控制信号异常时设备应转入安全模式如保持呼气末状态并报警。参数范围限制在代码中硬性限制频率如6-40次/分、潮气量如200-800ml的范围防止误操作设定危险值。7. 总结反思与未来改进方向完成这个项目后我深刻体会到医疗设备设计与普通创客项目之间的鸿沟。我们能够用很低的成本复制出“形似”的动作但距离“神似”——即满足安全、可靠、有效这些医疗级要求——还有漫长的路要走。这个项目最大的意义在于教育性和启发性它让复杂的医疗设备原理变得触手可及为工程师、医学生和爱好者提供了一个绝佳的跨学科学习平台。我个人在实际操作中的几点深刻体会机械精度远高于预期需求最初担心3D打印件和普通丝杆的精度不够。实际上对于呼吸机这种相对“粗糙”的位移控制毫米级开源硬件的精度完全足够。真正的挑战在于可靠性和一致性即能否在数百万次循环后依然保持初始精度。软件比硬件更复杂让电机动起来很简单但构建一个稳定、抗干扰、带完整状态管理和错误处理的控制逻辑需要仔细的设计和大量的测试。一个delay()误用就可能导致整个循环周期紊乱。安全是设计出来的不是附加的在项目后期才考虑添加各种报警和监控会发现很被动。应该在架构设计之初就把安全监控如周期超时、位置异常、温度过高作为核心状态的一部分来设计。如果作为一个更严肃的原型未来可以从以下几个方面改进增加压力传感在AMBU出口管路添加一个医用级压力传感器如MPXV7002DP实时监测气道压力。软件上实现压力限制高压报警和持续气道正压CPAP等基本模式。引入闭环控制从简单的开环位置控制升级为“容积-压力”双闭环控制。例如以目标潮气量为主要控制目标同时以气道压力为安全限制条件进行调节。提升可靠性使用工业级步进电机和驱动器采用金属丝杆和线性滑轨为ESP32设计独立的PCB而非使用开发板增加备用电池在主电源失效时维持报警电路工作。完善人机交互使用旋转编码器按键替代电位器操作更精准设计更直观的UI界面显示压力-时间波形图。进行标准化测试与生物医学工程人员合作使用专业的肺模拟器进行符合规范的测试量化其性能参数。最后我开源这个项目的所有设计文件、代码和文档是希望它能够成为一个“种子”。也许某天在资源极度匮乏的特殊环境下有专业人士能基于这个基础快速迭代出一个能临时救急的方案。而在那之前它最好的归宿就是我们的工作台、实验室和课堂帮助我们理解技术如何服务于生命。