脉搏血氧饱和度是一种广泛使用的医学测量仪器,它是一种无创且无痛的测试,可以测量我们血液中的氧饱和度水平,从而可以轻松检测出氧气的微小变化。在当前的Covid-19情况下,在不与患者接触的情况下远程同时跟踪多个患者的氧气含量变得非常重要。
因此,在本项目中,我们使用MAX30100脉搏血氧仪和ESP32构建了脉搏血氧仪,该血氧仪将跟踪血氧水平并通过连接到Wi-Fi网络通过互联网发送数据。这样,我们可以通过与患者保持社交距离来远程监视多个患者。所获得的数据将显示为图形,从而更易于跟踪和分析患者的状况。以前,我们还使用脉冲传感器构建了其他心率监测器。如果您对与Covid-19相关的其他项目感兴趣,则可以查看我们之前制造的人体温度计,用于发烧监控的智能红外温度计以及壁挂式温度扫描仪。
除了Covid-19应用之外,该项目还可以广泛用于慢性阻塞性肺疾病(COPD),哮喘,肺炎,肺癌,贫血,心脏病或心力衰竭,或先天性心脏病。
请注意,该项目中使用的传感器没有医学等级,并且该项目未经过防故障应用测试。始终使用医学额定的脉搏血氧仪确定患者的脉搏和氧气水平,并与执业医师讨论。这里讨论的项目仅用于教育目的。
MAX30100传感器
MAX30100传感器集成了脉搏血氧饱和度和心率监测器模块。它与I2C数据线通信,并将SpO2和Pulse信息提供给主机微控制器单元。它使用光电探测器,光学元件,其中红色,绿色IR LED调制LED脉冲。LED电流可配置为0至50mA。下图显示了MAX30100传感器。
上述传感器模块可在1.8V至5.5V的范围内工作。I2C引脚的上拉电阻包含在模块中。
所需组件
- WiFi连接
- ESP32
- MAX30100传感器
- Adafruit IO用户ID和自定义创建的信息中心(将做得更进一步)
- 5V足够的电源单元,额定电流至少为1A
- USB电缆Micro USB转USBA
- 带有Arduino IDE和ESP32编程环境的PC。
MAX30100血氧仪与ESP32的接口
下面给出了带有ESP32的MAX30100的完整电路图。
这是一个非常简单的示意图。ESP32 devkit C的引脚21和22通过SDA和SCL引脚与脉搏血氧仪传感器MAX30100连接。血氧仪还由ESP32开发板上的5V引脚供电。我使用面包板和连接线进行连接,测试设置如下所示:
带有ESP32的Adafruit IO用于心率监测
我们之前已经针对不同的物联网应用构建了许多Adafruit IO项目。Adafruit IO是一个出色的平台,可以在其中创建自定义仪表板。要为基于IoT的脉搏血氧饱和度传感器创建自定义仪表板,请使用以下步骤-
步骤1:输入拳头名称,姓氏,电子邮件地址,用户名和密码后,首先在adafruit IO中注册。
第2步:登录过程完成后,空白的仪表板窗口将打开。在此部分中,我们将需要创建一个仪表板以各种方式显示数据。因此,是时候创建新的仪表板并提供仪表板的名称和说明了。
步骤3:填写上述表格后,是时候为传感器创建图形和控制部分了。
选择开关块。需要打开或关闭脉搏血氧饱和度传感器。
步骤4:写下块名称。如上图所示,切换功能将提供两种状态:ON和OFF。在同一过程中,选择图形块。
该图形部分需要选择两次,因为将显示两个图形,Heart bit和SpO2。这两个部分均已创建。如我们所见,我们选择了所有输入和输出功能。
第5步:下一步也是最后一步,就是获取adafruit密钥。如我们所见,我们获得了adafruit键,需要在代码中添加它。
现在已配置Adafruit IO。现在该为该项目准备硬件并创建固件了。
代码说明
这段代码使用了许多库,所有库都很重要。该库是MAX30100脉搏血氧传感器库, Wire.h 为I2C, WiFi.h 在ESP32,在WiFi相关的支持 Adafruit的MQTT 和 MQTT客户机 库。完整程序可在此页面底部找到。
上面提到的那些库包含在代码的开头。
#包括
接下来的两个定义是WLAN SSID和WLAN密码。这必须是准确的,ESP32会使用它来连接WiFi网络。
#定义WLAN_SSID“ xxxxxxxxx”#定义WLAN_PASS“ 2581xxxxx2”
接下来,我们定义Adafruit io定义。
#define AIO_UPDATE_RATE_SEC 5 #define AIO_SERVER“ io.adafruit.com” #define AIO_SERVERPORT 1883 #define AIO_USERNAME“ xxxxxxxxxxxxx” #define AIO_KEY“ abcdefgh”
更新速率将每5秒更新一次数据,服务器将是 io.adafruit.com ,服务器端口为1883。用户名和密码将是从adafruit IO仪表板生成的用户名和密码。一切都会有所不同,需要按照adafruit设置部分中的说明进行生成。
如下图所示,定义I2C端口。
#定义I2C_SDA 21#定义I2C_SCL 22
接下来,使用三个变量来存储上一个报告以及bpm和spo2值。
uint32_t tsLastReport = 0; 浮动bpm_dt = 0; 浮点spo2_dt = 0;
MQTT与pub-sub模型(发布和订阅)一起使用。在此工作模型中,将数据提交到Adafruit服务器的设备保持在发布模式,其中Adafruit IO服务器预订相同的数据点。这样,每当设备发布任何新数据时,服务器(订阅该服务器)就会接收数据并采取必要的措施。
当服务器发布数据,而设备订阅该数据时,也会发生同样的事情。在我们的应用程序中,设备将SPO2和BPM的数据发送到服务器,因此它发布了数据,并从服务器接收了ON-OFF状态,因此订阅了该数据。在下面描述的代码段中配置了该对象-
WiFiClient客户端;Adafruit_MQTT_Client mqtt(&client,AIO_SERVER,AIO_SERVERPORT,AIO_USERNAME,AIO_KEY); Adafruit_MQTT_Subscribe sw_sub = Adafruit_MQTT_Subscribe(&mqtt,AIO_USERNAME“ / feeds / switch”); //注意AIO的MQTT路径遵循以下格式:
在 设置 功能中,我们将启动I2C,将WiFi与预定义的SSID和密码连接,并为开关状态(在Adafruit IO仪表板上创建的开关按钮)启动MQTT订阅过程。
void setup(){Serial.begin(115200); Wire.begin(I2C_SDA,I2C_SCL); WiFi.begin(WLAN_SSID,WLAN_PASS);而(WiFi.status()!= WL_CONNECTED){delay(500); Serial.print(“。”); } Serial.println(); Serial.println(“ WiFi已连接”); Serial.println(“ IP地址:”); Serial.println(WiFi.localIP()); mqtt.subscribe(&sw_sub); Serial.print(“初始化脉搏血氧仪..”); //初始化PulseOximeter实例//失败通常是由于I2C接线不正确,电源丢失或//如果目标(!pox.begin()){Serial.println(“ FAILED”);对于(;;); } else {Serial.println(“ SUCCESS”); } // IR LED的默认电流为50mA,可以通过取消注释下面的行来更改它。检查MAX30100_Registers.h中所有可用的选项。痘setIRLedCurrent(MAX30100_LED_CURR_7_6MA); //为节拍检测pox注册一个回调。setOnBeatDetectedCallback(onBeatDetected); stopReadPOX(); }
完成所有这些操作后,max30100会以led电流设置启动。MAX30100的头文件中还提供不同的当前设置,用于不同的配置。心跳检测回叫功能也将启动。完成所有这些设置后,血氧饱和度传感器将停止。
在 循环 功能中,将启动MQTT连接,并每隔5000毫秒检查预订模型。在这种情况下,如果开关打开,它将开始读取血氧饱和度传感器并发布心跳和SPO2值的数据。如果关闭开关,它将中止与脉搏血氧仪传感器有关的所有任务。
无效循环(){MQTT_connect(); Adafruit_MQTT_Subscribe *订阅; while((subscription = mqtt.readSubscription(5000))){if(subscription ==&sw_sub){Serial.print(F(“ Got:”)); Serial.println((char *)sw_sub.lastread);如果(!strcmp((char *)sw_sub.lastread,“ ON”)){Serial.print((“ Starting POX…”)); startReadPOX(); BaseType_t xReturned; if(poxReadTaskHld == NULL){xReturned = xTaskCreate(poxReadTask,/ *实现任务的函数。* /“ pox_read”,/ *任务的文本名称。* / 1024 * 3,/ *以字为单位的堆栈大小,不是* / NULL,/ *传递给任务的参数* / 2,/ *创建任务的优先级* /&poxReadTaskHld); / *用于传递创建的任务的句柄。 * /} delay(100); if(mqttPubTaskHld == NULL){xReturned = xTaskCreate(mqttPubTask,/ *实现任务的函数。 * /“ mqttPub”,/ *任务的文本名称。 * / 1024 * 3,/ *堆栈大小以字为单位,而不是字节。 * / NULL,/ *传递给任务的参数。 * / 2,/ *创建任务的优先级。 * /&mqttPubTaskHld); / *用于传递创建的任务的句柄。 * /}} else {Serial.print((“ Stoping POX…”)); //删除POX读取任务if(poxReadTaskHld!= NULL)vTaskDelete(poxReadTaskHld); poxReadTaskHld = NULL; } //删除MQTT发布任务if(mqttPubTaskHld!= NULL){vTaskDelete(mqttPubTaskHld); mqttPubTaskHld = NULL; } stopReadPOX(); }}}}/ *用于传递创建的任务的句柄。 * /}} else {Serial.print((“ Stoping POX…”)); //删除POX读取任务if(poxReadTaskHld!= NULL)vTaskDelete(poxReadTaskHld); poxReadTaskHld = NULL; } //删除MQTT发布任务if(mqttPubTaskHld!= NULL){vTaskDelete(mqttPubTaskHld); mqttPubTaskHld = NULL; } stopReadPOX(); }}}}/ *用于传递创建的任务的句柄。 * /}} else {Serial.print((“ Stoping POX…”)); //删除POX读取任务if(poxReadTaskHld!= NULL)vTaskDelete(poxReadTaskHld); poxReadTaskHld = NULL; } //删除MQTT发布任务if(mqttPubTaskHld!= NULL){vTaskDelete(mqttPubTaskHld); mqttPubTaskHld = NULL; } stopReadPOX(); }}}}
基于物联网的脉搏血氧仪演示
电路正确连接在面包板上,下面给出的程序已上传到ESP32。确保您在代码中相应地更改了Wi-Fi和Adafruit凭据,以使其适合您。
与WiFi和Adafruit IO服务器连接后,它开始按预期工作。
我们可以看到SPO2级别显示96%,心跳显示每分钟78到81位。它还提供了捕获数据的时间。
如上图所示,开关已关闭且数据为0。该项目的完整工作视频也可在此页面底部找到。
希望您喜欢这篇文章并学到了一些有用的东西,如果您有任何疑问,请将其留在下面的评论部分或在我们的论坛上发布。