Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Obtendo ECG em tempo real na tela OLED

Componentes e suprimentos

Arduino UNO
× 1
dispositivo uECG
× 1
Módulo nRF24 (genérico)
× 1
ElectroPeak 0.96 "Módulo de exibição OLED 64x128
× 1

Sobre este projeto





Algum tempo atrás eu postei alguns projetos demonstrando como obter dados de um dispositivo uECG - mas eles tinham uma grande quantidade de código confuso e ainda estavam usando apenas dados básicos dele. Então, finalmente, escrevi uma biblioteca Arduino que torna este caminho mais simples e muito mais confiável, aqui está:https://github.com/ultimaterobotics/uECG_library (observe que você também precisa instalar a biblioteca RF24 do Library Manager, e se você deseja mostrar dados em OLED como neste projeto - também a biblioteca SSD1306 da Adafruit).





1. Esquemas


Os esquemas são iguais aos de qualquer outro projeto que use o módulo nRF24 e OLED:o nRF24 é conectado ao barramento SPI do Arduino (D13, D12, D11) e dois pinos arbitrários para as linhas do módulo CS e CE - escolhi D10 e D9 por conveniência. O único ponto importante :o módulo nRF24 deve ser conectado a 3,3V linha, não para 5V! Também ajuda muito adicionar um capacitor de 1uF ou 10uF entre 3,3 V e GND - esses módulos nRF24 requerem uma tensão estável que o Arduino nem sempre pode fornecer em sua linha de 3,3 V, os capacitores ajudam nisso.

OLED é conectado via I2C - SDA a A4, SCL a A5 e alimentado por linha 5V. No meu caso, o módulo OLED tinha resistores embutidos para o protocolo I2C. Caso seu módulo não os tenha - você precisa adicionar resistores de 4,7k de SDA a 3,3 V e de SCL a 3,3 V, embora a maioria dos módulos que vi recentemente já os tenha.

Você pode ver os esquemas anexados abaixo, e aqui está uma foto do projeto montado:





2. Código


A biblioteca uECG leva algumas linhas de código para operação adequada, a saber:

em setup (), você precisa chamar uECG.begin (pin_cs, pin_ce) - você precisa dizer quais números de pinos são usados ​​para as linhas nRF24 CS e CE, ele ligará o módulo e o colocará no modo correto internamente.

Em loop (), você precisa chamar uECG.run () tão frequentemente quanto possível:o dispositivo uECG envia muitos dados - um pacote a cada poucos milissegundos - e se você não chamar uECG.run () na próxima vez pacote chega, seus dados serão perdidos. Isso significa nunca chamar a função delay () dentro do loop e usar millis () para tarefas que requerem tempo (adicionei um exemplo disso nos exemplos da biblioteca).

Este código de projeto está disponível como um exemplo dentro da biblioteca, e também está anexado abaixo (se parecer muito complexo - por favor, tenha em mente que aqui 95% do código é dedicado ao desenho de exibição otimizado, para valores simples de impressão em um monitor serial precisa de apenas algumas linhas):
  #include  
#include
#include

#define SCREEN_WIDTH 128 // OLED largura do display, em pixels
#define SCREEN_HEIGHT 64 // altura do display OLED, em pixels

// Declaração para um display SSD1306 conectado a I2C (SDA, pinos SCL)
# definir OLED_RESET -1 // Reinicializar o pino # (ou -1 se estiver compartilhando o pino de reinicialização do Arduino)
Tela Adafruit_SSD1306 (SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

int rf_cen =9; // pino de habilitação do chip nRF24
int rf_cs =10; // pino CS nRF24

void setup () {
Serial.begin (115200); // saída serial - muito útil para depuração
while (! display.begin (SSD1306_SWITCHCAPVCC, 0x3C)) {// Endereço 0x3D para 128x64
Serial.println (F ("SSD1306 alocação falhou"));
}
display.display ();
atraso (100);
uECG.begin (rf_cs, rf_cen);
atraso (100);

// Limpa o buffer
display.clearDisplay ();
display.setTextSize (1); // Escala normal de 1:1 pixel
display.setTextColor (WHITE); // Desenhe texto branco
display.cp437 (true); // Usar fonte completa de 256 caracteres da 'Página de código 437'
display.display ();
delay (100);
Serial.println ("após exibição");
}

uint32_t prev_data_count =0;
uint32_t prev_displ =0;

uint8_t ecg_screen [128];
int ecg_screen_len =128;
flutuante 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_data [x];
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 ( "etapas:");
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, BRANCO);
display.drawLine (110, 10, 127, 10, WHITE);
display.drawLine ( 110, 0, 110, 10, BRANCO);
display.drawLine (127, 0, 127, 10, BRANCO);
int bat_len =batt_perc / 6;
para (int x =1; x <10; x ++)
display.drawLine (110, x, 110 + bat_len, x, WHITE);
}
if (displ_phase ==1)
{
para ( int x =1; x display.drawLine (x-1, ecg_screen [x-1], x, ecg_screen [x], BRANCO);
}
if (displ_phase ==2)
{
for (int x =ecg_screen_len / 2; x display.drawLine (x-1, ecg_screen [x- 1], x, ecg_screen [x], BRANCO);
}
if (displ_phase ==3)
display.display ();
displ_phase ++;
if (displ_phase> 3) displ_phase =0;
}
}
}





3. Processando dados


Muito processamento é realizado a bordo e você pode obter várias estatísticas calculadas pelo dispositivo:BPM, GSR, último intervalo RR, parâmetro HRV e 16 bins HRV (o primeiro bin representa a quantidade de batimentos com variação <1%, segundo bin - variação entre 1 e 2% etc.), número de passos percorridos, leituras do acelerômetro (embora a taxa de atualização seja baixa, por isso é bom apenas para estimativa de pose).

Mas você também pode obter leituras de ECG brutas - o fluxo de dados não é perfeito, de vez em quando alguns pacotes são perdidos, mas você ainda pode obter algo utilizável:

Bem, é isso - se você tivesse este dispositivo acumulando poeira em um canto, agora ele realmente funciona sem muitos problemas :)

Código

biblioteca uECG arduino
Possui OLED e exemplos seriais simples emhttps://github.com/ultimaterobotics/uECG_library

Esquemas


Processo de manufatura

  1. Maxim:módulo biossensor PPG e ECG integrado para dispositivos móveis
  2. API do sensor ambiental com um RPi
  3. Introdução ao TJBot
  4. Módulo Verilog
  5. Parâmetros Verilog
  6. Java 9 - Sistema de Módulos
  7. Jogo Arduino Pong - Tela OLED
  8. Arduino e autômatos celulares baseados em OLED
  9. Dodge The Defs!
  10. Arduino Tutorial 01:Começando