9119|16

8

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

求助 max30102 心率血氧测试模块的问题 [复制链接]

 
本帖最后由 小白(学习中) 于 2019-8-4 14:57 编辑

我用的stm32f103rct6  软件模拟的iic  收到max30102 采集的数据处理之后的波形 浮动很大,怎么解决啊

 

这是采样数据,浮动值很大,下面配上IIC配置,算法模块是美信官网找的。求大佬指教

#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x.h"
#include "drv_systick.h"
#include "stdio.h"
#include "max30102_algorithm.h"
#include "DataScope_DP.h"

#define MAX_BRIGHTNESS 			255

//register addresses

#define REG_INTR_STATUS_1 		0x00
#define REG_INTR_STATUS_2 		0x01
#define REG_INTR_ENABLE_1 		0x02
#define REG_INTR_ENABLE_2 		0x03
#define REG_FIFO_WR_PTR 		0x04
#define REG_OVF_COUNTER 		0x05
#define REG_FIFO_RD_PTR 		0x06
#define REG_FIFO_DATA 			0x07
#define REG_FIFO_CONFIG 		0x08
#define REG_MODE_CONFIG 		0x09
#define REG_SPO2_CONFIG 		0x0A
#define REG_LED1_PA 			0x0C
#define REG_LED2_PA 			0x0D
#define REG_PILOT_PA 			0x10
#define REG_MULTI_LED_CTRL1		0x11
#define REG_MULTI_LED_CTRL2		0x12
#define REG_TEMP_INTR 			0x1F
#define REG_TEMP_FRAC 			0x20
#define REG_TEMP_CONFIG 		0x21
#define REG_PROX_INT_THRESH 	0x30
#define REG_REV_ID 				0xFE
#define REG_PART_ID 			0xFF

#define IIC_MAX30102_OK			0
#define IIC_MAX30102_Err		1


/*max30102 iic */

#define MAX30102_IIC_APBPERIPH_CLK_FUNC		RCC_APB2PeriphClockCmd
#define MAX30102_IIC_APBPERIPH_PORT			RCC_APB2Periph_GPIOB
#define MAX30102_IIC_PORT					GPIOB
#define MAX30102_IIC_PIN_SCL				GPIO_Pin_4
#define MAX30102_IIC_PIN_SDA				GPIO_Pin_3
#define MAX30102_INT						GPIO_Pin_5

#define MAX30102_SDA_HIGH()			GPIO_SetBits(MAX30102_IIC_PORT, MAX30102_IIC_PIN_SDA)
#define MAX30102_SDA_LOW()			GPIO_ResetBits(MAX30102_IIC_PORT, MAX30102_IIC_PIN_SDA)
#define MAX30102_SDA_READ()			GPIO_ReadInputDataBit(MAX30102_IIC_PORT, MAX30102_IIC_PIN_SDA)

#define MAX30102_SCL_HIGH()			GPIO_SetBits(MAX30102_IIC_PORT, MAX30102_IIC_PIN_SCL)
#define MAX30102_SCL_LOW()			GPIO_ResetBits(MAX30102_IIC_PORT, MAX30102_IIC_PIN_SCL)

#define MAX30102_INT_HIGH()			GPIO_SetBits(MAX30102_IIC_PORT, MAX30102_INT)
#define MAX30102_INT_LOW()			GPIO_ResetBits(MAX30102_IIC_PORT, MAX30102_INT)
#define MAX30102_INT_READ()			GPIO_ReadInputDataBit(MAX30102_IIC_PORT, MAX30102_INT)

#define IIC_TIME_OUT				2
#define WAIT_TIME_OUT				2000

#define MAX30102_I2C_OK				1
#define MAX30102_I2C_ERR			0

#define MAX30102_WRITE_ADDR			0XAE
#define MAX30102_READ_ADDR			0XAF

#define BUFSIZE						500	


/*引脚初始化*/
void MAX30102_I2C_Config(void)
{
	/*PB3 ,PB4    PB5为int  推挽输出 */
	/*先失能JTAG 功能*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	
	/*改变指定管脚的映射 GPIO_Remap_SWJ_Disable SWJ 完全禁用(JTAG+SW-DP)*/
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);
	
	/*改变指定管脚的映射 GPIO_Remap_SWJ_JTAGDisable ,JTAG-DP 禁用 + SW-DP 使能*/
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);

	RCC_APB2PeriphClockCmd(MAX30102_IIC_APBPERIPH_PORT, ENABLE);	//打开GPIOB的时钟
	GPIO_InitTypeDef GPIO_InitStruct;

	GPIO_InitStruct.GPIO_Pin = MAX30102_IIC_PIN_SCL | MAX30102_IIC_PIN_SDA;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(MAX30102_IIC_PORT,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin = MAX30102_INT;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(MAX30102_IIC_PORT,&GPIO_InitStruct);

}

/*SDA输出*/
void MAX30102_I2C_SdaOut(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;

	GPIO_InitStruct.GPIO_Pin = MAX30102_IIC_PIN_SDA;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(MAX30102_IIC_PORT,&GPIO_InitStruct);
}

/*SDA输入*/
void MAX30102_I2C_SdaIn(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;

	GPIO_InitStruct.GPIO_Pin = MAX30102_IIC_PIN_SDA;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(MAX30102_IIC_PORT,&GPIO_InitStruct);
}

/*开始信号*/
void MAX30102_I2C_Start(void)
{
	MAX30102_SCL_LOW();					//拉低SCL
	MAX30102_I2C_SdaOut();
	MAX30102_SDA_HIGH();				//拉高SDA

	MAX30102_SCL_HIGH();				//拉高SCL
	SYSTICK_DelayNus(IIC_TIME_OUT);
	MAX30102_SDA_LOW();
	SYSTICK_DelayNus(IIC_TIME_OUT);		//延时,速度控制
	MAX30102_SCL_LOW();					//钳住SCL
}

/*停止信号*/
void MAX30102_I2C_Stop(void)
{
	MAX30102_SCL_LOW();					//拉低SCL
	MAX30102_I2C_SdaOut();

	MAX30102_SDA_LOW();					//拉低SDA
	SYSTICK_DelayNus(IIC_TIME_OUT);
	MAX30102_SCL_HIGH();				//拉高SCL	
	MAX30102_SDA_HIGH();				//拉高SDA
	SYSTICK_DelayNus(IIC_TIME_OUT);
}

/*ACK信号*/
void MAX30102_I2C_SendAck(void)
{
	MAX30102_SCL_LOW();
	MAX30102_I2C_SdaOut();
	
	//MAX30102_SDA_HIGH();
	MAX30102_SDA_LOW();
	SYSTICK_DelayNus(IIC_TIME_OUT);
	MAX30102_SCL_HIGH();
	SYSTICK_DelayNus(IIC_TIME_OUT);
	MAX30102_SCL_LOW();
	MAX30102_SDA_HIGH();	
}

/*NACK*/
void MAX30102_I2C_SendNoAck(void)
{
	MAX30102_SCL_LOW();
	MAX30102_I2C_SdaOut();

	MAX30102_SDA_HIGH();
	SYSTICK_DelayNus(IIC_TIME_OUT);
	MAX30102_SCL_HIGH();
	SYSTICK_DelayNus(IIC_TIME_OUT);
	MAX30102_SCL_LOW();
}

/*等待ACK信号*/
uint8_t MAX30102_I2C_WaitAck(uint16_t TimeOut)
{
	MAX30102_SCL_LOW();
	MAX30102_I2C_SdaIn();

	MAX30102_SCL_HIGH();		/*数据高电平有效 读之前先拉高*/

	while(MAX30102_SDA_READ())
	{
		if(TimeOut == 0)			/*超时检测,异常终止*/
		{
			printf("WaitAck TimeOut!\n");
			MAX30102_I2C_Stop();
			return MAX30102_I2C_ERR;
		}
		TimeOut--;
		SYSTICK_DelayNus(IIC_TIME_OUT);
	}
	
	MAX30102_SCL_LOW();
	return MAX30102_I2C_OK;
}

/*i2c 发送一个字节*/
void MAX30102_I2C_SendByte(uint8_t byte)
{
	uint8_t i = 0;

	MAX30102_SCL_LOW();						/*拉低时钟传输数据*/
	MAX30102_I2C_SdaOut();
	for(i = 0; i < 8; i++)
	{
		if(byte & 0x80)						/*高位先行*/
			MAX30102_SDA_HIGH();
		else
			MAX30102_SDA_LOW();
		byte <<= 1;
		
		SYSTICK_DelayNus(IIC_TIME_OUT);
		MAX30102_SCL_HIGH();				/*拉高数据有效*/
		SYSTICK_DelayNus(IIC_TIME_OUT);
		MAX30102_SCL_LOW();
	}
}

/*I2c接收一个字节 */
uint8_t MAX30102_I2C_RecvByte(void)
{
	uint8_t date = 0;
	uint8_t i = 0;

	MAX30102_SCL_LOW();
	MAX30102_I2C_SdaIn();

	for(i = 0; i < 8; i++)
	{
		date <<= 1;
		MAX30102_SCL_HIGH();
		SYSTICK_DelayNus(IIC_TIME_OUT);
		if(MAX30102_SDA_READ())
			date |= 0x01;

		MAX30102_SCL_LOW();
		SYSTICK_DelayNus(IIC_TIME_OUT);	
	}
	return date;
}

/*	软件IIC写一个数据
	slaveAddr:从机地址
	regAddr:寄存器地址
	byte:需要写入的数据*/
uint8_t MAX30102_I2C_WriteByte(uint8_t regAddr,uint8_t *byte)
{
	MAX30102_I2C_Start();				/*起始信号*/
	
	MAX30102_I2C_SendByte(MAX30102_WRITE_ADDR);		/*设备地址,写操作0*/

	if(!MAX30102_I2C_WaitAck(WAIT_TIME_OUT))		/*等待应答,超时检测*/
	{
		printf("WaitAck1 TimeOut!\n");
		goto ERR_HANDLER;
	}
	
	MAX30102_I2C_SendByte(regAddr);		/*发送寄存器地址*/
	if(!MAX30102_I2C_WaitAck(WAIT_TIME_OUT))		/*等待应答*/
	{
		printf("WaitAck2 TimeOut!\n");
		goto ERR_HANDLER;
	}
	MAX30102_I2C_SendByte(*byte);
	if(!MAX30102_I2C_WaitAck(WAIT_TIME_OUT))		/*等待应答*/
	{
		printf("WaitAck3 TimeOut!\n");
		goto ERR_HANDLER;
	}
	
	MAX30102_I2C_Stop();					/*停止*/
	return MAX30102_I2C_OK;
ERR_HANDLER:
	return MAX30102_I2C_ERR;

}

/*I2C读一个数据*/
uint8_t MAX30102_I2C_ReadByte(uint8_t regAddr,uint8_t *byte)
{
	MAX30102_I2C_Start();							/*起始信号*/
	
	MAX30102_I2C_SendByte(MAX30102_WRITE_ADDR);		/*设备地址,写操作0,*/
	if(!MAX30102_I2C_WaitAck(WAIT_TIME_OUT))					/*等待应答,超时检测*/
	{
		printf("WaitAck4 TimeOut!\n");
		goto ERR_HANDLER;
	}
		
	MAX30102_I2C_SendByte(regAddr); 				/*发送寄存器地址*/
	if(!MAX30102_I2C_WaitAck(WAIT_TIME_OUT))					/*等待应答*/
	{
		printf("WaitAck5 TimeOut!\n");
		goto ERR_HANDLER;
	}
	
	MAX30102_I2C_Start();							/*重启信号*/
	
	MAX30102_I2C_SendByte(MAX30102_READ_ADDR);		/*设备地址,读操作1*/
	if(!MAX30102_I2C_WaitAck(WAIT_TIME_OUT))					/*等待应答,超时检测*/
	{
		printf("WaitAck6 TimeOut!\n");
		goto ERR_HANDLER;
	}
	
	*byte = MAX30102_I2C_RecvByte();				/*接收*/
	
	MAX30102_I2C_SendNoAck();						/*产生一个非应答信号*/
	
	MAX30102_I2C_Stop();
	
	return MAX30102_I2C_OK;
 ERR_HANDLER:
 	
	return MAX30102_I2C_ERR;
}

/*软件I2C 向指定设备 指定地址 写多个数据*/
/*regAddr寄存器地址*/
/*buf 数据缓冲区*/
/*num 缓冲区大小*/
uint8_t MAX30102_I2C_WriteBytes(uint8_t regAddr,uint8_t *buf,uint8_t num)
{
	MAX30102_I2C_Start();							/*起始信号*/
	
	MAX30102_I2C_SendByte(MAX30102_WRITE_ADDR);		/*设备地址,写操作0*/

	if(!MAX30102_I2C_WaitAck(WAIT_TIME_OUT))					/*等待应答,超时检测*/
	{
		printf("WaitAck1 TimeOut!\n");
		goto ERR_HANDLER;
	}
	
	MAX30102_I2C_SendByte(regAddr);		/*发送寄存器地址*/
	if(!MAX30102_I2C_WaitAck(WAIT_TIME_OUT))		/*等待应答*/
	{
		printf("WaitAck2 TimeOut!\n");
		goto ERR_HANDLER;
	}

	while(num--)							/*循环写入*/
	{	
		MAX30102_I2C_SendByte(*buf);		/*发送数据*/
		if(!MAX30102_I2C_WaitAck(WAIT_TIME_OUT))		/*等待应答*/
		{
			printf("WaitAck3 TimeOut!\n");
			goto ERR_HANDLER;
		}
		buf++;
		SYSTICK_DelayNus(10);
	}

	MAX30102_I2C_Stop();					/*停止*/
	return MAX30102_I2C_OK;
	
ERR_HANDLER:
	
	return MAX30102_I2C_ERR;
}

/*I2C读多个数据*/
uint8_t MAX30102_I2C_ReadBytes(uint8_t regAddr,uint8_t *buf,uint8_t num)
{
	MAX30102_I2C_Start();							/*起始信号*/
	
	MAX30102_I2C_SendByte(MAX30102_WRITE_ADDR);		/*设备地址,写操作0,*/
	if(!MAX30102_I2C_WaitAck(WAIT_TIME_OUT))					/*等待应答,超时检测*/
	{
		printf("WaitAck4 TimeOut!\n");
		goto ERR_HANDLER;
	}
		
	MAX30102_I2C_SendByte(regAddr); 	/*发送寄存器地址*/
	if(!MAX30102_I2C_WaitAck(WAIT_TIME_OUT))		/*等待应答*/
	{
		printf("WaitAck5 TimeOut!\n");
		goto ERR_HANDLER;
	}
	
	MAX30102_I2C_Start();							/*重启信号*/
	
	MAX30102_I2C_SendByte(MAX30102_READ_ADDR);		/*设备地址,读操作1*/
	if(!MAX30102_I2C_WaitAck(WAIT_TIME_OUT))					/*等待应答,超时检测*/
	{
		printf("WaitAck6 TimeOut!\n");
		goto ERR_HANDLER;
	}
	while(num--)						/*循环读数据*/
	{
		*buf = MAX30102_I2C_RecvByte();
		buf++;
		if(num == 0)
			MAX30102_I2C_SendNoAck();	/*最后一个数据回 NoACK*/
		else
			MAX30102_I2C_SendAck();		/*回应ACK*/
	}
	MAX30102_I2C_Stop();
	
	return MAX30102_I2C_OK;
ERR_HANDLER:
	
	return MAX30102_I2C_ERR;
}

/*复位*/
uint8_t MAX30102_Reset(void)
{
	uint8_t val = 0x40;
	if(MAX30102_I2C_WriteByte(REG_MODE_CONFIG,&val))
		return MAX30102_I2C_OK;
	else
		return MAX30102_I2C_ERR;
}

/*初始化*/
uint8_t MAX30102_Config(void)
{
	uint8_t val = 0;
	   val = 0xc0;
	if(!MAX30102_I2C_WriteByte(REG_INTR_ENABLE_1,&val)) // INTR setting
		return MAX30102_I2C_ERR;
	val = 0x00;		
	if(!MAX30102_I2C_WriteByte(REG_INTR_ENABLE_2,&val))
		return MAX30102_I2C_ERR;
	/*val = 0x01;		
	if(!MAX30102_I2C_WriteByte(REG_TEMP_CONFIG,&val)) //
		return MAX30102_I2C_ERR;*/
	val = 0x00;		
	if(!MAX30102_I2C_WriteByte(REG_FIFO_WR_PTR,&val))  //FIFO_WR_PTR[4:0]
		return MAX30102_I2C_ERR;
	val = 0x00;
	if(!MAX30102_I2C_WriteByte(REG_OVF_COUNTER,&val))  //OVF_COUNTER[4:0]
		return MAX30102_I2C_ERR;
	val = 0x00;
	if(!MAX30102_I2C_WriteByte(REG_FIFO_RD_PTR,&val))  //FIFO_RD_PTR[4:0]
		return MAX30102_I2C_ERR;
	val = 0x0f; 	
	if(!MAX30102_I2C_WriteByte(REG_FIFO_CONFIG,&val))  //sample avg = 1, fifo rollover=false, fifo almost full = 17
		return MAX30102_I2C_ERR;
	val = 0x03;
	if(!MAX30102_I2C_WriteByte(REG_MODE_CONFIG,&val))   //0x02 for Red only, 0x03 for SpO2 mode 0x07 multimode LED
		return MAX30102_I2C_ERR;
	val = 0x27; 
	if(!MAX30102_I2C_WriteByte(REG_SPO2_CONFIG,&val))  // SPO2_ADC range = 4096nA, SPO2 sample rate (100 Hz), LED pulseWidth (400uS)
		return MAX30102_I2C_ERR;
	val = 0x24; 
	if(!MAX30102_I2C_WriteByte(REG_LED1_PA,&val))  		 //Choose value for ~ 7mA for LED1
		return MAX30102_I2C_ERR;
	val = 0x24; 
	if(!MAX30102_I2C_WriteByte(REG_LED2_PA,&val))   	// Choose value for ~ 7mA for LED2
		return MAX30102_I2C_ERR;
	val = 0x7f; 
	if(!MAX30102_I2C_WriteByte(REG_PILOT_PA,&val))   	// Choose value for ~ 25mA for Pilot LED
		return MAX30102_I2C_ERR;	

	return MAX30102_I2C_OK;  
}


/*从MAX3102FIFO寄存器中简要读取一组样本
param[out]*pun_red_LED-存储红色LED读取数据的指针
param[out]* pun_ir_led-存储红外LED读取数据的指针
成功时返回真值*/

uint8_t MAX30102_Read_FIFO(uint32_t *pun_red_led, uint32_t *pun_ir_led)
{
	uint32_t un_temp;
	uint8_t ach_i2c_data[6];
	uint8_t uch_temp;
	*pun_red_led = 0;
  	*pun_ir_led = 0;

	/*读取清除寄存器状态*/
	MAX30102_I2C_ReadByte(REG_INTR_STATUS_1, &uch_temp);
	MAX30102_I2C_ReadByte(REG_INTR_STATUS_2, &uch_temp);

	ach_i2c_data[0] = REG_FIFO_DATA;
	if(!MAX30102_I2C_WriteBytes(REG_FIFO_DATA,ach_i2c_data,1))
		return MAX30102_I2C_ERR;
	if(!MAX30102_I2C_ReadBytes(REG_FIFO_DATA, ach_i2c_data,6))
		return MAX30102_I2C_ERR;

	un_temp = (unsigned char) ach_i2c_data[0];
	un_temp <<= 16;
	*pun_red_led += un_temp;
	un_temp = (unsigned char) ach_i2c_data[1];
	un_temp <<= 8;
	*pun_red_led += un_temp;
	un_temp = (unsigned char) ach_i2c_data[2];
	*pun_red_led += un_temp;

	un_temp = (unsigned char) ach_i2c_data[3];
	un_temp <<= 16;
	*pun_ir_led += un_temp;
	un_temp = (unsigned char) ach_i2c_data[4];
	un_temp <<= 8;
	*pun_ir_led += un_temp;
	un_temp = (unsigned char) ach_i2c_data[5];
	*pun_ir_led += un_temp;

	*pun_red_led &= 0x03ffff;		/* Mask MSB [23:18] */
	*pun_ir_led &= 0x03ffff;

	return MAX30102_I2C_OK;
}
uint32_t aun_ir_buffer[BUFSIZE];	 //红外LED传感器数据
int32_t n_ir_buffer_length;      //数据长度
uint32_t aun_red_buffer[BUFSIZE];    //红色LED传感器数据
int32_t n_sp02; 				 //SpO2值
int8_t ch_spo2_valid;   		 //指示SP02计算是否有效的指示器
int32_t n_heart_rate;  			 //心率值
int8_t  ch_hr_valid;    		 //显示心率计算是否有效的指示器
uint8_t uch_dummy;
uint32_t un_min, un_max, un_prev_data;  //用于计算反映心跳的LED亮度的变量
int i;
int32_t n_brightness;
float f_temp;

void MAX30102_test1(void)
{
	//MAX30102_Reset();		/*复位*/

	MAX30102_I2C_ReadByte(REG_INTR_STATUS_1, &uch_dummy);	

	//while(!MAX30102_Config())			/*初始化*/
	//{
	//	printf("max30102_init error!\n");
	//}

	n_brightness = 0;

	un_min = 0x3ffff;
	un_max = 0;
	
	n_ir_buffer_length = BUFSIZE;

	/*读取前n_ir_buffer_length个样本,确定信号范围*/
	for(i = 0; i < n_ir_buffer_length; i++ )
	{
		while(MAX30102_INT_READ());		/*等待中断响应	低电平有效*/
		MAX30102_Read_FIFO((aun_red_buffer+i),(aun_ir_buffer+i));

		if(un_min > aun_red_buffer)
            un_min = aun_red_buffer;    //update signal min
        if(un_max < aun_red_buffer)
            un_max = aun_red_buffer;    //update signal max

				/*打印波形*/
		//sendwares(&aun_red_buffer,&aun_ir_buffer,4);

		/*printf("red=");
		printf("%i", aun_red_buffer);
		printf(", ir=");
		printf("%i\n\r", aun_ir_buffer);*/
	}
	un_prev_data = aun_red_buffer;

	maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);

			/*打印波形*/
	sendwares(&n_heart_rate,&n_sp02,4);
}

uint8_t HR_value;
uint8_t SpO2_value;

void MAX30102_test2(void)
{
		i=0;
        un_min = 0x3FFFF;
        un_max = 0;
		
		/*将前100组样本转储到内存中,并将最后400组样本移到顶部*/
		for(i = 100; i < n_ir_buffer_length; i++)
		{
			aun_red_buffer[i-100] = aun_red_buffer;
            aun_ir_buffer[i-100] = aun_ir_buffer;
            
            //update the signal min and max
            if(un_min > aun_red_buffer)
            	un_min = aun_red_buffer;
            if(un_max < aun_red_buffer)
            	un_max = aun_red_buffer;
		}
		
		/*计算心率前取100组样本*/
		
		for(i = 400 ; i < 500; i++ )
		{
			un_prev_data = aun_red_buffer[i-1];
			while(MAX30102_INT_READ());
			MAX30102_Read_FIFO((aun_red_buffer + i), (aun_ir_buffer + i));

			if(aun_red_buffer > un_prev_data)  //just to determine the brightness of LED according to the deviation of adjacent two AD data
			{
				f_temp = aun_red_buffer-un_prev_data;
				f_temp /= (un_max-un_min);
				f_temp *= MAX_BRIGHTNESS;
				n_brightness -= (int)f_temp;
			if(n_brightness < 0)
				n_brightness = 0;
			}
			else
			{
				f_temp = un_prev_data - aun_red_buffer;
				f_temp /= (un_max-un_min);
				f_temp *= MAX_BRIGHTNESS;
				n_brightness += (int)f_temp;
				
				if(n_brightness > MAX_BRIGHTNESS)
					n_brightness = MAX_BRIGHTNESS;				
			}
			/*if(n_heart_rate < 40|| n_heart_rate >150)
					n_heart_rate = 0;
			if(n_sp02 < 40|| n_sp02 >100)
					n_sp02 = 0;*/
			
			printf(" red=");
			printf("%i", aun_red_buffer);
			printf(", ir=");
			printf("%i\n\r", aun_ir_buffer);
				
			printf(" HR=%i, ", n_heart_rate);
			printf("HRvalid=%i, ", ch_hr_valid);
			printf("SpO2=%i, ", n_sp02);
			printf("SPO2Valid=%i\n\r", ch_spo2_valid);


      }

	maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
}

 

image.png (14.73 KB, 下载次数: 0)

image.png

image.png (20.22 KB, 下载次数: 0)

image.png
此帖出自ARM技术论坛

最新回复

你好,你的问题解决了吗?我现在测试到也发现数据时错误的,不知道怎么解决   详情 回复 发表于 2021-6-25 17:31
点赞 关注(1)
 

回复
举报

8

帖子

0

TA的资源

一粒金砂(中级)

沙发
 

大佬们看看啊,别沉啊

此帖出自ARM技术论坛

点评

楼主问题解决了吗?是那两个电阻,模拟I2C的电阻吗? 楼主有遇到red和ir的值相等的问题吗?  详情 回复 发表于 2021-5-31 16:27
 
 
 

回复

626

帖子

173

TA的资源

一粒金砂(高级)

板凳
 

@chenzhufly  @wsdymg  @dcexpert  

帮你问问这两个大佬

此帖出自ARM技术论坛
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
 
 

回复

5979

帖子

8

TA的资源

版主

4
 

第一检查硬件,是不是电路噪声大;

第二检查原始数据,原始数据是否正确

第三检查算法,算法是否有效,能够有效滤波

此帖出自ARM技术论坛

点评

原始数据看了论坛里面测试成功的大佬的截图,差不多的,算法是官方提供的  详情 回复 发表于 2019-8-15 11:28
 
个人签名生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
 
 

回复

1万

帖子

24

TA的资源

版主

5
 

没有用这个芯片,记得以前MAXIM说算法是不公开的,可能数据处理方面需要多想想。

此帖出自ARM技术论坛
 
 
 

回复

8

帖子

0

TA的资源

一粒金砂(中级)

6
 
chenzhufly 发表于 2019-8-6 11:50 第一检查硬件,是不是电路噪声大; 第二检查原始数据,原始数据是否正确 第三检查算法,算法是否有效 ...

原始数据看了论坛里面测试成功的大佬的截图,差不多的,算法是官方提供的

此帖出自ARM技术论坛
 
 
 

回复

525

帖子

235

TA的资源

版主

7
 

用示波器看一下原始数据波形波动情况,如果硬件本身干扰较大就得从硬件上解决,软件滤波打辅助

此帖出自ARM技术论坛
 
个人签名爱电子,爱生活
 
 

回复

291

帖子

0

TA的资源

一粒金砂(高级)

8
 

检查一下硬件是否出错

此帖出自ARM技术论坛
 
 
 

回复

8

帖子

0

TA的资源

一粒金砂(中级)

9
 

多谢各位,之前是少了2个电阻,电压不够,

此帖出自ARM技术论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

10
 

你这个是基于C 的吗

此帖出自ARM技术论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

11
 
LLLLLLddd 发表于 2019-9-14 21:55 你这个是基于C 的吗

max30102是不是

此帖出自ARM技术论坛
 
 
 

回复

125

帖子

0

TA的资源

一粒金砂(高级)

12
 
chenzhufly 发表于 2019-8-6 11:50 第一检查硬件,是不是电路噪声大; 第二检查原始数据,原始数据是否正确 第三检查算法,算法是否有效 ...

呃嗯 这样思路很清晰了 ,谢谢

此帖出自ARM技术论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

13
 
楼主你好,请问你是哪少了电阻,我测的心率血氧都是错的
此帖出自ARM技术论坛
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

14
 

我想问问您,我的状况和您的是一样的,您是怎么解决的,希望您能指导一下。非常感谢

823940465@qq.com

此帖出自ARM技术论坛
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

15
 
小白(学习中) 发表于 2019-8-22 19:17 多谢各位,之前是少了2个电阻,电压不够,

哪里少了两个电阻呢,楼主?

此帖出自ARM技术论坛
 
 
 

回复

844

帖子

3

TA的资源

版主

16
 
小白(学习中) 发表于 2019-8-4 12:57 大佬们看看啊,别沉啊

楼主问题解决了吗?是那两个电阻,模拟I2C的电阻吗?

楼主有遇到red和ir的值相等的问题吗?

此帖出自ARM技术论坛
 
 
 

回复

2

帖子

1

TA的资源

一粒金砂(初级)

17
 
Healer03 发表于 2020-3-26 17:58 楼主你好,请问你是哪少了电阻,我测的心率血氧都是错的

你好,你的问题解决了吗?我现在测试到也发现数据时错误的,不知道怎么解决

此帖出自ARM技术论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表