37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来—小小的进步或是搞不掂的问题,希望能够抛砖引玉。
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百:MAX30102血氧仪手腕心率脉搏检测心跳传感器模块
实验接线示意图
硬件连接(MAX30102 到 Arduino):
-5V = 5V(允许 3.3V)
-接地 = 接地
-SDA = A4(或 SDA)
-SCL = A5(或 SCL)
-INT = 中断脚未连接
MAX30102心率血氧传感器模块使用注意事项:
1、手指直接按压可能会出现压力变化,压力变化会对传感器数值产生影响。
2、佩戴部位为手指,佩戴没有方向区别。
3、本模块并非专业医疗仪器,不能作为辅助配件参与诊断和治疗。
程序五:在 Arduino 的串口绘图器上显示用户的心跳
Arduino参考开源代码
/*
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
程序五:在 Arduino 的串口绘图器上显示用户的心跳
下载库: http://librarymanager/All#SparkFun_MAX30105
*/
#include <Wire.h>
#include "MAX30105.h"
MAX30105 particleSensor;
void setup() {
Serial.begin(115200);
Serial.println("正在初始化...");
// 初始化传感器
if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //使用默认 I2C 端口,400kHz 速度
{
Serial.println("没有找到MAX30105,请检查接线/电源。 ");
while (1);
}
//设置以感应串口绘图器上漂亮的曲线
byte ledBrightness = 0x1F; //亮度选项:0=关 到 255=50mA
byte sampleAverage = 8; //样本平均值选项:1、2、4、8、16、32
byte ledMode = 3; //工作方式选项:1 = 仅红色,2 = 红色 + IR,3 = 红色 + IR + 绿色
int 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);
//Arduino 绘图仪令人讨厌地自动缩放。为了解决这个问题,预先填充
//绘图仪的传感器平均读数为 500
//在通电时取平均 IR 读数
const byte avgAmount = 64;
long baseValue = 0;
for (byte x = 0 ; x < avgAmount ; x++)
{
baseValue += particleSensor.getIR(); //读取IR值
}
baseValue /= avgAmount;
//预填充绘图仪,使 Y 比例接近 IR 值
for (int x = 0 ; x < 500 ; x++)
Serial.println(baseValue);
}
void loop() {
Serial.println(particleSensor.getIR()); //将原始数据发送到绘图器
delay(10);
}
打开Arduino IDE——工具——串口绘图器,查看实验波形
实验串口绘图器返回情况
程序六:最简输出传感器读取的原始值(IR 和红色读数)
Arduino参考开源代码
/*
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
程序六:最简输出传感器读取的原始值(IR 和红色读数)
下载库: http://librarymanager/All#SparkFun_MAX30105
*/
#include <Wire.h>
#include "MAX30105.h"//导入驱动库
MAX30105 particleSensor;
void setup() {
Serial.begin(9600);//初始化串口
Serial.println("MAX30102准备就绪");
// 初始化传感器
if (particleSensor.begin() == false) {
Serial.println("没有找到MAX30102,请检查接线/电源。");
while (1);
}
particleSensor.setup(); //配置传感器,使用 6.4mA 进行 LED 驱动
}
void loop() {
Serial.print(" R[");//串口打印传感器读取的原始值
Serial.print(particleSensor.getRed());
Serial.print("] IR[");
Serial.print(particleSensor.getIR());
Serial.println("]");
delay(1000);
}
实验串口返回情况
程序七:最简绘制心率波形
Arduino参考开源代码
/*
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
程序七:最简绘制心率波形
下载库: http://librarymanager/All#SparkFun_MAX30105
*/
#include <Wire.h>
#include "MAX30105.h"//导入驱动库
MAX30105 particleSensor;
void setup() {
Serial.begin(9600);//初始化串口
Serial.println("MAX30102准备就绪");
// 初始化传感器
if (particleSensor.begin() == false) {
Serial.println("没有找到MAX30102,请检查接线/电源。");
while (1);
}
particleSensor.setup(); //配置传感器,使用 6.4mA 进行 LED 驱动
}
void loop() {
Serial.print(particleSensor.getRed());
Serial.print(", ");
Serial.println(particleSensor.getIR());
delay(6);
}
打开Arduino IDE——工具——串口绘图器,查看实验波形
实验串口绘图器返回情况
在 Arduino IDE 中,选择工具 > 串行绘图仪。当您将手滑过传感器时,您应该会看到类似于下图的波浪。
程序八:以光学方式检测心率的演示
说明:这种方法很棘手,容易给出错误的读数。所以请不要将它用于实际的医疗诊断。
Arduino参考开源代码
/*
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
程序八:以光学方式检测心率的演示
说明:这种方法很棘手,容易给出错误的读数。所以请不要将它用于实际的医疗诊断。
下载库: http://librarymanager/All#SparkFun_MAX30105
*/
#include <Wire.h>
#include "MAX30105.h"//导入驱动库
#include "heartRate.h"
MAX30105 particleSensor;
const byte RATE_SIZE = 4; //增加这个以获得更多平均,4比较好。
byte rates[RATE_SIZE]; //心率数组
byte rateSpot = 0;
long lastBeat = 0; //最后一个节拍发生的时间
float beatsPerMinute;
int beatAvg;
void setup() {
Serial.begin(115200);
Serial.println("Initializing...");
// 初始化传感器
if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) {
Serial.println("MAX30102 was not found. Please check wiring/power. ");
while (1);
}
Serial.println("Place your index finger on the sensor with steady pressure.");
particleSensor.setup(); //使用默认设置配置传感器
particleSensor.setPulseAmplitudeRed(0x0A); //将红色LED变为低电平表示传感器正在运行
particleSensor.setPulseAmplitudeGreen(0); //关闭绿色LED
}
void loop() {
long irValue = particleSensor.getIR();
if (checkForBeat(irValue) == true) {
//我们感觉到了节拍!
long delta = millis() - lastBeat;
lastBeat = millis();
beatsPerMinute = 60 / (delta / 1000.0);
if (beatsPerMinute < 255 && beatsPerMinute > 20) {
rates[rateSpot++] = (byte)beatsPerMinute; //将此读数存储在数组中
rateSpot %= RATE_SIZE; //包装变量
//取读数的平均值
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);
if (irValue < 50000)
Serial.print(" No finger?");
Serial.println();
}
实验串口返回情况
程序九:简单测量血氧饱和度 (SpO2)
说明:将手指尽可能稳定地放在传感器上,然后等待几秒钟以使读数有意义。
Arduino参考开源代码
/*
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
程序九:测量血氧饱和度 (SpO2)
说明:将手指尽可能稳定地放在传感器上,然后等待几秒钟以使读数有意义。
下载库: http://librarymanager/All#SparkFun_MAX30105
*/
#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 来存储 100 个 32 位格式的 IR LED 数据和红色 LED 数据样本
//为了解决这个问题,采样数据的16位MSB将被截断。样本变成 16 位数据。
uint16_t irBuffer[100]; //红外LED传感器数据
uint16_t redBuffer[100]; //红色LED传感器数据
#else
uint32_t irBuffer[100]; //红外LED传感器数据
uint32_t redBuffer[100]; //红色LED传感器数据
#endif
int32_t bufferLength; //数据长度
int32_t spo2; //SPO2值
int8_t validSPO2; //用于显示 SPO2 计算是否有效的指标
int32_t heartRate; //心率值
int8_t validHeartRate; //显示心率计算是否有效的指标
byte pulseLED = 11; //必须在PWM引脚上
byte readLED = 13; //每次读取数据时闪烁
void setup() {
Serial.begin(115200); // 以每秒 115200 位初始化串行通信
pinMode(pulseLED, OUTPUT);
pinMode(readLED, OUTPUT);
// 初始化传感器
if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) // 使用默认 I2C 端口,400kHz 速度
{
Serial.println(F("MAX30105 was not found. Please check wiring/power."));
while (1);
}
Serial.println(F("Attach sensor to finger with rubber band. Press any key to start conversion"));
while (Serial.available() == 0) ; //等到用户按下一个键
Serial.read();
byte ledBrightness = 60; //Options: 0=Off to 255=50mA
byte sampleAverage = 4; //Options: 1, 2, 4, 8, 16, 32
byte ledMode = 2; //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green
byte sampleRate = 100; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
int pulseWidth = 411; //Options: 69, 118, 215, 411
int adcRange = 4096; //Options: 2048, 4096, 8192, 16384
//使用这些设置配置传感器
particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange);
}
void loop() {
bufferLength = 100; // 100 的缓冲区长度存储以 25sps 运行的 4 秒样本
//读取前100个样本,并确定信号范围
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 个样本后的心率和 SpO2(前 4 秒样本)
maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
//继续从MAX30102采样。每 1 秒计算一次心率和 SpO2
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(", HR="));
Serial.print(heartRate, DEC);
Serial.print(F(", HRvalid="));
Serial.print(validHeartRate, DEC);
Serial.print(F(", SPO2="));
Serial.print(spo2, DEC);
Serial.print(F(", SPO2Valid="));
Serial.println(validSPO2, DEC);
}
//收集25个新样本后重新计算HR和SP02
maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
}
}
实验串口返回情况