Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Получение ЭКГ в реальном времени на OLED-экране

Компоненты и расходные материалы

Arduino UNO
× 1
устройство УЭКГ
× 1
Модуль nRF24 (общий)
× 1
ElectroPeak 0.96 "OLED-дисплей 64x128"
× 1

Об этом проекте


Некоторое время назад я опубликовал несколько проектов, демонстрирующих, как получить данные с устройства УЭКГ, но в них было довольно много запутанного кода, и они по-прежнему использовали только базовые данные из него. Итак, наконец, я написал библиотеку Arduino, которая делает этот способ более простым и надежным, вот она:https://github.com/ultimaterobotics/uECG_library (обратите внимание, что вам также необходимо установить библиотеку RF24 из диспетчера библиотек, и если вы хотите показать данные на OLED, как в этом проекте - также библиотека Adafruit SSD1306).

1. Схема

Схема такая же, как и для любого другого проекта, использующего модуль nRF24 и OLED:nRF24 подключен к шине SPI Arduino (D13, D12, D11) и двум произвольным контактам для линий модуля CS и CE - я выбрал D10 и D9 для удобства. Единственный важный момент :модуль nRF24 должен быть подключен к 3,3 В линия, а не до 5В! Также очень помогает добавление конденсатора 1 мкФ или 10 мкФ между 3,3 В и заземлением - этим модулям nRF24 требуется стабильное напряжение, которое Arduino не всегда может обеспечить на своей линии 3,3 В, в этом помогают конденсаторы.

OLED подключается через I2C - SDA к A4, SCL к A5 и питается от линии 5 В. В моем случае OLED-модуль имел встроенные резисторы для протокола I2C. Если в вашем модуле их нет - вам нужно добавить резисторы 4,7 кОм от SDA до 3,3 В и от SCL до 3,3 В, хотя в большинстве модулей, которые я видел недавно, они уже есть.

Вы можете увидеть прилагаемые ниже схемы, а также фото собранного проекта:

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 // Сбросить контакт № (или -1, если используется общий вывод сброса Arduino)
Отображение Adafruit_SSD1306 (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 для 128x64
Serial.println (F («Ошибка выделения SSD1306»));
}
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-символьный шрифт 'Code Page 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);
для (int x =0; x Serial.println (ecg_data [x]);

для (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;
если (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, БЕЛЫЙ);
display.drawLine (110, 10, 127, 10, БЕЛЫЙ);
display.drawLine ( 110, 0, 110, 10, БЕЛЫЙ);
display.drawLine (127, 0, 127, 10, БЕЛЫЙ);
int bat_len =batt_perc / 6;
for (int x =1; х <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], БЕЛЫЙ);
}
if (displ_phase ==2)
{
for (int x =ecg_screen_len / 2; x display.drawLine (x-1, ecg_screen [x- 1], x, ecg_screen [x], БЕЛЫЙ);
}
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
Имеет OLED и простые серийные примеры внутри https://github.com/ultimaterobotics/uECG_library

Схема


Производственный процесс

  1. Maxim:интегрированный модуль биосенсора PPG и ЭКГ для мобильных устройств
  2. API датчика окружающей среды с RPi
  3. Начало работы с TJBot
  4. Верилог-модуль
  5. Параметры Verilog
  6. Java 9 — модульная система
  7. Игра Arduino Pong - OLED-дисплей
  8. Клеточные автоматы на основе Arduino и OLED
  9. Уклоняйся от защиты!
  10. Учебник по Arduino 01:Начало работы