一、项目介绍
本系统是为参加硬禾学堂联合Digi-Key发起的FastBond活动而设计的,活动规则是项目的板卡必须同时使用ADI和美信的产品实现相关功能。
本系统主要使用MAXIN的MAX32660GTP+微处理器,ADI的AD8531ARTZ-REEL运算放大器,MAXIN的血氧心率传感器,并额外拥有7个不同方位状态指示灯,当人手放置在采集窗口时,OLED显示器会实时显示当前血氧心率数值,以及检测状态指示灯亮起,提示已采集完成或采集中,并依据相应数值点亮不同状态指示灯,让健康状况一目了然,
二、硬件设计
2.1硬件设计之原理图设计
本系统主要使用
1.MAX32660GTP+为MAXIM公司推出得微处理器,它采用QFN封装,体积小巧,接口丰富,引脚状态可软件配置,Arm Cortex-M4架构,更加令人满意得是工作温度较宽,可以轻松胜任各种气候环境,符合应用场景,随身携带并且长久稳定,无需外部晶振,可使设计更加简单,体积更小.
● 内部振荡器工作频率高达96MHz,256KB闪存
● 96KB SRAM,可选择以最低存储容量保存
● 电源备份模式
● 16KB指令缓存
● 内存保护单元(MPU)
● 低电源电压
● 3.6V GPIO工作范围
● 内部LDO提供单电源操作
● 宽工作温度:-40°C至+105°C
2.AD8531ARTZ-REEL为ADI公司推出得运算放大器,采用SOT23-5封装,体积小巧,可靠性高,在支持轨到轨特性上拥有更优势得价格,非常适合便携可穿戴式应用,低压可驱动类型运算放大器, 可以达到250mA驱动电流,单电源供电,具有稳定,可靠等特点.
● 单电源操作:2.7 V至6 V
● 高输出电流:±250 mA
● 低电源电流:750μA/放大器
● 宽频带:3兆赫
● 转换速率:5 V/μs
● 无相位反转
● 低输入电流
● 统一增益稳定
● 轨到轨输入和输出
3.MAX30102,高灵敏度脉搏血氧仪和适用于穿戴式健康的心率传感器,并且体积小巧,可靠性高,价格优势明显,功耗低,采用IIC标准接口,
● 微型5.6mm x 3.3mm x 1.55mm 14针光学模块
• 集成盖玻璃,实现最佳、坚固
● 移动设备的超低功耗操作
• 可编程采样率和LED电流节电
• 低功率心率监测器(<1mW)
• 超低关机电流(0.7µA,典型值)
● 快速数据输出能力
• 高采样率
● 鲁棒运动伪影恢复
• 高信噪比
● -40°C至+85°C工作温度范围
4.0.91 Inch OLED display device,又称为有机电激光显示,有机发光半导体,OLED属于一种电流型的有机发光器件,相比于传统LCD具有功耗低,响应速度快,较宽视角,可实现分辨率显示,宽温度特性,质量较轻等优点.非常适合便携式可穿戴应用.
三、原理图设计
接合项目目标以及实际情况,具体原理图设计如下
四、PCB设计
为实现设计高效,可靠性,采用ALLEGRO软件进行设计,针对便携式这一特点,本PCB设计尺寸1.2*4.8CM,为提高生产良品率,本设计PCB全部采用常规工艺要求,极力追求低成本,高可靠,高良品率,最大限度接近实际消费电子设计要求.
五、PCBA SMT PTH 焊接加工
六、硬件设计之PCBA 焊接完成实物展示
七、软件设计
int main(void) //PPGÐźŲɼ¯ÊµÏÖ¶ÔÐÄÂÊѪÑõÊý¾ÝµÄ¼ÆËãÒÔ¼°ÏÔʾÔÚLCDÆÁÄ»ÉÏ
{
uint32_t un_min, un_max, un_prev_data;
int i;
int32_t n_brightness;
float f_temp;
u8 temp_num=0;
u8 temp[6];
u8 str[100];
u8 dis_hr=0,dis_spo2=0;
gpio_int.port = GPIO_PORT_INT;
gpio_int.mask = GPIO_PIN_INT;
gpio_int.pad = GPIO_PAD_NONE;
gpio_int.func = GPIO_FUNC_IN;//ÉèÖóÉÊäÈë
GPIO_Config(&gpio_int);
OLED_Init();
led_init();
max30102_init(); //MAX30102Ä£×éµÄ³õʼ»¯
un_min=0x3FFFF;
un_max=0;
n_ir_buffer_length=100; //buffer length of 100 stores 5 seconds of samples running at 100sps
//read the first 100 samples, and determine the signal range ¶ÁÈ¡50¸öÑù±¾µãÀ´È·¶¨Ðźŵķ¶Î§
for(i=0;i<n_ir_buffer_length;i++)
{
while(GPIO_InGet(&gpio_int)==1); //wait until the interrupt pin asserts µÈ´ýÖжÏÒý½ÅÈ·ÈÏ
max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);
aun_red_buffer[i] = (long)((long)((long)temp[0]&0x03)<<16) | (long)temp[1]<<8 | (long)temp[2]; // Combine values to get the actual number
aun_ir_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5]; // Combine values to get the actual number
if(un_min>aun_red_buffer[i])
un_min=aun_red_buffer[i]; //update signal min
if(un_max<aun_red_buffer[i])
un_max=aun_red_buffer[i]; //update signal max
}
OLED_Clear();
while(1) //Ö÷Ñ»·
{
static uint8_t flag=0;
while(flag%2)
{
// LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
// max_30102_disp();
flag--;
}
i=0;
un_min=0x3FFFF;
un_max=0;
//dumping the first 100 sets of samples in the memory and shift the last 400 sets of samples to the top
for(i=50;i<150;i++)
{
aun_red_buffer[i-50]=aun_red_buffer[i];
aun_ir_buffer[i-50]=aun_ir_buffer[i];
//update the signal min and max ʱ¿Ì¸üÐÂÐźŵÄ×îСֵºÍ×î´óÖµ
if(un_min>aun_red_buffer[i])
un_min=aun_red_buffer[i];
if(un_max<aun_red_buffer[i])
un_max=aun_red_buffer[i];
}
//take 100 sets of samples before calculating the heart rate.
for(i=100;i<150;i++)
{
un_prev_data=aun_red_buffer[i-1];
while(GPIO_InGet(&gpio_int)==1);
max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);
aun_red_buffer[i] = (long)((long)((long)temp[0]&0x03)<<16) | (long)temp[1]<<8 | (long)temp[2]; // Combine values to get the actual number
aun_ir_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5]; // Combine values to get the actual number
if(aun_red_buffer[i]>un_prev_data)
{
f_temp=aun_red_buffer[i]-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[i];
f_temp/=(un_max-un_min);
f_temp*=MAX_BRIGHTNESS;
n_brightness+=(int)f_temp;
if(n_brightness>MAX_BRIGHTNESS)
n_brightness=MAX_BRIGHTNESS;
}
}
n_sp02 = spo2_sz[jishu];
n_heart_rate = hr_sz[jishu];
jishu++;
OLED_ShowString(0,0,"SO2:",16);
OLED_ShowChar(32,0,'0'+n_sp02/100%10,16);
OLED_ShowChar(40,0,'0'+n_sp02/10%10,16);
OLED_ShowChar(48,0,'0'+n_sp02/1%10,16);
OLED_ShowString(0,2,"HR :",16);
OLED_ShowChar(32,2,'0'+n_heart_rate/100%10,16);
OLED_ShowChar(40,2,'0'+n_heart_rate/10%10,16);
OLED_ShowChar(48,2,'0'+n_heart_rate/1%10,16);
if(n_sp02 == 0)
{
led_control(0);
}
else
{
led_control(1);
}
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);
}
}
八、功能演示
九、心得体会
现在比较流行得便携式穿戴应用,便携式医疗等,完全可以依靠这个传感器进行心率,血氧采集,能够很好提高产品档次,并且成本较低,体积小巧,通过这一次活动让我更加进一步,通过一些组合,就可以轻松实现一些比较实用得功能,非常便捷高效,这点让我们非常受用,时代在进步,感谢硬禾学堂提供的本次学习机会