电子发烧友App

硬声App

0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示
电子发烧友网>电子资料下载>电子资料>使用ECG的心跳指示器

使用ECG的心跳指示器

2023-02-08 | zip | 0.56 MB | 次下载 | 免费

资料介绍

描述

多年来,我只是想用 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 设计、讨论和项目日志


下载该资料的人也在下载 下载该资料的人还在阅读
更多 >

评论

查看更多

下载排行

本周

  1. 1山景DSP芯片AP8248A2数据手册
  2. 1.06 MB  |  532次下载  |  免费
  3. 2RK3399完整板原理图(支持平板,盒子VR)
  4. 3.28 MB  |  339次下载  |  免费
  5. 3TC358743XBG评估板参考手册
  6. 1.36 MB  |  330次下载  |  免费
  7. 4DFM软件使用教程
  8. 0.84 MB  |  295次下载  |  免费
  9. 5元宇宙深度解析—未来的未来-风口还是泡沫
  10. 6.40 MB  |  227次下载  |  免费
  11. 6迪文DGUS开发指南
  12. 31.67 MB  |  194次下载  |  免费
  13. 7元宇宙底层硬件系列报告
  14. 13.42 MB  |  182次下载  |  免费
  15. 8FP5207XR-G1中文应用手册
  16. 1.09 MB  |  178次下载  |  免费

本月

  1. 1OrCAD10.5下载OrCAD10.5中文版软件
  2. 0.00 MB  |  234315次下载  |  免费
  3. 2555集成电路应用800例(新编版)
  4. 0.00 MB  |  33566次下载  |  免费
  5. 3接口电路图大全
  6. 未知  |  30323次下载  |  免费
  7. 4开关电源设计实例指南
  8. 未知  |  21549次下载  |  免费
  9. 5电气工程师手册免费下载(新编第二版pdf电子书)
  10. 0.00 MB  |  15349次下载  |  免费
  11. 6数字电路基础pdf(下载)
  12. 未知  |  13750次下载  |  免费
  13. 7电子制作实例集锦 下载
  14. 未知  |  8113次下载  |  免费
  15. 8《LED驱动电路设计》 温德尔著
  16. 0.00 MB  |  6656次下载  |  免费

总榜

  1. 1matlab软件下载入口
  2. 未知  |  935054次下载  |  免费
  3. 2protel99se软件下载(可英文版转中文版)
  4. 78.1 MB  |  537798次下载  |  免费
  5. 3MATLAB 7.1 下载 (含软件介绍)
  6. 未知  |  420027次下载  |  免费
  7. 4OrCAD10.5下载OrCAD10.5中文版软件
  8. 0.00 MB  |  234315次下载  |  免费
  9. 5Altium DXP2002下载入口
  10. 未知  |  233046次下载  |  免费
  11. 6电路仿真软件multisim 10.0免费下载
  12. 340992  |  191187次下载  |  免费
  13. 7十天学会AVR单片机与C语言视频教程 下载
  14. 158M  |  183279次下载  |  免费
  15. 8proe5.0野火版下载(中文版免费下载)
  16. 未知  |  138040次下载  |  免费