说到智能可穿戴产品,那么必不可少的功能应该就是蓝牙了吧!那么芯片必须带蓝牙功能,支持国产芯片,那么就上很火的ESP32吧!
一 、硬件选型和电路设计
本设计基于ESP32芯片,刚好使用上之前做项目学习用到的ESP32手环开发板——T_Wristband。 该开发板基于ESP32主芯片,板载tp4056锂电池充电管理芯片和50mAh锂电池,pcf8563时钟芯片,mpu9250多轴陀螺仪芯片,以及支持fpc接插座扩展外部传感器。
为了达到测量心率血氧的功能,选用了美信的MAX30102集成芯片。MAX30102是美信的一款用于可穿戴健康设备的高灵敏度脉搏血氧仪和心率传感器,传感器自带红光/红外光发射管和接收管,只需很少的外部器件便可完成心率血氧检测,为小型可穿戴产品的一个非常合适的传感器产品。
温度检测则选型了adi 的 adt7320高精度温度传感器。其参数和优点如下:
- 高性能
温度精度
±0.20°C:-10°C至+85°C
±0.25°C(-20°C至+105°C,3.3 V)
16位分辨率:0.0078℃
超低温漂:0.0073°C - 易于实现
用户无需校准或校正温度
无需线性校正 - 低功率
1 SPS(每秒采样率)省电模式
正常模式下为700 μW(3.3 V,典型值)
关断模式下为7 μW(3.3 V,典型值)
- 宽工作范围
工作温度范围:-40°C至+150°C
电压范围:2.7 V至5.5 V - 可编程中断
临界过温指示器
过温/欠温中断 - SPI兼容型接口
- 16引脚、4 mm × 4 mm LFCSP封装,符合RoHS标准
- 欲了解更多特性,请参考数据手册
在adt7320的电路设计中,为了兼容adt7420芯片,故在电路上设计了对I2C总线的上拉电阻,方便测试时更换芯片使用。
二、软件使用和程序编程
ESP32开发方式支持arduino 和 官方 ESP-IDF 软件,在易用性上,arduino更好,而且有众多的开源库的支持,让esp32开发体验更好。因此选择使用arduino进行程序开发。
arduino软件的安装和esp32开发板管理的设置就不在些赘述了,网上有太多的介绍。注意,根据开发板管理网址的更新,可能在选择开发板时 找不到对应的开发板型号,那么可以按以下图示中进行选择,只要在软件编程时不使用到板载芯片没有的功能,就能正常编程开发了。
软件开发需要使用到库支持,可以在库管理界面下载,也可以从网页下方的附件中下载后放置到arduino库所在文件夹,即可使用。
为什么使用库?因为使用库可以提高开发效率,当然如果你是大牛,自己写驱动库也是一样的,可以让程序功能更高效。
使用库开发的好处就在于,只需要再编写很少的程序,即可达到所想的功能。以下为max30102的心率读取程序示例。可以看到,短短几行,就已经完成了心率读取计算和OLED屏幕显示的功能了,简直不要太爽。(以下程序在附件里有,下载后可直接编译)
#include <TFT_eSPI.h> // Graphics and font library for ST7735 driver chip
#include <Wire.h>
#define LED_PIN 4
#define HEATRATE_SDA 15
#define HEATRATE_SCL 13
#define HEATRATE_INT 4
TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h
#include "MAX30105.h"
#include "heartRate.h"
MAX30105 particleSensor;
const uint8_t RATE_SIZE = 4; //Increase this for more averaging. 4 is good.
uint8_t rates[RATE_SIZE]; //Array of heart rates
uint8_t rateSpot = 0;
long lastBeat = 0; //Time at which the last beat occurred
float beatsPerMinute;
int beatAvg;
char buff[256];
void setup(void)
{
Serial.begin(115200);
tft.init();
tft.setRotation(1);
tft.setTextColor(TFT_GREEN, TFT_BLACK); // Note: the new fonts do not draw the background colour
tft.fillScreen(TFT_BLACK);
tft.setCursor(0, 0);
pinMode(LED_PIN, OUTPUT);
Wire1.begin(HEATRATE_SDA, HEATRATE_SCL);
// Initialize sensor
if (!particleSensor.begin(Wire1, 400000)) { //Use default I2C port, 400kHz speed
tft.setTextColor(TFT_RED, TFT_BLACK); // Note: the new fonts do not draw the background colour
tft.println("MAX30105 was not found");
delay(10000); //delay ten sec to restart
esp_restart();
}
particleSensor.setup(); //Configure sensor with default settings
particleSensor.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running
particleSensor.setPulseAmplitudeGreen(0); //Turn off Green LED
}
void loop()
{
long irValue = particleSensor.getIR();
if (checkForBeat(irValue) == true) {
//We sensed a beat!
long delta = millis() - lastBeat;
lastBeat = millis();
beatsPerMinute = 60 / (delta / 1000.0);
if (beatsPerMinute < 255 && beatsPerMinute > 20) {
rates[rateSpot++] = (uint8_t)beatsPerMinute; //Store this reading in the array
rateSpot %= RATE_SIZE; //Wrap variable
//Take average of readings
beatAvg = 0;
for (uint8_t x = 0 ; x < RATE_SIZE ; x++)
beatAvg += rates[x];
beatAvg /= RATE_SIZE;
}
}
tft.fillScreen(TFT_BLACK);
snprintf(buff, sizeof(buff), "IR=%lu BPM=%.2f", irValue, beatsPerMinute);
tft.drawString(buff, 0, 0);
snprintf(buff, sizeof(buff), "Avg BPM=%d", beatAvg);
tft.drawString(buff, 0, 16);
if (irValue < 50000)
digitalWrite(LED_PIN, 0);
else
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
}
adt7320的程序还在调试中,就先不贴出来了,等完成再跟大家分享。
开发板还板载了mpu9250多轴陀螺仪传感器(mpu9250已经停产,新设计不建议使用,可以使用LSM9DS1替代),可以作为计步和意外摔倒的检测,这些以后再跟大家分享。