37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来---小小的进步或是搞不掂的问题,希望能够抛砖引玉。
MAX30102
是一种综合性脉搏血氧测定法,心率监测模块。它包括内部LED,光电探测器、光学元件和低噪声电子设备具有环境光抑制功能。max30102提供了完整的系统解决方案,简化流程设计适用于移动和可穿戴设备。MAX30102在单个1.8V电源上工作为内部LED提供单独的5.0V电源。通信通过标准I2c兼容接口。模块可以通过软件关闭零备用电流,允许电源轨始终保持通电。
应用
●可穿戴设备
●健身辅助设备
MAX30102的优点和特点
●心率监测器和脉搏血氧计传感器输入LED反射溶液
●微型5.6毫米x 3.3毫米x 1.55毫米14针光学模块
•集成的盖玻片提供最佳、坚固的
●移动设备超低功率运行
•可编程采样率和LED电流节电
•低功率心率监测器(<1兆瓦)
•超低停机电流(0.7μA,典型值)
●快速数据输出能力
•采样率高
●强大的运动伪影复原能力
•高信噪比
-40°C至+85°C工作温度范围
MAX30102手腕心率模块
有两个发光二极管,一个光检测器,优化光学和低噪声的仿真信号处理,以检测脉搏血氧饱和度和心脏速率信号。
1、只需要将手指头紧贴在传感器上,就能估计 脉搏血氧饱和度(SpO2)及脉搏(相当于心跳)。
2、携带氧气的红血球能吸收较多红外光(850-1000nm),未携带氧气的红血球则是吸收较多的红光(600-750nm)。
3、因此pulse oximeter就是一个迷你的分光计,利用不同红血球之吸收光谱的原理,来分析血氧饱和度。
4、这种实时而快速的测量方式,也广泛被运用在许多临床的参考。
MAX30102手腕心率模块电原理图
经过多方寻找,从一个研究MAX30102算法的程序中找到了一个经过亲自验证有效的实际血氧标定计算公式:
SpO2=-45.060*R*R+ 30.354 *R + 94.845
其中的R可以通过红光和红外光光强的对数值计算得到,这个标定表达式实际上是对血氧饱和度的二次曲线拟合,是经过测量得到的。最后终于可以输出血氧饱和度数据了。
MAX30102手腕心率模块主要应用
辅助健身设备
智能电话
平板电脑
可穿戴设备
MAX30102的发光部分包括两个LED,一个是红光LED(660nm),另一个是红外光LED(880nm),这个是测量血氧饱和度SPO2最常见的配置。接收部分是一个对可见光和红外光都敏感的光电二极管,其接收的光强度信号转换为电流信号,经过环境光消除电路后,最后被自带的18位ADC进行采样转化,至此模拟部分完成。AD转化后的数字经过数字滤波后储存在数据寄存器中,最后可通过I2C总线被外接MCU读取。在硬件上,LED的电源和其他部分的电源不是同一个,因为LED为了保证足够的出射光强,需要瞬间大电流(最大50ma),这就要求LED的正向电压足够大(要求3.1V以上)。而其余的AD转换和I2C总线部分,为了实现低功耗要求电压足够小(要求1.8V),所以传感器需要两路独立的电源。此外,由于LED电源会产生瞬间大电流,所以电源引脚附近要加一个大电容减轻对电源电压的影响。
传统的脉搏测量方法主要有三种:一是从心电信号中提取;二是从测量血压时压力传感器测到的波动来计算脉率;三是光电容积法。前两种方法提取信号都会限制病人的活动,如果长时间使用会增加病人生理和心理上的不舒适感。而光电容积法脉搏测量作为监护测量中最普遍的方法之一,其具有方法简单、佩戴方便、可靠性高等特点。
光电容积法的基本原理是利用人体组织在血管搏动时造成透光率不同来进行脉搏和血氧饱和度测量的。其使用的传感器由光源和光电变换器两部分组成,通过绑带或夹子固定在病人的手指、手腕或耳垂上。光源一般采用对动脉血中氧合血红蛋白(HbO2)和去氧血红蛋白(Hb)有选择性的特定波长的发光二极管(一般选用660nm附近的红光和900nm附近的红外光)。当光束透过人体外周血管,由于动脉搏动充血容积变化导致这束光的透光率发生改变,此时由光电变换器接收经人体组织反射的光线,转变为电信号并将其放大和输出。由于脉搏是随心脏的搏动而周期性变化的信号,动脉血管容积也呈现周期性变化,因此光电变换器的电信号变化周期就是脉搏率。
MAX30102手腕心率模块实验接线示意图
实验开源代码
/* 【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程) 实验一百: MAX30102血氧仪手腕心率脉搏检测心跳传感器模块 1、安装库:IDE-工具-管理库-搜索“MAX30105”-安装 2、项目:串口读取测量数据 3、连线(I2C): VIN → 3.3V GND → GND SDA 接 A4 SCL 接 A5 */ #include <Wire.h> #include "MAX30105.h" #include "heartRate.h" MAX30105 particleSensor; const byte RATE_SIZE = 4; //Increase this for more averaging. 4 is good. byte rates[RATE_SIZE]; //Array of heart rates byte rateSpot = 0; long lastBeat = 0; //Time at which the last beat occurred float beatsPerMinute; int beatAvg; void setup(){ Serial.begin(115200); Serial.println("Initializing..."); // Initialize sensor if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed { Serial.println("MAX30105 was not found. Please check wiring/power. "); while (1); } Serial.println("Place your index finger on the sensor with steady pressure."); particleSensor.setup(); //Configure sensor with default settings particleSensor.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running particleSensor.setPulseAmplitudeGreen(0); //Turn off Green LED } void loop(){ long irValue = particleSensor.getIR(); if (checkForBeat(irValue) == true) { //We sensed a beat! long delta = millis() - lastBeat; lastBeat = millis(); beatsPerMinute = 60 / (delta / 1000.0); if (beatsPerMinute < 255 && beatsPerMinute > 20) { rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array rateSpot %= RATE_SIZE; //Wrap variable //Take average of readings beatAvg = 0; for (byte x = 0 ; x < RATE_SIZE ; x++) beatAvg += rates[x]; beatAvg /= RATE_SIZE; } } Serial.print("IR="); Serial.print(irValue); Serial.print(", BPM="); Serial.print(beatsPerMinute); Serial.print(", Avg BPM="); Serial.print(beatAvg); Serial.println(); delay(1000); }
Initializing...
Place your index finger on the sensor with steady pressure.
正在初始化…
将食指稳定地放在传感器上。
(初始化后的串口数据-未放上手指)
实验串口返回情况
模块电原理图之二