本次DIY也使用了用来获取心率和血氧的传感器模块——MAX30102。通信方式是IIC。驱动程序在论坛管理员给的资料包中也有。在OLED驱动程序的基础上添加max30102文件夹下的文件,如果用MAX78000的I/O口模拟IIC通信的话,可以myssd1306文件夹下的xiic.c和.h文件复制过来。对应的I/O口在xiic.h文件中有定义。对应端口定义如下
#define MXC_GPIO_PORT_SDA MXC_GPIO2 #define MXC_GPIO_PORT_SCL MXC_GPIO2 #define MXC_GPIO_PIN_SDA MXC_GPIO_PIN_6 #define MXC_GPIO_PIN_SCL MXC_GPIO_PIN_7
可以修改对应的I/O口。主要的代码放在blood.c文件中,用了操作系统,如果不用操作系统的话需要修改一下。修改后main函数主要调用vTaskDataCollection函数即可,该函数有对MAX30102的初始化,包括对I/O的初始化。初始化代码如下
hardIIC_init(); max30102_reset(); max30102_Bus_Write(REG_INTR_ENABLE_1, 0xc0); // INTR setting max30102_Bus_Write(REG_INTR_ENABLE_2, 0x00); max30102_Bus_Write(REG_FIFO_WR_PTR, 0x00); // FIFO_WR_PTR[4:0] max30102_Bus_Write(REG_OVF_COUNTER, 0x00); // OVF_COUNTER[4:0] max30102_Bus_Write(REG_FIFO_RD_PTR, 0x00); // FIFO_RD_PTR[4:0] max30102_Bus_Write(REG_FIFO_CONFIG, 0x0f); // sample avg = 1, fifo rollover=false, fifo almost full = 17 max30102_Bus_Write(REG_MODE_CONFIG, 0x03); // 0x02 for Red only, 0x03 for SpO2 mode 0x07 multimode LED max30102_Bus_Write(REG_SPO2_CONFIG, 0x27); // SPO2_ADC range = 4096nA, SPO2 sample rate (100 Hz), LED pulseWidth (400uS) max30102_Bus_Write(REG_LED1_PA, 0x24); // Choose value for ~ 7mA for LED1 max30102_Bus_Write(REG_LED2_PA, 0x24); // Choose value for ~ 7mA for LED2 max30102_Bus_Write(REG_PILOT_PA, 0x7f); // Choose value for ~ 25mA for Pilot LED
初始化后会读取6字节的数据为血氧和心率的原始数据,也对这些数据做了一些处理,之前也没接触过传感器数据的处理,都是直接拿来用的,所以就直接用了。看源码和坛友的分享都是处理500多个数据才认为是有效的,但是在用的时候发现很长时间才有心跳数据。在数据处理中将数据通过串口发送后也将这些数据显示在OLED上。显示源码如下
sprintf(buff, "HpO2:%.2f ", sp02_num); GUI_ShowString(16,16,buff,16,1); sprintf(buff, "Hear:%d ", (int)Heart_Rate); GUI_ShowString(16,32,buff,16,1); OLED_Display();
下载后发现MAX30102会亮红灯,模拟真实的手表将手腕放在前面先是有血氧,过一会才有心率。不仅可以用串口查看这两个数据,也可以在OLED上查看对应的数据,效果如下