云天 发表于 2025-8-22 10:32:51

行空板M10——心率血氧值AI检测仪

本帖最后由 云天 于 2025-8-22 11:15 编辑

基于行空板M10与MAX30102的智能健康监测项目
在当今快节奏的生活中,人们对自身健康状况的关注度越来越高,尤其是心率和血氧这两个重要的生理指标。心率反映着心脏的跳动频率,而血氧饱和度则直接关系到身体组织的供氧情况。为了帮助人们更便捷地监测这些指标,并通过人工智能技术获得专业的健康分析,我们设计了一款名为“心率血氧值AI检测仪”的创客项目。该项目基于行空板M10及其扩展板组合,搭配MAX30102心率血氧传感器,实现了心率血氧的实时监测、数据记录以及AI智能分析,为个人健康管理提供了一个高效、智能的解决方案。

【项目背景与意义】
随着科技的飞速发展,人们对健康监测的需求不再局限于传统的医疗设备。便携式、智能化的健康监测工具逐渐成为人们日常生活中的重要组成部分。心率血氧值AI检测仪的开发,旨在满足人们随时随地监测自身健康状况的需求。通过将先进的传感器技术与人工智能相结合,该设备不仅能够实时获取心率和血氧数据,还能通过AI模型对这些数据进行深度分析,为用户提供个性化的健康建议。这对于预防心血管疾病、呼吸系统疾病等慢性疾病具有重要意义,同时也为健康管理提供了一种全新的模式。

【硬件选型与设计】
(一)主控板:行空板M10
行空板M10是一款功能强大的开源硬件平台,具备高性能的处理器和丰富的接口资源。它支持多种编程语言,包括Python,这使得开发过程更加灵活和高效。行空板M10的低功耗设计和良好的兼容性,使其成为理想的主控板选择。在本项目中,行空板M10负责协调各个硬件模块的工作,处理传感器数据,并与AI模型进行交互。

(二)扩展板组合
为了满足项目的多样化需求,我们为行空板M10配备了电机IO扩展板、金手指扩展板和800mAh电池扩展板。电机IO扩展板提供了双路直流电机驱动、红外收发和RGB灯效交互功能,虽然在本项目中主要利用其I/O扩展能力,但它也为未来功能的拓展提供了可能。金手指扩展板进一步扩展了行空板M10的I/O接口,使得更多的传感器和执行器能够接入系统。800mAh电池扩展板则为设备提供了稳定的移动供电,确保设备在没有外部电源的情况下也能长时间运行。这种扩展板组合设计,不仅提升了设备的功能性,还增强了其便携性和适应性。
https://ws.dfrobot.com.cn/lqDC6ZftFwSmGRmLlo5PmgjT6LW_
(三)传感器:MAX30102心率血氧传感器
MAX30102心率血氧传感器是本项目的核心部件之一。它采用PPG光电容积脉搏波描记法,能够精准地测量心率和血氧饱和度。该传感器内置了集成算法的微控制器,可以直接输出心率血氧数值,大大降低了主控板的计算负担。其I2C和UART接口设计,使得与行空板M10的连接和通信变得简单快捷。此外,MAX30102的工作电流低,能够在保证测量精度的同时,延长设备的续航时间。

【软件设计与实现】
(一)实时数据采集、显示、AI智能分析

[*]通过编写Python程序,我们实现了对MAX30102传感器的初始化和数据采集功能。程序会周期性地从传感器读取心率和血氧数据,并通过行空板M10的GUI界面实时显示出来。用户可以直观地看到自己的心率和血氧数值,及时了解自身的健康状况。
[*]为了实现AI智能分析功能,我们引入了Moonshot AI提供的Kimi大模型。通过OpenAI的API接口,我们将采集到的心率血氧数据发送给Kimi模型,并获取其分析结果。Kimi模型能够根据输入的数据,结合大量的医学知识和数据分析经验,为用户提供个性化的健康建议。例如,当心率过高时,模型会提醒用户注意休息;当血氧饱和度偏低时,模型会建议用户改善通风条件等。这种AI智能分析功能,使得设备不仅仅是一个数据采集工具,更是一个能够为用户提供专业指导的健康管理助手。

(二)数据记录与文件传输
为了方便用户对历史数据进行回顾和分析,我们将每次采集到的心率血氧数据记录到电子表格中。表格中包含了序号、心率值、血氧值和记录时间等信息,形成了多条连续的数据记录。每间隔一段时间(如1小时),程序会将电子表格保存为文件,并通过OpenAI的文件接口上传给Kimi模型。Kimi模型会对这些历史数据进行综合分析,为用户提供更全面的健康建议。这种数据记录和文件传输机制,不仅保证了数据的完整性,还为AI模型的深度分析提供了数据基础。



【完整代码】
#-*- coding: UTF-8 -*-

# MindPlus
# Python
import sys
import time
from unihiker import GUI
import openai
import json
from pinpong.board import Board
from pinpong.libs.dfrobot_max30102 import DFRobot_BloodOxygen_S
import xlwt
import math
from pathlib import Path
sys.path.append("/root/mindplus/.lib/thirdExtension/mengchangfeng-kimi-thirdex")

Board().begin()
u_gui=GUI()
p_max30102 = DFRobot_BloodOxygen_S()
while (False == p_max30102.begin()):
    print("init fail!")
    time.sleep(1)

标题=u_gui.draw_text(text="心率血氧测量仪",x=20,y=5,font_size=20, color="#FF0000")
心率=u_gui.draw_text(text="",x=10,y=55,font_size=20, color="#0000FF")
血氧=u_gui.draw_text(text="",x=10,y=85,font_size=20, color="#0000FF")
分析=u_gui.draw_text(text="",x=2,y=120,font_size=14, color="#00FF00")
XinLv = -1
XueYang = -1

client = openai.OpenAI(api_key="sk-IEnRsel06IHN26r4biNUBJYtRVUS1dQyi2WbuFjmg6lwboJ0", base_url="https://api.moonshot.cn/v1")
messages = [
    {"role": "system", "content": "你是 Kimi,由 Moonshot AI 提供的人工智能助手,你更擅长中文对话。你的回答形成一句话,字数控制在80个字以内。"},
]
def chat(input: str) -> str:
    """
    chat 函数支持多轮对话,每次调用 chat 函数与 Kimi 大模型对话时,Kimi 大模型都会”看到“此前已经
    产生的历史对话消息,换句话说,Kimi 大模型拥有了记忆。
    """
   
    global messages
   
    # 我们将用户最新的问题构造成一个 message(role=user),并添加到 messages 的尾部
    messages.append({
      "role": "user",
      "content": input,   
    })
   
    # 携带 messages 与 Kimi 大模型对话
    completion = client.chat.completions.create(
      model="kimi-k2-0711-preview",
      messages=messages,
      temperature=0.6,
    )
   
    # 通过 API 我们获得了 Kimi 大模型给予我们的回复消息(role=assistant)
    assistant_message = completion.choices.message
   
    # 为了让 Kimi 大模型拥有完整的记忆,我们必须将 Kimi 大模型返回给我们的消息也添加到 messages 中
    messages.append(assistant_message)
   
    return assistant_message.content
def wrap_text(text, line_length):
    """
    将文本按照指定的字符个数换行。

    :param text: 要处理的文本
    :param line_length: 每行的字符个数
    :return: 换行后的文本
    """
    wrapped_text = ""
    current_line_length = 0

    for char in text:
      if current_line_length >= line_length:
            wrapped_text += "\n"
            current_line_length = 0
      wrapped_text += char
      current_line_length += 1

    return wrapped_text
YunXingShiJian = time.time()
BiaoShi = 0
CeShiShiJian = time.time()
XuHao = 0
WenJianJiLuShiJian = time.time()
WenJianJiLuBiaoShi = 0
WenJianXuHao = 1
while True:
    if (WenJianJiLuBiaoShi == 0):
      WenJianJiLuBiaoShi = 1
      fp = xlwt.Workbook(encoding="ascii")
      table = fp.add_sheet(sheetname="心率血氧值记录表", cell_overwrite_ok=True)
      timeStyle = xlwt.easyxf(strg_to_parse="font: name Times New Roman, color-index red, bold on", num_format_str="dd/mm/yyyy")
      xhStyle = xlwt.easyxf(strg_to_parse="font: name Times New Roman, color-index red, bold on", num_format_str="0")
      numStyle = xlwt.easyxf(strg_to_parse="font: name Times New Roman, color-index red, bold on", num_format_str="0.00")
      mindFont = xlwt.Font()
      mindFont.name = "微软雅黑"
      titleStyle = xlwt.XFStyle()
      titleStyle.font = mindFont
      table.write(0, 0, "序号", style=titleStyle)
      table.write(0, 1, "心率值", style=titleStyle)
      table.write(0, 2, "血氧值", style=titleStyle)
      table.write(0, 3, "记录时间", style=titleStyle)
    p_max30102.sensor_start_collect()
    XinLv = p_max30102.get_heartbeat()
    XueYang = p_max30102.get_spo2()
    if (not (XinLv == -1)):
      if (BiaoShi == 0):
            YunXingShiJian = time.time()
            BiaoShi = 1
      心率.config(text=(str("心率:") + str(XinLv)))
    if (not (XueYang == -1)):
      if (BiaoShi == 0):
            YunXingShiJian = time.time()
            BiaoShi = 1
      血氧.config(text=(str("血氧:") + str(XueYang)))
    if (BiaoShi == 1):
      if ((time.time() - YunXingShiJian) > 25):
            if XinLv==-1 orXueYang==-1:
                continue
            YunXingShiJian = time.time()
            original_text=chat(str("我现在的") + str("心率值是") + str(XinLv)+ str("、血氧值是") + str(XueYang) + str(",请为帮我分析一下。"))
            print(original_text)
            wrapped_text = wrap_text(original_text, 12)
            分析.config(color="#000000")
            分析.config(text=wrapped_text)
    if ((not (XinLv == -1)) and (not (XueYang == -1))):
      XuHao = (XuHao + 1)
      table.write((int(XuHao)), 0, (int(XuHao)), style=xhStyle)
      table.write((int(XuHao)), 1, XinLv, style=numStyle)
      table.write((int(XuHao)), 2, XueYang, style=numStyle)
      table.write((int(XuHao)), 3, time.strftime("%Y/%m/%d %H:%M:%S"), style=timeStyle)
    else:
      continue
    if ((time.time() - WenJianJiLuShiJian) > 60):
      YunXingShiJian = time.time()
      WenJianJiLuShiJian = time.time()
      WenJianJiLuBiaoShi = 0
      fp.save((str("心率血氧值记录表") + str((str((int(WenJianXuHao))) + str(".xls")))))
      file_path = Path("心率血氧值记录表1.xls")
      file_object = client.files.create(file=file_path, purpose="file-extract")
      file_content = client.files.content(file_id=file_object.id).text
      messages=[{
            "role": "system",
            "content": file_content
      }]
      WenJianXuHao = (WenJianXuHao + 1)
      original_text=chat("帮我分析一下,我的心率血氧值记录数据,并给出建议,字数控制在80字")
      print(original_text)
      wrapped_text = wrap_text(original_text, 12)
      分析.config(color="#00FF00")
      分析.config(text=wrapped_text)
    time.sleep(1)


【项目实施与测试】

[*]在完成硬件搭建和软件编程后,我们对心率血氧值AI检测仪进行了简单的测试。后期测试过程中,我们将模拟了不同的使用场景,包括静息状态、运动状态和睡眠状态等,以验证设备在各种情况下的性能表现。
[*]测试结果显示,设备能够稳定地采集心率血氧数据,并准确地显示在GUI界面上。AI智能分析功能也表现出了较高的准确性和实用性,能够为用户提供有价值的健康建议。同时,数据记录和文件传输功能也运行正常,电子表格能够完整地保存数据,并成功上传给Kimi模型进行分析。







(单条心率血氧值数据,Kimi大模型分析)



(多条心率血氧值数据,Kimi大模型分析)
【项目优化与拓展】
虽然心率血氧值AI检测仪已经具备了基本的功能,但在实际使用过程中,我们仍然发现了一些可以优化和拓展的地方。例如,为了提高设备的便携性,我们可以进一步优化硬件设计,减小设备的体积和重量。在软件方面,我们可以增加更多的健康监测功能,如血压监测、睡眠质量分析等,以满足用户更全面的健康管理需求。此外,我们还可以通过改进AI模型的算法,提高其分析的准确性和效率,为用户提供更优质的服务。
【视频演示】
https://www.bilibili.com/video/BV193YfzRE73/?share_source=copy_web
【项目总结】
心率血氧值AI检测仪的开发,是创客精神与现代科技相结合的产物。它不仅解决了人们在日常生活中对心率血氧监测的需求,还通过AI技术为用户提供个性化的健康建议,为健康管理提供了一种全新的思路。在项目实施过程中,我们充分发挥了行空板M10及其扩展板组合的强大功能,以及MAX30102心率血氧传感器的高精度测量能力,实现了设备的稳定运行和高效数据处理。


easy猿 发表于 2025-8-27 09:04:48

云天老师出品。必数精品
页: [1]
查看完整版本: 行空板M10——心率血氧值AI检测仪