Macos、ArduinoIDE2.0.4。


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
/* 使用MAX30105突破的光学SP02检测(SPK算法) 作者:Nathan Seidle@SparkFun Electronics 日期:2016年10月19日 https://github.com/sparkfun/MAX30105_Particle_Sensor_Breakout/tree/master/Libraries/Arduino/Examples/Example8_SPO2 /Users/用户/Documents/Arduino/libraries/SparkFun_MAX3010x_Pulse_and_Proximity_Sensor_Library/examples/Example8_SPO2/Example8_SPO2.ino 此演示显示心率和SPO2水平。最好用橡皮筋或其他方法将传感器固定在手指上。装置人类通常不善于对事物施加恒定的压力。当你将手指压在传感器上,其变化足以导致血液进入手指流动不同,导致传感器读数波动。 此示例基于Maxim的MAXREFDES117和RD117_LILYPAD.ino。他们的榜样修改为与SparkFun MAX30105库一起使用,并在Arduino 1.6.11下编译有关详细信息,请参阅许可证文件。 硬件连接 Max30102 - Arduino: VIN - 5V(或3.3V) GND - GND SDA - A4 SCL - A5 */ #include <Wire.h> #include "MAX30105.h" #include "spo2_algorithm.h" MAX30105 particleSensor; #define MAX_BRIGHTNESS 255 #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) // Arduino Uno没有足够的SRAM以32位格式存储100个IR led数据和红色led数据样本。为了解决此问题,将截断采样数据的16位MSB。样本变为16位数据。 uint16_t irBuffer[100]; //infrared LED sensor data 红外线的LED传感器数据 uint16_t redBuffer[100]; //red LED sensor data 红色LED传感器数据 #else uint32_t irBuffer[100]; //infrared LED sensor data 红外线LED传感器数据 uint32_t redBuffer[100]; //red LED sensor data 红色LED传感器数据 #endif int32_t bufferLength; // 数据长度 int32_t spo2; // SPO2-血氧饱和度值 int8_t validSPO2; // SPO2值是否有效。0-无效,1-有效 int32_t heartRate; // 心率值 int8_t validHeartRate; // 心率值是否有效。0-无效,1-有效 byte readLED = 13; // 接13脚。心率检测指示灯,每次读取数据时闪烁 void setup() { Serial.begin(115200); // 以每秒115200位的速度初始化串行通信: pinMode(readLED, OUTPUT); // Initialize sensor if (!particleSensor.begin(Wire, I2C_SPEED_FAST)){ // 使用默认I2C端口,400kHz速度 Serial.println(F("未找到MAX30105设备")); while (1); } Serial.println(F("用橡皮筋将传感器连接到手指上,保持稳定亲密静止接触")); byte ledBrightness = 60; // 可选: 0=Off to 255=50mA byte sampleAverage = 4; // 可选: 1, 2, 4, 8, 16, 32 byte ledMode = 2; // 可选: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green byte sampleRate = 100; // 可选: 50, 100, 200, 400, 800, 1000, 1600, 3200 int pulseWidth = 411; // 可选: 69, 118, 215, 411 int adcRange = 4096; // 可选: 2048, 4096, 8192, 16384 particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange); //Configure sensor with these settings particleSensor.setPulseAmplitudeRed(0x0A); // 将红色LED拉低,表示传感器正在运行 } void loop() { Serial.println(F("------累计100个样本------")); bufferLength = 100; // 取前100个样本确定信号范围。每个样本存储以 每秒采样25次 的数据 for (byte i = 0; i < bufferLength; i++) { while (particleSensor.available() == false) { // 检测新数据 particleSensor.check(); // 检查传感器是否有新数据 } redBuffer[i] = particleSensor.getRed(); // 监测红色数据 irBuffer[i] = particleSensor.getIR(); // 监测红外线数据 particleSensor.nextSample(); // 我们已经完成了当前样本,所以转到下一个样本 // Serial.print(F("red=")); // Serial.print(redBuffer[i], DEC); // Serial.print(F(", ir=")); // Serial.println(irBuffer[i], DEC); } // 计算前100个样本(每个样本的前4秒)后的心率和血氧量 // 通过检测PPG周期的峰值和红色/红外信号的相应AC/DC,计算SPO2的an_ratio。该算法针对手臂M0/M3。由于寄存器溢出,SPO2的公式没有达到精度。 // 因此,准确的SPO2是预先计算的,并为每个an_ratio保存longo-uch_SPO2_table[]。 maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate); // /Users/用户名/Documents/Arduino/libraries/SparkFun_MAX3010x_Pulse_and_Proximity_Sensor_Library/src/spo2_algorithm.cpp Serial.println(F("------样本计算完毕------")); // 从MAX30102连续取样。每1秒计算一次心率和血氧 while (1) { // 将前25组样本转储到存储器中,并将最后75组样本移到顶部 for (byte i = 25; i < 100; i++) { redBuffer[i - 25] = redBuffer[i]; irBuffer[i - 25] = irBuffer[i]; } // 在计算心率之前,采集25组样本。 for (byte i = 75; i < 100; i++) { while (particleSensor.available() == false){ // 检测新数据 particleSensor.check(); // 检查传感器是否有新数据 } digitalWrite(readLED, !digitalRead(readLED)); // 每次读取数据时,闪一下LED redBuffer[i] = particleSensor.getRed(); irBuffer[i] = particleSensor.getIR(); particleSensor.nextSample(); // 我们已经完成了当前样本,所以转到下一个样本 // 通过UART向终端程序发送样本和计算结果 Serial.print(F("red=")); Serial.print(redBuffer[i], DEC); Serial.print(F(", ir=")); Serial.print(irBuffer[i], DEC); Serial.print(F("。心率=")); Serial.print(heartRate, DEC); Serial.print(F(",是否有效=")); Serial.print(validHeartRate, DEC); Serial.print(F("。血氧含量=")); Serial.print(spo2, DEC); Serial.print(F(",是否有效=")); Serial.println(validSPO2, DEC); } // 收集25个新样本后,重新计算心率和血氧 maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate); } } |
测试效果并不理想,可能是操作流程不严格。库的代码内部原理没有做研究。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
用橡皮筋将传感器连接到手指上,保持稳定亲密静止接触 ------累计100个样本------ ------样本计算完毕------ red=654, ir=5049。心率=-999,是否有效=0。血氧含量=-999,是否有效=0 red=652, ir=5047。心率=-999,是否有效=0。血氧含量=-999,是否有效=0 red=657, ir=5050。心率=-999,是否有效=0。血氧含量=-999,是否有效=0 red=655, ir=5041。心率=-999,是否有效=0。血氧含量=-999,是否有效=0 red=657, ir=5052。心率=-999,是否有效=0。血氧含量=-999,是否有效=0 red=27963, ir=64529。心率=53,是否有效=1。血氧含量=-999,是否有效=0 red=27683, ir=64434。心率=53,是否有效=1。血氧含量=-999,是否有效=0 red=26866, ir=58378。心率=53,是否有效=1。血氧含量=-999,是否有效=0 red=3201, ir=8752。心率=53,是否有效=1。血氧含量=-999,是否有效=0 red=526, ir=4840。心率=53,是否有效=1。血氧含量=-999,是否有效=0 red=799, ir=30616。心率=53,是否有效=1。血氧含量=-999,是否有效=0 red=21947, ir=45416。心率=53,是否有效=1。血氧含量=-999,是否有效=0 red=22689, ir=47406。心率=53,是否有效=1。血氧含量=-999,是否有效=0 red=24176, ir=53349。心率=53,是否有效=1。血氧含量=-999,是否有效=0 red=25629, ir=57329。心率=53,是否有效=1。血氧含量=-999,是否有效=0 red=26415, ir=58626。心率=65,是否有效=1。血氧含量=96,是否有效=1 red=26417, ir=58635。心率=65,是否有效=1。血氧含量=96,是否有效=1 red=26423, ir=58572。心率=65,是否有效=1。血氧含量=96,是否有效=1 red=26267, ir=62533。心率=65,是否有效=1。血氧含量=96,是否有效=1 red=9552, ir=6038。心率=71,是否有效=1。血氧含量=100,是否有效=1 red=300, ir=2332。心率=71,是否有效=1。血氧含量=100,是否有效=1 red=271, ir=2158。心率=71,是否有效=1。血氧含量=100,是否有效=1 red=264, ir=2214。心率=71,是否有效=1。血氧含量=100,是否有效=1 |
- end
声明
本文由崔维友 威格灵 cuiweiyou vigiles cuiweiyou 原创,转载请注明出处:http://www.gaohaiyan.com/4159.html
承接App定制、企业web站点、办公系统软件 设计开发,外包项目,毕设