|
代码说明 这段代码使用了许多库,而且都很重要。这些库分别是MAX30100 脉搏血氧仪传感器库、用于I2C的Wire.h、用于ESP32中WiFi相关支持的WiFi.h、Adafruit MQTT和MQTT客户端库。
首先在代码开头包含上面提到的那些库的头文件。 - #include <stdint.h>
- #include <Wire.h>
- #include <WiFi.h>
- #include "Adafruit_MQTT.h"
- #include "Adafruit_MQTT_Client.h"
- #include "MAX30100_PulseOximeter.h" //used arduino builtin MAX30100 lib (https://github.com/oxullo/Arduino-MAX30100)
复制代码接下来定义无线名称WLAN SSID和密码WLAN_PASS 。ESP32使用这些定义来连接WiFi网络。 - #define WLAN_SSID "xxxxxxxxx"
- #define 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端口,如原理图所示. - #define I2C_SDA 21
- #define I2C_SCL 22
复制代码接下来,定义三个变量用于存储上次报告以及bpm和spo2值。 - uint32_t tsLastReport = 0;
- float bpm_dt=0;
- float spo2_dt = 0;
复制代码
MQTT使用发布-订阅模型。在此工作模型中,向Adafruit服务器提交数据的设备保持发布模式,其中Adafruit IO服务器订阅相同的数据点。每当设备发布任何新数据时,服务器接收数据并执行必要的动作。
当服务器发布数据并且设备订阅它时,也会发生同样的事情。在我们的应用中,设备将SPO2和BPM的数据发送到服务器,因此它发布该数据并从服务器接收ON-OFF状态,从而需要订阅该状态。下面代码中配置了MQTT。 - WiFiClient client;
- 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");
- // Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
- Adafruit_MQTT_Publish bpm_pub = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/bpm");
- Adafruit_MQTT_Publish spo2_pub = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/SpO2");
复制代码
在setup()函数中,我们启动I2C,使用预定义的SSID和密码连接WiFi,启动MQTT,订阅开关状态。 - void setup()
- {
- Serial.begin(115200);
- Wire.begin(I2C_SDA, I2C_SCL);
- WiFi.begin(WLAN_SSID, WLAN_PASS);
- while (WiFi.status() != WL_CONNECTED) {
- delay(500);
- Serial.print(".");
- }
- Serial.println();
- Serial.println("WiFi connected");
- Serial.println("IP address: "); Serial.println(WiFi.localIP());
- mqtt.subscribe(&sw_sub);
- Serial.print("Initializing pulse oximeter..");
- // Initialize the PulseOximeter instance
- // Failures are generally due to an improper I2C wiring, missing power supply
- // or wrong target chip
- if (!pox.begin()) {
- Serial.println("FAILED");
- for(;;);
- } else {
- Serial.println("SUCCESS");
- }
- // The default current for the IR LED is 50mA and it could be changed
- // by uncommenting the following line. Check MAX30100_Registers.h for all the
- // available options.
- pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
- // Register a callback for the beat detection
- pox.setOnBeatDetectedCallback(onBeatDetected);
- stopReadPOX();
- }
复制代码
在所有这些之后,max30100以LED电流设置启动。 MAX30100头文件中还提供了不同的电流设置,用于不同的配置。心跳检测回调函数也启动。 在所有这些设置之后,血氧计传感器开始工作。
在loop()函数中,启动MQTT连接,每5000毫秒检查一次订阅。如果开关打开,它开始读取血氧计传感器并发布心率和氧饱和度值的数据。 如果开关关闭,它将暂停与脉搏血氧仪传感器相关的所有任务。 - void loop() {
- MQTT_connect();
- Adafruit_MQTT_Subscribe *subscription;
- while ((subscription = mqtt.readSubscription(5000)))
- {
- if (subscription == &sw_sub)
- {
- Serial.print(F("Got: "));
- Serial.println((char *)sw_sub.lastread);
- if (!strcmp((char*) sw_sub.lastread, "ON"))
- {
- Serial.print(("Starting POX... "));
- startReadPOX();
- BaseType_t xReturned;
- if(poxReadTaskHld == NULL){
- xReturned = xTaskCreate(
- poxReadTask, /* Function that implements the task. */
- "pox_read", /* Text name for the task. */
- 1024*3, /* Stack size in words, not bytes. */
- NULL, /* Parameter passed into the task. */
- 2,/* Priority at which the task is created. */
- &poxReadTaskHld ); /* Used to pass out the created task's handle. */
- }
- delay(100);
- if(mqttPubTaskHld == NULL){
- xReturned = xTaskCreate(
- mqttPubTask, /* Function that implements the task. */
- "mqttPub", /* Text name for the task. */
- 1024*3, /* Stack size in words, not bytes. */
- NULL, /* Parameter passed into the task. */
- 2,/* Priority at which the task is created. */
- &mqttPubTaskHld ); /* Used to pass out the created task's handle. */
- }
- }
- else
- {
- Serial.print(("Stoping POX... "));
- // Detele POX read task
- if(poxReadTaskHld != NULL)
- vTaskDelete(poxReadTaskHld);
- poxReadTaskHld = NULL;
- }
- // Delete the MQTT Pub Task
- if(mqttPubTaskHld != NULL){
- vTaskDelete(mqttPubTaskHld);
- mqttPubTaskHld = NULL;
- }
- stopReadPOX();
- }
- }
- }
- }
复制代码
基于物联网的脉搏血氧仪演示 在面包板上正确连接电路,将代码上传到ESP32。 确保在代码中相应地更改Wi-Fi和Adafruit凭据。
与WiFi和Adafruit IO服务器连接后,它开始按预期工作。
如上图所示,氧饱和度值显示为96%,心跳显示为每分钟78到81次。 它还提供捕获数据的时间。当开关处于关闭状态时,数据为0。
希望你喜欢这篇文章并学到了一些有用的东西,如果你有任何问题,请随时在本贴下面进行回复。 |