DIY 高精度血氧传感器制作指南:红外/红光、Arduino、LCD 与元件全解析
元件清单
| 元件 | 规格/备注 | 数量 |
|---|---|---|
| 红外发射管 | 波长 805–1000 nm,发射角 18° | 1 |
| 光电二极管 LPT80A | 宽光谱响应,需同时接收红光(600 nm)和红外(940 nm) | 1 |
| 5 mm 红色 LED | 波长约 600 nm | 1 |
| 电阻 10 kΩ | – | 1 |
| 电阻 330 Ω | – | 2 |
| DFRobot I2C 16×2 LCD 模块 | 或其他兼容 LCD,用于显示数值 | 1 |
| Arduino UNO | – | 1 |
| 杜邦线 | – | 1 套 |
| 高亮白光 LED | 可选,用于改进版消除环境光干扰 | 1 |
所需工具
- 烙铁(鸥翼头)
软件与在线服务
- Arduino IDE
项目原理与制作过程
血氧饱和度与 COVID-19
疫情期间,血氧饱和度(SpO₂)成为重要健康指标。正常人 SpO₂ ≥ 95%,若低于 90% 并伴有咳嗽、发热,需就医。指夹式血氧仪利用红光(~660 nm)与红外光(~940 nm)对含氧血红蛋白和脱氧血红蛋白吸收差异,无创测量 SpO₂。若制造者能自制血氧仪,可辅助早期筛查,减少恐慌性就医。
先理解心率传感器原理
项目起步于常见的 KY-039 心率模块:一颗红外 LED 照射光电二极管,配两个电阻限流与采样。手指置于两者间,血液搏动导致透光率周期性变化,光电二极管输出电流随之变化,经放大后即可得到脉搏波形。若无 KY-039,可自行搭建:仅需红外 LED、光电二极管、三个电阻。
通过计数波峰获取心率
信号含噪声且幅度小,需滑动平均滤波(窗口 4 个样本)并消除 50 Hz 电源干扰。采用“连续 N 个样本上升”判定波峰(代码中 rise_threshold = 3),统计单位时间内波峰数即得 BPM。关键在于选取合适的阈值,避免将双峰波的切迹误判为心跳。
构建血氧仪:改造 KY-039 增加红光通道
血液对红光(~600 nm)和红外光(~950 nm)吸收随含氧量不同。在 KY-039 基础上断开红外 LED 与 VCC,分别用 330 Ω 电阻接两个 Arduino 引脚,新增一颗 600 nm 红光 LED。交替点亮两 LED,同一光电二极管分时采样,得到红光与红外两路信号。原理图见文中图示。
SpO₂ 计算公式与校准
根据米兰理工大学文献,定义比值 R:
R = ((REDmax - REDmin) / REDmin) / ((IRmax - IRmin) / IRmin)
每个心跳周期内,采样率 40 ms(红/红外各 20 ms),周期长度 L = 周期/40 个样本。在最近 L 个样本中求两路信号的最大最小值,算出 R。R 与 SpO₂ 的关系近似线性:SpO₂ = K × R + M。需用市售血氧仪作参考,记录两组(正常呼吸、屏气)的 SpO₂ 与 R 值,解二元一次方程得 K、M。作者实测校准公式为 SpO₂ = -19 × R + 112。显示前要求最近 5 个周期稳定(±10%),以提高可靠性。
改进:消除环境光干扰
低成本元件极易受环境光影响。作者加装一颗常亮白光 LED,并用黑布遮挡传感器,提供恒定背景光。改进后读数稳定,不再随环境光变化,但需重新校准。
核心代码(oximeter-diy-ver-0.92.ino)
/* DIY 血氧仪 v0.92
* 基于 KY-039 改造或自制红外/红光+光电二极管传感器
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define MAX_PERIOD_SIZ 80
#define MEASURES 10
#define SAMP_SIZ 4
#define RISE_THRESHOLD 3
LiquidCrystal_I2C lcd(0x3F, 16, 2);
int T = 20; // 单通道采样时隙(ms)
int sensorPin = A1;
int REDLed = 3;
int IRLed = 4;
// 自定义字符:心形、问号等
byte sym[3][8] = { ... };
void setup() {
Serial.begin(9600);
pinMode(sensorPin, INPUT);
pinMode(REDLed, OUTPUT);
pinMode(IRLed, OUTPUT);
lcd.init(); lcd.backlight();
digitalWrite(REDLed, LOW); digitalWrite(IRLed, LOW);
for(int i=0;i<8;i++) lcd.createChar(i, sym[i]);
}
void loop() {
// 交替点亮 IR/RED,各采样 20 ms 并滑动平均
// 存入环形缓冲,周期满时计算 R
// 滑动平均检测 IR 波峰,计算 BPM
// 稳定后用校准公式换算 SpO₂,LCD 显示
// 串口输出原始波形供绘图调试
}
完整代码请见项目附件,已包含详细注释。
原理图
基于 KY-039 改造或全新搭建的电路原理图(Fritzing 文件 oximeter-diy_oW9ZI5zQtJ.fzz)。

关键提示
- 手指放置要稳,指甲贴紧 LED,测量期间勿移动、勿遮挡环境光。
- 采样时隙 20 ms 可有效抑制 50 Hz 交流干扰。
- 校准需市售血氧仪配合,两点法求线性系数。
- 改进版加装白光 LED + 遮光罩,显著提升稳定性。
- 本项目仅供教学/实验参考,非医疗器械,不可用于临床诊断。
制造工艺
- 树莓派 DIY 红外运动传感器:从原理到代码的完整指南
- 树莓派 PIR 运动传感器控制 LED 实战指南
- 树莓派低成本土壤湿度传感器:智能灌溉 DIY 指南
- 树莓派 DS18B20 温度传感器测试与 HC-SR04 超声波测距实战
- 树莓派 + MCP9808 + InfluxDB + Grafana:家庭温度监测系统
- Sensor Telemetry 2.0.1:基于 Azure IoT Hub 的高精度温度监控系统
- 低成本情绪传感器与 EEG:实时情绪检测硬件方案
- DIY Arduino TV-B-Gone:万能关机遥控器
- UnifiedWater v1 — 基于 Arduino MKR GSM 1400 的完整水质监测套件
- 面向色敏工艺的精准红外温度传感
- 无源红外传感器节能电路:设计、原理与应用
- 哪种激光雷达波长将主导汽车应用?