MAX30102学习笔记(下)
一.与stm32的连接
各引脚连接
max30102<->stm32
- VCC<->3.3V
- GND<->GND
- SCL<->PB6
- SDA<->PB7
- IM<->PB9( IM脚是int)
如果stm32要和oled连接
0.96inch OLED <->stm32
- VCC<->3.3V
- GND<->GND
- D0 <->PA5
- D1 <->PA6
- RST<->pb5
- DC <->PA4
- CS <->pb6
连接成功后大概是这样的(焊接的有点…丑)
二.代码部分
一部分的主函数
int main(void)
{
uint8_t uch_dummy;
delay_init(); //延时函数初始化
LED_Init(); //初始化led
uart_init(115200);
KEY_Init();
//max30102初始化
max30102_reset(); //resets the MAX30102
maxim_max30102_read_reg(REG_INTR_STATUS_1,&uch_dummy); //Reads/clears the interrupt status register
max30102_init(); //initialize the MAX30102
//读取ID
max_id= max30102_Bus_Read(REG_PART_ID);
//初始化结束
while(1)
{
//buffer length of BUFFER_SIZE stores ST seconds of samples running at FS sps
//read BUFFER_SIZE samples, and determine the signal range
for(i=0;i<BUFFER_SIZE;i++)
{
while(MAX30102_INT==1); //wait until the interrupt pin asserts;
max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);//当连接成功时从max30102中读取数据
//红光三字节数据,红外字三节数据
aun_ir_buffer[i] = (long)((long)((long)temp[0]&0x03)<<16) | (long)temp[1]<<8 | (long)temp[2]; // Combine values to get the actual number
aun_red_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5];
if(b>50)
printf(" %d",aun_ir_buffer[i]);
if(aun_ir_buffer[i]>20000)//手指正常接触的数据都是10w+
{b++;
if(b>80)//防止b的溢出
b=51;//大于51就可以了
}
else//松手后执行
{
b=0;
i=BUFFER_SIZE;
aun_ir_buffer[0]=0;
aun_ir_buffer[80]=0;
aun_ir_buffer[35]=0;
aun_ir_buffer[20]=0;
aun_ir_buffer[50]=0;
aun_ir_buffer[149]=0;
aun_ir_buffer[100]=0;
}
//因为每次开始时手指接触模块都会有点颤抖导致所测数据不准确所以就丢掉最开始的50组数据,不用他们进行计算
if(b==50)//当手指第一次按下时扔,后面不执行
{i=-1;
b=51;
}
}
//calculate heart rate and SpO2 after BUFFER_SIZE samples (ST seconds of samples) using Robert's method
//计算心率
//calculate heart rate and SpO2 after BUFFER_SIZE samples (ST seconds of samples) using Robert's method
if(b>50)
rf_heart_rate_and_oxygen_saturation(aun_ir_buffer, BUFFER_SIZE, aun_red_buffer, &n_spo2, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid, &ratio, &correl);
//解决有时候松手时突然弹出的一个hr=40的数据
if(aun_ir_buffer[0]<70000||aun_ir_buffer[80]<70000||aun_ir_buffer[110]<70000||aun_ir_buffer[149]<70000)
ch_hr_valid=0;
if((ch_hr_valid == 1)&&(ch_spo2_valid == 1))
{
data[0]=data[1];
data[1]=data[2];
data[2]=n_heart_rate;
if(data[1]>20&&data[0]>20)
n_heart_rate=(data[0]+data[1]+data[2])/3;
printf("hr=%d sp=%d",n_heart_rate,(int)n_spo2);
}
else
{
data[0]=0;
data[1]=0;
data[2]=0;
n_heart_rate=0;
n_spo2=0;
}
}
}
三.程序基本思路
- 先对各项要用到的部分进行初始化操作
- 模块和单片机连接成功后进行数据的采集,I2C协议,判断手指是否有按在心率模块上(有手指判断是否为第一次),然后对采集到的数据判断是否有效(手指有抖动幅度较大的都是无效数字会删去)。
- 执行算法(手指为第一次时前50个数据不纳入计算因为误差较大)
- 返回数据
网上看到的一个对算法理解有帮助的图
四.成功效果
串口助手接受数据的图
用其中一次成功数据用excel表格绘制的图片