参考:【教程】教你玩转Stduino之手指心跳检测模块 - 知乎 (zhihu.com)
1 原理
心跳检测模块,由一个红外线发射LED和红外接收器构成。手指心跳监测模块能够测量脉搏,是这样工作的:当手指放在发射器与接收器之间,红外发射LED发射的光将穿过手指,到被接收器接收。而血压会随着脉搏变化,导致红外接收器接收到的光通量也会随之变化,因此可以通过红外光接收的情况来统计监测心跳。
红外心率测量是一种基于光学原理来检测人体心率的方法,其工作原理主要涉及光的发射、吸收、反射以及信号处理等过程,以下是具体介绍:
光学原理
1. **光源发射**
- 红外心率测量设备通常使用红外发光二极管(LED)作为光源。这种LED能够发射特定波长的红外光,一般在700 - 1000纳米左右。例如,常用的波长为940纳米的红外LED,其发射的光具有良好的穿透性,能够穿透皮肤表层到达皮下组织。
2. **光的吸收与反射**
- 当红外光照射到人体手指、耳垂或手腕等部位时,部分光会被组织吸收,部分光会被反射回来。人体的血液中含有大量的血红蛋白,血红蛋白对红外光有特定的吸收特性。血液中的血红蛋白和氧合血红蛋白对红外光的吸收量会随着血液的流动而发生变化。
- 在心脏收缩(心缩期)时,大量血液被泵入动脉,血管扩张,血液量增加,对红外光的吸收也会相应增加,反射光的强度就会减弱;而在心脏舒张(心舒期)时,血管收缩,血液量相对减少,对红外光的吸收减少,反射光的强度增强。这种反射光强度的变化与心脏的搏动密切相关。
信号检测与处理
1. **光电检测**
- 设备中有一个光电传感器(如光电二极管),它能够将反射回来的红外光信号转换为电信号。当反射光强度发生变化时,光电传感器输出的电信号的幅度也会随之变化。例如,当反射光强度减弱时,输出的电信号幅度减小;当反射光强度增强时,输出的电信号幅度增大。
2. **信号放大与滤波**
- 由于光电传感器输出的信号通常比较微弱,需要经过放大电路进行放大。同时,人体周围环境可能存在各种干扰信号,如电磁干扰、环境光干扰等。为了提取出准确的心率信号,还需要通过滤波电路去除这些干扰信号。滤波电路一般会设计为带通滤波器,只允许与心率频率范围(通常为0.5 - 5赫兹)相符的信号通过。
3. **信号处理与心率计算**
- 放大和滤波后的信号是一个随时间变化的周期性信号,其周期与心脏的搏动周期相对应。通过数字信号处理技术,如快速傅里叶变换(FFT)等方法,可以分析信号的频率成分,提取出心率信号的频率。心率的计算公式为心率(次/分钟)= 60 × 信号频率(赫兹)。例如,如果信号频率为1赫兹,那么心率就是60次/分钟。
红外心率测量技术具有非侵入性、操作方便、测量速度快等优点,广泛应用于医疗健康监测设备、智能穿戴设备(如智能手环、智能手表)等领域。然而,它也存在一些局限性,比如在手指等部位有污垢、指甲油等情况时,可能会影响红外光的反射和吸收,从而导致测量结果不准确。
2接线图
信号端接模拟量A0端口
电路修改说明: arduino板子的VIN--供电, GND, A0采集信号。但我感觉这个模块太简单了,就没有其他电路。怀疑不是心电检测。
下面这个怎么看也不是心率信号。
需要安装signal process 工具包,否则无法处理peak函数
% 确保安装了MATLAB Support Package for Arduino Hardware
% 如果未安装,请运行以下命令:
% matlab.addons.install('https://github.com/mathworks/arduinoio/archive/master.zip')
% 初始化Arduino连接
clear
a = arduino('COM6', 'Uno'); % 根据实际使用的端口修改COM3
% 配置引脚模式
configurePin(a, 'A0', 'AnalogInput'); % 设置A0为模拟输入
configurePin(a, 'D13', 'DigitalOutput'); % 设置D13为数字输出
% 初始化变量
sampleRate = 100; % 采样率100Hz
windowSize = 100; % 用于计算心率的窗口大小
data = zeros(windowSize, 1); % 初始化数据缓冲区
heartRate = 0; % 初始化心率
ledState = 0; % LED初始状态
% 主循环
for i = 1:1000 % 读取1000个数据点
% 读取A0端口的模拟值
pulseValue = readVoltage(a, 'A0');
% 将读取的值存储到数据缓冲区
data(i) = pulseValue;
% 如果数据缓冲区已满,计算心率
if i >= windowSize
% 提取窗口内的数据
signal = data(i - windowSize + 1:i);
% 检测信号中的峰值
[peaks, locs] = findpeaks(signal, 'MinPeakProminence', 10);
% 如果检测到多个峰值,计算心率
if length(peaks) > 1
avgPeakDistance = mean(diff(locs)); % 计算平均峰值间隔
heartRate = 60 / (avgPeakDistance / sampleRate); % 计算心率(单位:bpm)
fprintf('Heart Rate: %.2f BPM\n', heartRate);
end
end
% 控制D13端口的LED闪烁
if heartRate > 0
ledState = ~ledState; % 切换LED状态
writeDigitalPin(a, 'D13', ledState); % 写入LED状态
end
% 短暂延时以匹配采样率
pause(1 / sampleRate);
end
figure
plot(signal)
title('心率检测信号')
% 关闭Arduino连接
clear
采集数据data,1000点,不像 心率图