×

使用ECG的心跳指示器

消耗积分:0 | 格式:zip | 大小:0.56 MB | 2023-02-08

韩刚龙

分享资料个

描述

多年来,我只是想用 LED 做一些能随着我的心跳而闪烁的东西(不仅是当我完全静止不动,但有时会时不时地跳一下)。事实证明这出奇地困难,我尝试了很多年但都失败了。但现在不是了!

实际上,所有繁重的工作都是由uECG完成的——一种小型可穿戴 ECG 设备,它是开源的,并且有一个 Arduino 友好的输出引脚(该引脚随着每次心跳而变高/变低)。处理这些引脚状态比处理 ECG 信号要容易得多,而且我已经尽力从中获得最大收益。
UPD:你可能想检查这个项目的第二次迭代,它通过无线电链路接收数据。

1. 原理图
由于我们这里只使用数字信号,所以非常简单。但作为可穿戴设备,如果大多数连接都是焊接的,它会更可靠(也更小)——对于快速测试来说,没有必要这样做,但如果你打算在一些繁重的活动中佩戴它,我强烈建议这样做。
示意图如下所示:

 
pYYBAGPi-FWAdnl0AAFSlvJRmHM499.png
 
  • LED 环的 DI 引脚连接到引脚 D11(可在代码中配置)
  • uECG 设备的 DRV 引脚连接到引脚 D3(也可配置)
  • 电池的 + 连接到 Arduino 5V 和 LED 环形 5V 输入
  • 电池 - 连接到 Arduino GND、环形 GND 和 uECG 的 GND

我直接使用 LiPo 电池作为 5V 输入 - 没有错误,如果你将它连接到 Vin - 它不会可靠地工作(Vin 上的稳压器会引入电压降,我们在这里绝对买不起)。问题是,只要输入电压不低于 3.4 伏,Arduino 就是稳定的。LiPo 电池在充满电时的起始电压为 4.2 伏,仅当剩余电量少于 15% 时才达到 3.4 伏。因此,对于任何大于 ~200 mAh 的电池,您可以获得不错的运行时间。除此之外,请记住电池应该通过一些连接器连接 :) 因为你想将它从原理图上断开并偶尔充电一次。

2. 代码
该程序以一种简单的方式工作:它不断读取 D3 引脚,并在检测到变化时 - 将该变化的时间推入 20 元素数组。第一个和最后一个元素之间的差值除以 20,即为每次节拍的平均时间(以毫秒为单位)。因此,将 1 分钟(60000 毫秒)除以该数字即可得出 BPM 值。您可以调整数组中的元素数量。较少数量的元素会导致更快的响应,但结果不太稳定(节拍检测中的任何问题都会导致计算出的 BPM 大幅跳跃)。更多的元素会提供更稳定的数据,但当 BPM 快速变化时响应更慢。

然后将 BPM 映射到颜色(当 BPM 从低到高时,蓝色->绿色->黄色->粉红色->红色),并映射到 LED 的数量:80 BPM 八段亮起,110 - 11 等等(比例也可在代码中调整)。

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
// DI pin of LED ring
#define PIN            11
// number of pixels in the ring
#define NUMPIXELS      16
// input pin for connecting uECG
int in_pin = 3;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
pixels.begin(); // This initializes the NeoPixel library.
pinMode(in_pin, INPUT); //set pin to input mode
digitalWrite(in_pin, 1); //enable PULLUP: this is critical, uECG doesn't have internal pull-up
}
//we store last 20 heartbeats to averge BPM over them
//with higher value, it will become more reliable,
//but it will take more time to see output change when BPM changes
#define BEAT_HIST 20
long beats[BEAT_HIST];
void push_beat(long ms) //shift all beats in array and insert current one
{
for(int x = 0; x < BEAT_HIST-1; x++)
{
beats[x] = beats[x+1];
}
beats[BEAT_HIST-1] = ms;
}
int get_bpm() //using time difference between first and last beats
{
long dt = beats[BEAT_HIST-1] - beats[0];
long bpm = BEAT_HIST * 60000 / dt;
return bpm;
}
long last_pix_upd = 0; //to keep track of when we updated pixels previous time
int prev_in_state = 0; //previous state of input pin: we want to process only changes of state
void loop()
{
long ms = millis();
int in_state = digitalRead(in_pin); //1 when no beat detected, 0 in beat
if(in_state == 1 && prev_in_state == 0) //react only to change
{
push_beat(ms);
}
prev_in_state = in_state;
if(ms - last_pix_upd > 10) //don't update pixels too often
{
int r, g, b;
last_pix_upd = ms;
int bpm = get_bpm();
int max_bright = 120; //value of maximum brightness, max 255. But you don't always want it at max :)
float dd = 20; //change in BPM between color tones (blue->green->yellow->pink->red)
float t1 = 90, t2, t3, t4; //t1 - "base" BPM, lower than t1 would be blue
t2 = t1 + dd;
t3 = t2 + dd;
t4 = t3 + dd;
//code for changing color depending in which t1...t4 range we are now
if(bpm < t1){ r = 0; g = 0; b = max_bright; }
else if(bpm < t2) { r = 0; g = max_bright * (bpm-t1)/dd; b = max_bright - g; }
else if(bpm < t3) { r = max_bright * (bpm-t2)/dd; g = max_bright - r; b = r/4; }
else if(bpm < t4) { r = max_bright; g = 0; b = max_bright/2 - max_bright * (bpm-t3)/(2*dd); }
else {r = max_bright; g = 0; b = 0; }
if(in_state) //when not in beat, 1/4 intensity, so only beats are highlighted
{
r *= 0.25;
g *= 0.25;
b *= 0.25;
}
int on_pixels = (bpm+5)/10; //number of used LEDs: for 60 BPM, 6 LEDs will be on, for 120 - 12 etc
for(int i=0;i<NUMPIXELS;i++)
{
if(i < on_pixels) pixels.setPixelColor(i, pixels.Color(r,g,b));
else pixels.setPixelColor(i, pixels.Color(0,0,0)); //turn off all other LEDs
}
pixels.show();
}
}

3. 组装成可穿戴设备
将 Arduino 放在环内很方便 - 它的尺寸几乎完美匹配。电池也适合附近。不要忘记 uECG 是放在胸部上的——因此您需要一根带连接器的电线,首先放置它,然后穿上带有其他组件的衬衫,然后插入连接器。否则戴上它真的很不方便-相信我,我试过了))

 
pYYBAGPi-ImAJ5blAAlxQ5SW6zs489.jpg
所有组件到位
 
 
poYBAGPi-I2AIfaqAAF3Ff8hFR4918.jpg
我只是从里面把所有东西都粘在衬衫上
 

基本上就是这样 - 如果一切都正确完成,在您插入所有连接器后的 30 秒内,它将开始闪烁并指示 BPM。

4. 现场测试
我在步行和跑步时对其进行了测试 - 发现在跑步过程中,电池会在 ECG 传感器上方反弹,从而扭曲其读数。当我稍微移动它时,结果发现连接 uECG 和 Arduino 的电线太短,每一步都会拉动 ECG 传感器,再次扭曲读数。总的来说,我只有在行走和站立时才能获得可靠的节拍,但在跑步时却不行——但我认为我会改进这一点。传感器本身,当我将它与不同的衬衫一起使用时,在运行期间也能正确显示 BPM(通过其应用程序检查)。

此外,事实证明,胸部上的 LED 看起来很酷,但实际上毫无用处。低头看脉真的很不方便。我想在下一次迭代中,我会制作某种可以指示节拍的腕带。

PS 如果你对 uECG 项目感兴趣——你可以查看它的hackaday 页面,那里有很多技术细节、PCB 设计、讨论和项目日志


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !