亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

在 OLED 屏幕上获取实时心电图

组件和用品

Arduino UNO
× 1
uECG 设备
× 1
nRF24 模块(通用)
× 1
ElectroPeak 0.96" OLED 64x128 显示模块
× 1

关于这个项目


前段时间我发布了几个项目,展示了如何从 uECG 设备获取数据 - 但它们有很多凌乱的代码,并且仍然只使用其中的基本数据。所以最后我写了一个 Arduino 库,使这种方式更简单,更可靠,这里是:https://github.com/ultimaterobotics/uECG_library(请注意,您还需要从库管理器安装 RF24 库,如果您想要像在这个项目中一样在 OLED 上显示数据 - 也是 Adafruit 的 SSD1306 库)。

1. 原理图

原理图与使用 nRF24 模块和 OLED 的任何其他项目相同:nRF24 连接到 Arduino 的 SPI 总线(D13、D12、D11)和用于模块 CS 和 CE 线的两个任意引脚 - 为了方便,我选择了 D10 和 D9。唯一的重点 :nRF24 模块必须连接到 3.3V 线,不要到5V!在 3.3V 和 GND 之间添加 1uF 或 10uF 电容器也有很大帮助 - 这些 nRF24 模块需要稳定的电压,而 Arduino 无法始终在其 3.3V 线路上提供,电容器对此有帮助。

OLED 通过 I2C - SDA 连接到 A4,SCL 连接到 A5,并由 5V 线路供电。就我而言,OLED 模块具有用于 I2C 协议的内置电阻器。如果您的模块没有它们 - 您需要添加 4.7k 电阻从 SDA 到 3.3V 和从 SCL 到 3.3V,尽管我最近看到的大多数模块已经有了。

您可以在下面看到原理图,这是组装项目的照片:

2.代码

uECG 库需要相当多的代码才能正常运行,即:

在 setup() 中,您需要调用 uECG.begin(pin_cs, pin_ce) - 您需要告诉它哪些引脚号用于 nRF24 CS 和 CE 线,它将打开模块并将其置于内部正确的模式。

在 loop() 中,您需要尽可能频繁地调用 uECG.run():uECG 设备发送大量数据 - 每几毫秒发送一个数据包 - 如果您在下一次之前不调用 uECG.run()数据包到达,其数据将丢失。这意味着永远不要在循环内调用 delay() 函数,并且对需要计时的任务使用millis()(我在库示例中添加了一个示例)。

此项目代码可用作库中的示例,也附在下面(如果它看起来太复杂 - 请记住,这里 95% 的代码专门用于优化显示绘图,用于将简单的值打印到串行监视器中只需要几行):

#include 
#include
#include

#define SCREEN_WIDTH 128 // OLED显示宽度,以像素为单位
#define SCREEN_HEIGHT 64 // OLED 显示高度,以像素为单位

// SSD1306 显示器连接到 I2C(SDA、SCL 引脚)的声明
#定义 OLED_RESET -1 // 重置引脚 #(如果共享 Arduino 重置引脚,则为 -1)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

int rf_cen =9; //nRF24芯片使能引脚
int rf_cs =10; //nRF24 CS 引脚

void setup() {
Serial.begin(115200); //串行输出——对调试非常有用
while(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // 地址0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
}
display.display();
delay(100);
uECG.begin(rf_cs, rf_cen);
delay(100);

// 清除缓冲区
display.clearDisplay();
display.setTextSize(1); // 普通 1:1 像素比例
display.setTextColor(WHITE); // 绘制白色文本
display.cp437(true); // 使用完整的 256 字符“代码页 437”字体
display.display();
delay(100);
Serial.println("after display");
}

uint32_t prev_data_count =0;
uint32_t prev_displ =0;

uint8_t ecg_screen[128];
int ecg_screen_len =128;
float ecg_avg =0;
float ecg_max =1;
float ecg_min =-1;
int ecg_size =40;

int displ_phase =0;

void loop()
{
uECG.run();
uint32_t data_count =uECG.getDataCount();
int new_data =data_count - prev_data_count;
prev_data_count =data_count;
if(new_data> 0)
{
uint32_t ms =millis();
int16_t ecg_data[8];
uECG.getECG(ecg_data, new_data);
for(int x =0; x Serial.println(ecg_data[x]);

for(int x =new_data; x ecg_screen[x-new_data] =ecg_screen[x];
for(int x =0; x {
ecg_avg *=0.99;
ecg_avg +=0.01*ecg_data[x];
ecg_max =ecg_max*0.995 + ecg_avg*0.005;
ecg_min =ecg_min*0.995 + ecg_avg*0.005;
if(ecg_data[x]> ecg_max) ecg_max[/>] ecg; if(ecg_data[x] int ecg_y =63-ecg_size*(ecg_data[x] - ecg_min) / (ecg_max - ecg_min + 1);
ecg_screen[ ecg_screen_len-1-new_data+x] =ecg_y;
}

if(ms - prev_displ> 30)
{
prev_displ =ms;
if (displ_phase ==0)
{
display.clearDisplay();
display.setCursor(0, 0);
display.print("BPM:");
display.println(uECG.getBPM());
display.print(" RR:");
display.println(uECG.getLastRR());
display.print( "步骤:");
display.print(uECG.getSteps());
int batt_mv =uECG.getBattery();
int batt_perc =(batt_mv - 3300)/8;
if(batt_perc <0) batt_perc =0;
if(batt_perc> 100) batt_perc =100;
display.drawLine(110, 0, 127, 0, WHITE);
display.drawLine(110, 10, 127, 10, WHITE);
display.drawLine( 110, 0, 110, 10, WHITE);
display.drawLine(127, 0, 127, 10, WHITE);
int bat_len =batt_perc / 6;
for(int x =1; x <10; x++)
display.drawLine(110, x, 110+bat_len, x, WHITE);
}
if(displ_phase ==1)
{
for( int x =1; x display.drawLine(x-1, ecg_screen[x-1], x, ecg_screen[x], WHITE);
}
if(displ_phase ==2)
{
for(int x =ecg_screen_len/2; x display.drawLine(x-1, ecg_screen[x- 1], x, ecg_screen[x], WHITE);
}
if(displ_phase ==3)
display.display();
displ_phase++;
if (displ_phase> 3) displ_phase =0;
}
}
}

3. 处理数据

大量处理在机上执行,您可以获得设备计算的各种统计数据:BPM、GSR、上次 RR 间隔、HRV 参数和 16 个 HRV 区间(第一个区间表示变化 <1% 的节拍量,第二个区间 - 1% 和 2% 之间的变化等)、行走的步数、加速度计读数(虽然刷新率很低,所以它只适用于姿态估计)。

但是您也可以获得原始心电图读数 - 数据流并不完美,时不时会丢失一些数据包,但您仍然可以获得一些可用的东西:

好吧,就是这样 - 如果你有这个设备在角落里收集灰尘,现在它实际上工作起来没有太多麻烦:)

代码

uECG arduino 库
里面有OLED和简单的串口例子https://github.com/ultimaterobotics/uECG_library

示意图


制造工艺

  1. Maxim:用于移动设备的集成 PPG 和 ECG 生物传感器模块
  2. 带有 RPi 的环境传感器 API
  3. TJBot 入门
  4. Verilog 模块
  5. Verilog 参数
  6. Java 9 - 模块系统
  7. Arduino Pong Game - OLED 显示器
  8. JX 波形发生器
  9. DIY 虚拟现实滑板
  10. 基于 Arduino 和 OLED 的元胞自动机
  11. Dodge The Defs!
  12. Arduino教程01:入门