Funpack第六期-MAX32660-EVSYS-心率计
利用 MAX32660 作为主控 MCU,MAX30102 传感器采样数据,SSD12864 显示,完成了一个心率计的功能。
标签
嵌入式系统
Jackistang
更新2021-03-22
1136

Funpack第六期-MAX32660-EVSYS评估板

利用 MAX32660 + MAX30102 + OLED12864 完成了心率测量显示的任务。

硬件资料

MAX32660-EVSYS评估板

评估板最核心的是MAX32660微控制器,属于美信DARWIN产品系列,是一款超低功耗、性价比突出、集成度非常高的32位控制器。

FgsPG5m_ysdsZSYjU5yGXioN1Toy

FriG5pf-pF3IkgoMipw778DtPpJa

FvN35BTPWFEbwAEsF8rl0WVJeKk0

FtHulxgrqtXJmeCtdFUys9Dxhakj

MAX30102

用于可穿戴健康设备的高灵敏度脉搏血氧仪和心率传感器

主要特征

- LED反射方案中提供心率监测仪和脉搏血氧仪生物传感器(光电容积法)
- 微小、5.6mm x 3.3mm x 1.55mm、14引脚光模块
- 集成玻璃盖,实现最优、可靠的性能
- 使移动设备以极低功耗工作
- 可编程采样率和LED电流,节省功耗
- 低功耗心率监测仪(< 1mW)
- 超低关断电流(0.7µA,典型值)
- 快速数据输出
- 高采样率
- 可靠的运动伪影抑制
- 高SNR
- -40°C至+85°C工作温度范围

应用/用途

- 辅助健身设备
- 智能电话
- 平板电脑
- 可穿戴设备

FtJRH0MfvEaAglg2ae1xFJ59Mtd7

SSD1306 OLED 12864

OLED 屏幕作为一种新型的显示技术,其自身可以发光,亮度,对比度高,功耗低,在当下备受追捧。

该屏幕有 I2C 和 SPI 两种接口,这里使用 SPI 接口,并且使用了 u8g2 软件包。

软件

RT-Thread

MAX32660 目前已经移植到了 RT-Thread 上,我基于 RT-Thread 的 I2C 框架来控制 MAX30102,SPI 框架来控制 ssd1306 显示屏。

心率算法

我移植了 Arduino 里的 MAX30102 软件包,对接了其用 I2C 读写寄存器的接口。

static rt_bool_t maxim_max30102_write_reg(uint8_t uch_addr, uint8_t uch_data)
{
    uint8_t buf[2];
    struct rt_i2c_msg msg;
    rt_size_t err;

    buf[0] = uch_addr;
    buf[1] = uch_data;

    msg.addr = MAX30102_ADDR;
    msg.flags = RT_I2C_WR;
    msg.buf = buf;
    msg.len = ARRAY_SIZE(buf);

    if ((err = rt_i2c_transfer(i2c_bus, &msg, 1)) != 1)
    {
        LOG_E("I2c write failed (err: %d).", err);
        return RT_FALSE;
    }

    return RT_TRUE;
}
static rt_bool_t maxim_max30102_read_reg(uint8_t uch_addr, uint8_t *data, uint16_t len)
{
    RT_ASSERT(data);

    struct rt_i2c_msg msg_buf[2];
    rt_size_t err;

    msg_buf[0].addr  = MAX30102_ADDR;
    msg_buf[0].flags = RT_I2C_WR;
    msg_buf[0].buf   = &uch_addr;
    msg_buf[0].len   = 1;

    msg_buf[1].addr  = MAX30102_ADDR;
    msg_buf[1].flags = RT_I2C_RD;
    msg_buf[1].buf   = data;
    msg_buf[1].len   = len;

    if ((err = rt_i2c_transfer(i2c_bus, msg_buf, 2)) != 2)
    {
        LOG_E("I2c read failed (err: %d).", err);
        return RT_FALSE;
    }

    return RT_TRUE;
}

然后从 MAX30102 里读出来的数据是红光强度的 AD 值,我们利用这个 AD 值进行算法处理,得到我们最终的心率值。

心率算法采用的是前项差分动态阈值的方法,该心率算法的详细描述可参考:Maxim设计指南 | 基于前项差分和动态阈值的PPG心率测量算法。

这里列出一张我当时数据处理之后的图片,这里每一个波谷就代表一次心脏跳动。

FuScsCQX0MtxIH2Q8LqP-2dK1aFp

心率算法实现不算复杂,而且我已经做了一个 sensor 软件包贡献给 RT-Thread 了,内部集成了心率算法,直接使用就行,代码仓库为:https://github.com/Jackistang/max30102_rtt

RTC

我使用 RT-Thread 的软件 RTC 实现了时钟计数,在程序运行前设置系统时间,这里只是设置了一个初始值。

set_date(2021, 3, 21);
set_time(18, 20, 00);

然后再需要显示时钟字符串的时候,调用接口 `daytime()` 即可得到字符串。

#define DAYTIME_LEN 10
/**
 * @brief Get the format time Hour:Min:Sec from time_t.
 * @param time A pointer to timer_t.
 * @return Hour:Min:Sec format time string.
 */
char *daytime(time_t *time)
{
    static char buf[DAYTIME_LEN];
    int blank = 0, i = 0;
    char *t = ctime(time);
    while (*t != '\0' && i < DAYTIME_LEN) {
        if (*t == ' ')
            blank++;
        if (blank == 3) {
            buf[i++] = *t;
        }
        t++;
    }

    return buf;
}

now = time(NULL);
u8g2.setFont(u8g2_font_6x12_tf);
u8g2.drawStr(10, 10, daytime(&now));
u8g2.sendBuffer();

心得体会

十分感谢 Funpack 活动,感谢硬禾学堂和 Digi-Key ,我通过这期任务接触到了美信 MAX32660 这款优秀的开发板,也成功地挑战自己,利用 MAX30102 完成了心率测量的功能,收获颇多,十分感谢。

项目源代码太大,不能上传网址,所以放到网盘里了。

链接:https://pan.baidu.com/s/1wt0nK14F-82BPKIwrFFREA
提取码:5jhe
复制这段内容后打开百度网盘手机App,操作更方便哦

团队介绍
团队成员
Jackistang
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号