24浏览
查看: 24|回复: 0

[M10项目] 行空板M10——心率血氧值AI检测仪

[复制链接]
本帖最后由 云天 于 2025-8-22 11:15 编辑

基于行空板M10与MAX30102的智能健康监测项目

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

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

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

(二)扩展板组合
为了满足项目的多样化需求,我们为行空板M10配备了电机IO扩展板、金手指扩展板和800mAh电池扩展板。电机IO扩展板提供了双路直流电机驱动、红外收发和RGB灯效交互功能,虽然在本项目中主要利用其I/O扩展能力,但它也为未来功能的拓展提供了可能。金手指扩展板进一步扩展了行空板M10的I/O接口,使得更多的传感器和执行器能够接入系统。800mAh电池扩展板则为设备提供了稳定的移动供电,确保设备在没有外部电源的情况下也能长时间运行。这种扩展板组合设计,不仅提升了设备的功能性,还增强了其便携性和适应性。

(三)传感器:MAX30102心率血氧传感器
MAX30102心率血氧传感器是本项目的核心部件之一。它采用PPG光电容积脉搏波描记法,能够精准地测量心率和血氧饱和度。该传感器内置了集成算法的微控制器,可以直接输出心率血氧数值,大大降低了主控板的计算负担。其I2C和UART接口设计,使得与行空板M10的连接和通信变得简单快捷。此外,MAX30102的工作电流低,能够在保证测量精度的同时,延长设备的续航时间。
行空板M10——心率血氧值AI检测仪图1

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

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


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

【完整代码】

  1. #  -*- coding: UTF-8 -*-
  2. # MindPlus
  3. # Python
  4. import sys
  5. import time
  6. from unihiker import GUI
  7. import openai
  8. import json
  9. from pinpong.board import Board
  10. from pinpong.libs.dfrobot_max30102 import DFRobot_BloodOxygen_S
  11. import xlwt
  12. import math
  13. from pathlib import Path
  14. sys.path.append("/root/mindplus/.lib/thirdExtension/mengchangfeng-kimi-thirdex")
  15. Board().begin()
  16. u_gui=GUI()
  17. p_max30102 = DFRobot_BloodOxygen_S()
  18. while (False == p_max30102.begin()):
  19.     print("init fail!")
  20.     time.sleep(1)
  21. 标题=u_gui.draw_text(text="心率血氧测量仪",x=20,y=5,font_size=20, color="#FF0000")
  22. 心率=u_gui.draw_text(text="",x=10,y=55,font_size=20, color="#0000FF")
  23. 血氧=u_gui.draw_text(text="",x=10,y=85,font_size=20, color="#0000FF")
  24. 分析=u_gui.draw_text(text="",x=2,y=120,font_size=14, color="#00FF00")
  25. XinLv = -1
  26. XueYang = -1
  27. client = openai.OpenAI(api_key="sk-IEnRsel06IHN26r4biNUBJYtRVUS1dQyi2WbuFjmg6lwboJ0", base_url="https://api.moonshot.cn/v1")
  28. messages = [
  29.     {"role": "system", "content": "你是 Kimi,由 Moonshot AI 提供的人工智能助手,你更擅长中文对话。你的回答形成一句话,字数控制在80个字以内。"},
  30. ]
  31. def chat(input: str) -> str:
  32.     """
  33.     chat 函数支持多轮对话,每次调用 chat 函数与 Kimi 大模型对话时,Kimi 大模型都会”看到“此前已经
  34.     产生的历史对话消息,换句话说,Kimi 大模型拥有了记忆。
  35.     """
  36.    
  37.     global messages
  38.    
  39.     # 我们将用户最新的问题构造成一个 message(role=user),并添加到 messages 的尾部
  40.     messages.append({
  41.         "role": "user",
  42.         "content": input,   
  43.     })
  44.    
  45.     # 携带 messages 与 Kimi 大模型对话
  46.     completion = client.chat.completions.create(
  47.         model="kimi-k2-0711-preview",
  48.         messages=messages,
  49.         temperature=0.6,
  50.     )
  51.    
  52.     # 通过 API 我们获得了 Kimi 大模型给予我们的回复消息(role=assistant)
  53.     assistant_message = completion.choices[0].message
  54.    
  55.     # 为了让 Kimi 大模型拥有完整的记忆,我们必须将 Kimi 大模型返回给我们的消息也添加到 messages 中
  56.     messages.append(assistant_message)
  57.    
  58.     return assistant_message.content
  59. def wrap_text(text, line_length):
  60.     """
  61.     将文本按照指定的字符个数换行。
  62.     :param text: 要处理的文本
  63.     :param line_length: 每行的字符个数
  64.     :return: 换行后的文本
  65.     """
  66.     wrapped_text = ""
  67.     current_line_length = 0
  68.     for char in text:
  69.         if current_line_length >= line_length:
  70.             wrapped_text += "\n"
  71.             current_line_length = 0
  72.         wrapped_text += char
  73.         current_line_length += 1
  74.     return wrapped_text
  75. YunXingShiJian = time.time()
  76. BiaoShi = 0
  77. CeShiShiJian = time.time()
  78. XuHao = 0
  79. WenJianJiLuShiJian = time.time()
  80. WenJianJiLuBiaoShi = 0
  81. WenJianXuHao = 1
  82. while True:
  83.     if (WenJianJiLuBiaoShi == 0):
  84.         WenJianJiLuBiaoShi = 1
  85.         fp = xlwt.Workbook(encoding="ascii")
  86.         table = fp.add_sheet(sheetname="心率血氧值记录表", cell_overwrite_ok=True)
  87.         timeStyle = xlwt.easyxf(strg_to_parse="font: name Times New Roman, color-index red, bold on", num_format_str="dd/mm/yyyy")
  88.         xhStyle = xlwt.easyxf(strg_to_parse="font: name Times New Roman, color-index red, bold on", num_format_str="0")
  89.         numStyle = xlwt.easyxf(strg_to_parse="font: name Times New Roman, color-index red, bold on", num_format_str="0.00")
  90.         mindFont = xlwt.Font()
  91.         mindFont.name = "微软雅黑"
  92.         titleStyle = xlwt.XFStyle()
  93.         titleStyle.font = mindFont
  94.         table.write(0, 0, "序号", style=titleStyle)
  95.         table.write(0, 1, "心率值", style=titleStyle)
  96.         table.write(0, 2, "血氧值", style=titleStyle)
  97.         table.write(0, 3, "记录时间", style=titleStyle)
  98.     p_max30102.sensor_start_collect()
  99.     XinLv = p_max30102.get_heartbeat()
  100.     XueYang = p_max30102.get_spo2()
  101.     if (not (XinLv == -1)):
  102.         if (BiaoShi == 0):
  103.             YunXingShiJian = time.time()
  104.             BiaoShi = 1
  105.         心率.config(text=(str("心率:") + str(XinLv)))
  106.     if (not (XueYang == -1)):
  107.         if (BiaoShi == 0):
  108.             YunXingShiJian = time.time()
  109.             BiaoShi = 1
  110.         血氧.config(text=(str("血氧:") + str(XueYang)))
  111.     if (BiaoShi == 1):
  112.         if ((time.time() - YunXingShiJian) > 25):
  113.             if XinLv==-1 or  XueYang==-1:
  114.                 continue
  115.             YunXingShiJian = time.time()
  116.             original_text=chat(str("我现在的") + str("心率值是") + str(XinLv)+ str("、血氧值是") + str(XueYang) + str(",请为帮我分析一下。"))
  117.             print(original_text)
  118.             wrapped_text = wrap_text(original_text, 12)
  119.             分析.config(color="#000000")
  120.             分析.config(text=wrapped_text)
  121.     if ((not (XinLv == -1)) and (not (XueYang == -1))):
  122.         XuHao = (XuHao + 1)
  123.         table.write((int(XuHao)), 0, (int(XuHao)), style=xhStyle)
  124.         table.write((int(XuHao)), 1, XinLv, style=numStyle)
  125.         table.write((int(XuHao)), 2, XueYang, style=numStyle)
  126.         table.write((int(XuHao)), 3, time.strftime("%Y/%m/%d %H:%M:%S"), style=timeStyle)
  127.     else:
  128.         continue
  129.     if ((time.time() - WenJianJiLuShiJian) > 60):
  130.         YunXingShiJian = time.time()
  131.         WenJianJiLuShiJian = time.time()
  132.         WenJianJiLuBiaoShi = 0
  133.         fp.save((str("心率血氧值记录表") + str((str((int(WenJianXuHao))) + str(".xls")))))
  134.         file_path = Path("心率血氧值记录表1.xls")
  135.         file_object = client.files.create(file=file_path, purpose="file-extract")
  136.         file_content = client.files.content(file_id=file_object.id).text
  137.         messages=[{
  138.             "role": "system",
  139.             "content": file_content
  140.         }]
  141.         WenJianXuHao = (WenJianXuHao + 1)
  142.         original_text=chat("帮我分析一下,我的心率血氧值记录数据,并给出建议,字数控制在80字")
  143.         print(original_text)
  144.         wrapped_text = wrap_text(original_text, 12)
  145.         分析.config(color="#00FF00")
  146.         分析.config(text=wrapped_text)
  147.     time.sleep(1)
复制代码


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


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


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


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

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

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


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

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

【项目优化与拓展】
虽然心率血氧值AI检测仪已经具备了基本的功能,但在实际使用过程中,我们仍然发现了一些可以优化和拓展的地方。例如,为了提高设备的便携性,我们可以进一步优化硬件设计,减小设备的体积和重量。在软件方面,我们可以增加更多的健康监测功能,如血压监测、睡眠质量分析等,以满足用户更全面的健康管理需求。此外,我们还可以通过改进AI模型的算法,提高其分析的准确性和效率,为用户提供更优质的服务。
【视频演示】

【项目总结】
心率血氧值AI检测仪的开发,是创客精神与现代科技相结合的产物。它不仅解决了人们在日常生活中对心率血氧监测的需求,还通过AI技术为用户提供个性化的健康建议,为健康管理提供了一种全新的思路。在项目实施过程中,我们充分发挥了行空板M10及其扩展板组合的强大功能,以及MAX30102心率血氧传感器的高精度测量能力,实现了设备的稳定运行和高效数据处理。


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail