在医疗科技迅猛发展的当下,智能化、精准化医疗成为行业发展的主流方向。但输液监控环节仍以传统人工巡查为主。
在患者比较多时,护士们往往无法时刻关注每个病人的输液情况。大型综合医院里,护士每班人均需监管 20 - 30 个病床的输液情况,高峰时巡查间隔超 30 分钟,极大增加了输液异常难以及时发现的风险。
本课程通过介绍物联网在医疗设施中的应用,引导学生展开病患输液监测系统的实践探索。
学习目标

学习活动1

Q:系统需要获取哪些数据?
A同学:作为护士,希望在护士站就能实时看到所有病床的输液滴速,以便及时发现异常并调整,避免患者输液过快或过慢影响治疗效果。
B同学:作为患者家属,希望能在病床旁的显示屏上清晰看到剩余输液时间,心里更踏实,也方便安排后续事务。
C同学:作为医生,希望系统能自动记录患者的输液数据,以便分析治疗效果和调整治疗方案。
学习活动2

1.需求分析
需求环节 | 功能需求描述 |
采集数据 | 实时获取输液滴速数据 |
传输与存储数据 | 将获取的数据发送到物联网服务平台 |
分析处理数据 | 分析输液滴速数据与输液袋余量、已输液量、剩余输液时间之间的关系 |
反馈与控制 | 输液袋余量数据超出阈值范围时,进行报警提醒 |
2.功能实现
滴速监测:利用红外传感器检测液滴对红外线的遮挡次数,通过算法转换为滴速。
输液余量计算:根据输液管横截面积、已采集滴数和每滴液体体积,运用公式计算剩余液体体积。
剩余输液时间计算:结合当前滴速和剩余液体体积,通过除法运算得出并实时更新。
低液位报警:液位传感器检测到液位低于设定阈值时,触发病床端声光报警和护士站消息提醒。
数据传输:通过Wi-Fi 模块,按特定传输协议将病床端数据发送到护士站。
3.算法设计
根据需求分析与功能实现绘制流程图。
(1)病床端流程图

(2)护士站端流程图

学习活动3

任务1:硬件搭建
1. 选择传感器、主控板等物联实验设备。
(1)行空板K10

功能:主控设备,集成WiFi、LCD显示、GPIO接口等。
特点:支持Mind+图形化编程与MicroPython代码编程。
(2)红外对管

功能:检测液滴下落频率,计算滴速。
接口:数字信号输出(接K10的GPIO0)。
(3)有源蜂鸣器

功能:发出报警声音。
接口:数字信号输出(接K10的GPIO1)。
接线
(1)病床端接线图

(2)护士站接线图

固件烧录
固件(附件1)
K10-micropython-educore-V0.1-250208.bin
烧录工具flash_download_tool
https://dl.espressif.com/public/flash_download_tool.zip
代码编辑器Thonny
https://github.com/thonny/thonny/releases/download/v4.1.7/thonny-4.1.7.exe
(1)打开固件烧录软件flash_download_tool,选择ESP32-S3

(2)选择固件文件、COM口,点击ERASE按钮,擦除固件

(3)等待,直到擦除完成,出现FINISH完成

(4)点击START按钮,开始烧录固件

(5)等待,直到烧录完成,出现FINISH完成

(6)打开Thonny软件,依次选择菜单运行->配置接收器,并做如下图配置

2. 设置无线网络。

3. 配置物联网服务平台。

4. 确定传感器的位置。
任务2:采集数据
(1)滴速监测
原理:
红外对管传感器由红外发射管(IR LED)和接收管(光敏三极管/光电传感器)对射安装,中间为液滴下落路径。
无液滴时:红外光持续照射接收管,接收端输出稳定的高/低电平。
液滴经过时:液滴遮挡红外光路径,接收端因光强突变产生电平跳变(如高→低→高),形成脉冲信号。
公式:

任务3:传输与存储数据
在物联系统中,物联网服务平台负责数据的存储,主控板负责读取传感器数据并通过网络发送给物联网服务平台。在该项目中,行空板K10先连接Wifi网络,再连接到物联网服务平台SIOT v2,然后不停地读取传感器的数据,并把这些数据上传到物联网服务平台SIOT v2。
(1)上传输液开始数据到物联网平台
上传输液开始数据程序实现

物联网平台输液开始数据展示

(2)上传输液结束数据到物联网平台
上传输液结束数据程序实现

物联网平台输液结束数据展示

(3)上传低液量报警数据到物联网平台(网络报警功能)
上传低液量报警数据程序实现

物联网平台低液量报警数据展示

任务4:分析处理数据
(1)输液余量计算(剩余液体体积)
原理:
滴速乘以已输注时间得到的是已经滴出的总滴数,再除以滴系数就可以将总滴数换算成对应的液体体积(mL),就是已经输注的液体量(mL)。用总液量减去已经输注的液体量,就得到了剩余液量。
公式:

总液量(mL):指一开始准备输注的液体总体积,单位为毫升(mL)。
滴速(滴 / 分钟):表示每分钟输液的滴数,即输液过程中液体滴落的速度。
已输注时间(分钟):是指从开始输液到当前时刻所经过的时间,单位为分钟。
滴系数(滴 /mL):指每毫升液体对应的滴数,不同的输液器可能有不同的滴系数,常见的有 10 滴 /mL、15 滴 /mL、20 滴 /mL 等。
(2)剩余输液时间计算(预估完成时间)
原理:
通过将剩余液量乘以滴系数,得到剩余液体对应的总滴数,再除以滴速,从而得出以分钟为单位的剩余输液时间。
公式:

剩余液量(mL):即当前输液容器中尚未输注的液体体积,单位是毫升。它反映了输液进程中还剩下多少量的液体有待输入人体。
滴系数(滴 /mL):指的是每毫升液体所对应的滴数。不同规格的输液器,其滴系数会有所不同,常见的数值有 10 滴 /mL、15 滴 /mL、20 滴 /mL 等。这一参数是将液体体积与滴数进行转换的关键依据。
滴速(滴 / 分钟):表示每分钟内液体从输液管中滴下的数量。它体现了输液的速度快慢,是控制输液节奏的重要指标。
任务5:实现反馈与控制
(1)低液量触发视觉报警、声音报警

程序设计(主要功能模块及说明)

1.病床端程序设计
病床端程序实现了对输液过程的实时监测、指标计算、界面显示以及异常报警等功能,通过与硬件设备(如滴液传感器、蜂鸣器)和网络(WiFi、MQTT)的协同工作,为护士站中央监护系统提供准确的输液数据,并在出现异常情况时及时发出警报。
(1)AppConfig 类
功能概述:AppConfig 类作为整个智能输液监控系统的全局配置中心,集中管理了系统运行所需的各类参数,包括网络连接(WiFi 和 MQTT)、硬件设备以及安全限制等方面的配置信息。通过这种集中管理方式,使得系统的配置参数易于修改和维护,增强了代码的可扩展性和可维护性。
class AppConfig:
"""应用程序全局配置"""
# WiFi配置
WIFI_SSID = "GOCLOUD" # 无线网络名称
WIFI_PASSWORD = "L2100Hbb" # WiFi密码
WIFI_TIMEOUT_MS = 50000 # 连接超时(毫秒)
WIFI_MAX_RETRIES = 3 # 最大重试次数
# MQTT配置
MQTT_SERVER = "192.168.123.16" # 消息代理地址
MQTT_PORT = 1883 # 服务端口
MQTT_USER = "siot" # 认证用户名
MQTT_PASSWORD = "dfrobot" # 认证密码
MQTT_MAX_RETRIES = 3 # 连接重试次数
ALARM_TOPIC = "siot/infusion_alarm" # 输液报警主题
START_TOPIC = "siot/infusion_start" # 输液开始主题
END_TOPIC = "siot/infusion_end" # 输液结束主题
# 硬件参数
HARDWARE_DEBOUNCE_MS = 50 # 传感器消抖时间(毫秒)
DISPLAY_REFRESH_MS = 1000 # 屏幕刷新间隔(毫秒)
BUZZER_FREQ = 2000 # 蜂鸣器频率(Hz)
BUZZER_DURATION_MS = 500 # 蜂鸣持续时间(毫秒)
SENSOR_PIN = 0 # 滴液传感器GPIO引脚
SPEAKER_PIN = 1 # 蜂鸣器控制引脚
# 安全参数(成人标准)
SAFETY_MIN_DROP_RATE = 40 # 最低安全滴速(滴/分钟)
SAFETY_MAX_DROP_RATE = 60 # 最高安全滴速(滴/分钟)
WiFi 配置:包含无线网络名称、密码、连接超时时间和最大重试次数,用于设备连接到指定的 WiFi 网络。
MQTT 配置:指定了 MQTT 消息代理的地址、端口、认证信息、连接重试次数以及不同事件的 MQTT 主题,用于设备与 MQTT 服务器进行通信。
硬件参数:设置了传感器消抖时间、屏幕刷新间隔、蜂鸣器的频率和持续时间,以及滴液传感器和蜂鸣器所连接的 GPIO 引脚。
安全参数:定义了输液的最低和最高安全滴速,用于约束计算得到的滴速。
(2)InfusionMetrics 类
功能概述:InfusionMetrics 类作为数据模型,用于封装输液过程中的关键指标数据。通过将这些指标数据整合到一个类中,方便在系统的不同模块之间进行传递和使用,提高了数据的组织性和可管理性。
class InfusionMetrics:
"""输液过程指标数据容器
属性:
- drop_rate: 当前滴速(滴/分钟)
- elapsed_time: 已输注时间(HH:MM:SS)
- remaining_volume: 剩余液量(毫升)
- remaining_time: 预计剩余时间(HH:MM:SS)
"""
def __init__(self, drop_rate, elapsed_time, remaining_volume, remaining_time):
self.drop_rate = drop_rate
self.elapsed_time = elapsed_time
self.remaining_volume = remaining_volume
self.remaining_time = remaining_time
(3)InfusionCalculator 类
功能概述:InfusionCalculator 类是输液指标的计算引擎,负责根据输入的相关参数计算输液过程中的各项关键指标,如滴速、已输注时间、剩余液量和预计剩余时间等。通过将计算逻辑封装在这个类中,实现了计算功能的模块化,提高了代码的复用性和可维护性。
class InfusionCalculator:
"""输液指标计算引擎"""
@staticmethod
def calculate(current_time, start_time, drop_count, total_ml, drop_factor, cfg):
"""执行所有指标计算
参数:
current_time -- 当前时间(毫秒ticks)
start_time -- 输液开始时间(毫秒ticks)
drop_count -- 累计滴数
total_ml -- 输液总量(毫升)
drop_factor -- 滴系数(滴/毫升)
cfg -- 配置对象
返回:
InfusionMetrics对象包含计算结果
"""
# 计算经过时间(防止除零)
elapsed_ticks = max(time.ticks_diff(current_time, start_time), 1)
elapsed_min = elapsed_ticks / 60000 # 转换为分钟
# 有效滴数处理(防止负数)
valid_drops = max(drop_count, 0)
# 计算原始滴速并约束到安全范围
raw_rate = valid_drops / elapsed_min
safe_rate = clamp(raw_rate, cfg.SAFETY_MIN_DROP_RATE, cfg.SAFETY_MAX_DROP_RATE)
# 计算液量
infused_ml = min(valid_drops / drop_factor, total_ml)
remaining_ml = max(total_ml - infused_ml, 0)
# 估算剩余时间(基于安全滴速)
remain_min = (remaining_ml * drop_factor / safe_rate) if safe_rate > 0 else 0
return InfusionMetrics(
safe_rate,
format_duration(elapsed_min),
remaining_ml,
format_duration(remain_min)
)
(4) InfusionMonitor 类
功能概述:InfusionMonitor 类是智能输液监控系统的主控制器,负责协调系统的各个组件和功能,实现对输液过程的全面监控。它涵盖了硬件设备的初始化、网络连接的建立、传感器数据的处理、用户界面的更新以及报警处理等多个方面,确保系统能够稳定、可靠地运行。
_handle_sensor方法:处理滴液传感器信号,具有消抖功能。读取传感器的当前状态,若状态发生变化且经过了消抖时间,则进行处理。当传感器输出低电平时(下降沿),若累计滴数未达到最大滴数,则增加累计滴数,并更新传感器状态和上次消抖时间。
def _handle_sensor(self, current_time):
"""处理滴液传感器信号(带消抖)"""
current_state = self.drop_sensor.read_digital()
# 状态变化检测
if current_state != self.last_sensor_state:
# 消抖时间检查
if time.ticks_diff(current_time, self.last_debounce_time) > self.cfg.HARDWARE_DEBOUNCE_MS:
# 下降沿触发计数(传感器输出低电平)
if current_state == 0:
max_drops = self.total_volume * self.drop_factor
if self.drop_count < max_drops:
self.drop_count += 1
print(f"[传感器] 滴数更新:{self.drop_count}")
# 更新状态记录
self.last_sensor_state = current_state
self.last_debounce_time = current_time
_render_metrics方法:绘制动态监测指标,包括当前滴速、已输注时间、剩余液量和预计剩余时间,让用户实时掌握输液的状态。
def _render_metrics(self, metrics):
"""绘制动态监测指标"""
y_pos = [90, 140, 190, 240] # 四行数据的Y坐标
self.display.print("Rate: {:.1f}/min".format(metrics.drop_rate), 20, y_pos[0])
self.display.print("Elapsed: {}".format(metrics.elapsed_time), 20, y_pos[1])
self.display.print("Volume: {:.1f}mL".format(metrics.remaining_volume), 20, y_pos[2])
self.display.print("Remain: {}".format(metrics.remaining_time), 20, y_pos[3])
(5)InfusionSimulator 类
功能概述:InfusionSimulator 类继承自 InfusionMonitor 类,主要用于在没有实际硬件设备的情况下对输液监控系统进行测试。它通过模拟滴液生成来替代真实的传感器输入,并增强了界面更新功能,在控制台输出监控数据,方便开发者进行调试和验证。
_handle_sensor方法:模拟滴液生成,根据基准滴速和随机波动生成滴液信号。当当前时间达到下次滴液时间时,生成随机间隔,更新下次滴液时间,并在累计滴数未达到最大滴数时增加累计滴数。
def _handle_sensor(self, current_time):
"""模拟滴液生成(替代真实传感器处理)"""
if current_time >= self.next_drop_time:
# 生成随机间隔(±20%波动)
variance = random.uniform(0.8, 1.2)
interval = (60000 // self.base_rate) * variance
self.next_drop_time = current_time + int(interval)
# 安全增加滴数
max_drops = self.total_volume * self.drop_factor
if self.drop_count < max_drops:
self.drop_count += 1
print(f"[模拟] 滴数:{self.drop_count}")
_update_interface方法:调用父类的 _update_interface 方法更新界面,同时在控制台输出监控数据,包括当前滴速、已用时间、剩余液量和预计剩余时间等信息,方便开发者实时查看模拟的输液状态。
def _update_interface(self, current_time):
"""增强界面更新(添加控制台输出)"""
metrics = super()._update_interface(current_time)
# 控制台打印监控数据
print("\n==== 实时监控 =====")
print(f"当前滴速: {metrics.drop_rate:.1f} 滴/分钟")
print(f"已用时间: {metrics.elapsed_time}")
print(f"剩余液量: {metrics.remaining_volume:.1f}mL")
print(f"预计剩余: {metrics.remaining_time}")
print("===================\n")
return metrics
2.护士站程序设计
护士站端程序实现了一个护士站中央监护系统,用于对多个床位的输液状态进行集中监控。系统能够接收来自各个输液设备的 MQTT 消息,包括输液开始、输液报警和输液结束消息,并进行相应的处理。当收到报警消息时,系统会触发声光警示,在TFT 屏幕上显示报警信息并控制蜂鸣器发声。系统还会在屏幕上绘制多个床位的状态显示框,方便护士直观查看各个床位的情况。
(1)AppConfig 类
功能概述:作为应用程序的全局配置中心,存储了系统运行所需的各种参数,包括网络连接(WiFi 和 MQTT)、硬件设备、显示参数以及报警坐标等信息,方便统一管理和修改。
(2)NurseStation 类
功能概述:护士站中央监护系统的核心类,负责系统的初始化、网络连接、消息接收与处理、床位状态显示以及报警处理等功能。
_process_alarm方法:处理报警消息,解析消息中的床号和报警信息,将床号添加到报警床位集合中,记录上次报警时间,触发蜂鸣器发声,并在屏幕上使报警文字闪烁显示。
def _process_alarm(self, msg):
"""处理报警消息
消息格式:"Bed-1|low volume:0.95mL"
"""
try:
# 先按 | 分割消息
parts = msg.split('|')
# 提取床号部分,例如从 Bed-1 中提取 1
bed_name = parts[0]
alarm_msg = parts[1]
bed_number = int(bed_name.split('-')[1])
print(f"[报警] 低液量:{bed_name} {alarm_msg}")
self.alarm_beds.add(bed_name)
self.last_alarm_time = time.ticks_ms()
self.alarm_flashing = True # 开启闪烁标志
# 文字闪烁逻辑
for _ in range(5): # 闪烁5次,可根据需要调整
self._trigger_buzzer()
self.display.print("Low Alarm", self.cfg.x_coordinates[bed_number - 1], self.cfg.y_coordinates[bed_number - 1])
time.sleep(0.5)
self.display.print(" ", self.cfg.x_coordinates[bed_number - 1], self.cfg.y_coordinates[bed_number - 1])
time.sleep(0.5)
self.alarm_flashing = False # 关闭闪烁标志
except ValueError as e:
print(f"消息解析错误,无法将床号转换为整数: {e}")
except IndexError as e:
print(f"消息格式错误,无法正确分割消息: {e}")
except Exception as e:
print(f"消息处理异常: {e}")
_process_start方法:处理输液开始消息,解析消息中的床号和开始时间,在屏幕上显示床号。
def _process_start(self, msg):
"""处理报警消息
消息格式:"Bed-1|start time:2025-02-06 12:28:15"
"""
try:
bed_name, start_time = msg.split('|')
print(f"[事件] {bed_name} {start_time}")
bed_number = int(bed_name.split('-')[1]) # 分割获取床号
self.display.print(bed_name, self.cfg.x_coordinates[bed_number - 1]+10, self.cfg.y_coordinates[bed_number - 1] - 50)
except Exception as e:
print("消息解析失败:", e)
_process_end方法:处理输液结束消息,解析消息中的床号和结束时间,在屏幕上清除该床位的显示信息。
def _process_end(self, msg):
"""处理报警消息
消息格式:"Bed-1|end time:2025-02-06 12:28:15"
"""
try:
bed_name, end_time = msg.split('|')
print(f"[事件] {bed_name} {end_time}")
bed_number = int(bed_name.split('-')[1]) # 分割获取床号
self.display.print(" ", self.cfg.x_coordinates[bed_number - 1]+10, self.cfg.y_coordinates[bed_number - 1] - 50)
except Exception as e:
print("消息解析失败:", e)
_on_alarm方法:报警消息回调函数,解析消息中的床号和报警信息,更新报警状态,将床号添加到报警床位集合中,记录上次报警时间,并触发蜂鸣器发声。
def _on_alarm(self, topic, msg):
"""报警消息回调"""
try:
bed_name, alarm_msg = msg.split('|')
print(f"[网络] {topic}:{bed_name} {alarm_msg}")
# 更新报警状态
self.alarm_beds.add(bed_name)
self.last_alarm_time = time.ticks_ms()
# 触发声音报警
self._trigger_buzzer()
except:
print("无效报警消息:", msg)
_display_all_beds方法:调用 _draw_multiple_beds 方法显示所有床位状态显示框。
def _display_all_beds(self):
"""显示所有床位"""
self._draw_multiple_beds(self.cfg.BED_COLUMNS, self.cfg.BED_ROWS, self.cfg.RECT_WIDTH, self.cfg.RECT_HEIGHT)
测试与调试

实验阶段 | 实验项目 | 实验内容 | 预期结果 | 实际结果 | 是否通过 | 问题与解决方案 |
---|---|---|---|---|---|---|
硬件搭建 | 传感器连接 | 将红外传感器连接到行空板 K10 的指定引脚(P0) | 传感器能正常连接,无松动、短路等情况 | 若连接异常,检查引脚是否对应、线路是否损坏 | ||
蜂鸣器连接 | 将有源蜂鸣器连接到行空板 K10 的指定引脚(P1) | 蜂鸣器能正常连接,通电后可发出声音 | 若无声,检查电源、引脚连接和蜂鸣器是否损坏 | |||
网络连接 | WiFi 连接 | 尝试连接指定的 WiFi 网络(WIFI_SSID) | 在规定重试次数(WIFI_MAX_RETRIES)内成功连接 | 若失败,检查密码、路由器状态等 | ||
MQTT 连接 | 连接到指定的 MQTT 服务器(MQTT_SERVER) | 在规定重试次数(MQTT_MAX_RETRIES)内成功连接 | 若失败,检查服务器地址、端口、用户名和密码 | |||
功能测试 | 滴速监测 | 模拟输液滴液,观察系统计算的滴速 | 滴速计算准确,在合理误差范围内 | 若误差大,检查传感器灵敏度、计算逻辑 | ||
液量计算 | 设置不同的输液总量和滴系数,观察剩余液量计算 | 剩余液量计算准确,与实际相符 | 若不符,检查滴系数设置、滴数统计 | |||
低液量报警 | 将模拟剩余液量降低到报警阈值以下 | 系统触发声光报警,MQTT 发送报警消息 | 若未报警,检查报警阈值设置、蜂鸣器和 MQTT 配置 | |||
数据上报 | 观察系统是否将输液数据(开始输液时间、结束输液时间等)通过 MQTT 上报 | 数据准确上报到指定的 MQTT 主题 | 若未上报,检查 MQTT 主题设置、网络连接 |

实验阶段 | 实验项目 | 实验内容 | 预期结果 | 实际结果 | 是否通过 | 问题与解决方案 |
---|---|---|---|---|---|---|
硬件搭建 | 蜂鸣器连接 | 将有源蜂鸣器连接到行空板 K10 的指定引脚(SPEAKER_PIN) | 蜂鸣器能正常连接,通电后可发出声音 | 若无声,检查电源、引脚连接和蜂鸣器是否损坏 | ||
网络连接 | WiFi 连接 | 尝试连接指定的 WiFi 网络(WIFI_SSID) | 在规定重试次数(WIFI_MAX_RETRIES)内成功连接 | 若失败,检查密码、路由器状态等 | ||
MQTT 连接 | 连接到指定的 MQTT 服务器(MQTT_SERVER) | 在规定重试次数(MQTT_MAX_RETRIES)内成功连接 | 若失败,检查服务器地址、端口、用户名和密码 | |||
功能测试 | 多床位状态监控 | 模拟多个病床的输液开始、报警和结束消息 | 护士站系统能准确接收并显示各床位状态 | 若接收异常,检查 MQTT 主题订阅、消息格式 | ||
报警提示 | 模拟某床位低液量报警消息 | 护士站系统触发声光报警,在对应位置显示报警信息 | 若未报警,检查报警阈值设置、蜂鸣器和显示逻辑 | |||
声光警示 | 观察报警时蜂鸣器发声和屏幕闪烁情况 | 蜂鸣器按设定频率和时长发声,屏幕报警文字闪烁 | 若异常,检查蜂鸣器参数设置、显示逻辑 | |||
过期报警清除 | 设置报警消息后,等待超过设定时间(如 5 秒) | 系统自动清除过期报警信息 | 若未清除,检查时间判断逻辑 |
3.输液实时监控

九、成果展示
十、附件
1.附件1:固件
K10-micropython-educore-V0.1-250208.bin
2.附件2:代码文件
(1)病床端主程序:bedside_infusion_monitor.py
(2)护士站端主程序:nursestation_central_monitor.py
2.附件3:教学资源
《医疗设施新功能 ——基于行空板K10的病床输液信息系统》教案
《信息科技教学指南硬件编程代码说明(202408)》
附件
附件
附件
评论