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

Индикатор сердцебиения с использованием ЭКГ

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

устройство УЭКГ
× 1
Arduino Nano R3
× 1
Кольцо Adafruit NeoPixel:светодиод WS2812 5050 RGB
× 1
Литий-ионный аккумулятор 1000 мАч
× 1

Необходимые инструменты и машины

Паяльник (общий)

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

В течение многих лет я просто хотел сделать что-то со светодиодами, которые мигают в такт моему сердцебиению (и не только тогда, когда я остаюсь совершенно неподвижным и все же пропускаю удар здесь и там). Это оказалось на удивление сложно, я пытался и терпел неудачу годами. Но больше нет!

На самом деле вся тяжелая работа выполняется с помощью УЭКГ - небольшого носимого устройства ЭКГ с открытым исходным кодом и имеющего дружественный к Arduino выходной контакт (этот контакт переключается на высокий / низкий уровень с каждым ударом сердца). Обработка этих состояний контактов намного проще, чем обработка сигнала ЭКГ, и я попытался извлечь из этого максимальную пользу.
UPD:вы можете проверить 2-ю итерацию этого проекта, который получает данные по радиоканалу.

1. Схема
Поскольку здесь мы работаем только с цифровыми сигналами, это очень просто. Но как носимый он был бы намного надежнее (и меньше), если бы большинство соединений было припаяно - для быстрой проверки в этом нет необходимости, но если вы собираетесь носить его во время какой-либо тяжелой деятельности, я настоятельно рекомендую это.
Схема выглядит так:

  • Вывод DI светодиодного кольца подключается к выводу D11 (настраивается в коде).
  • Вывод DRV устройства uECG подключается к выводу D3 (также настраивается)
  • + аккумулятор идет на входы Arduino 5V и LED Ring 5V
  • Батарея - идет на Arduino GND, звонит GND и UECG GND.

Я использовал LiPo аккумулятор непосредственно в качестве входа 5V - нет ошибки, если вы подключите его к Vin - он не будет работать надежно (регулятор напряжения на Vin вызывает падение напряжения, и мы абсолютно не можем себе этого позволить). Дело в том, что Arduino работает стабильно, пока входное напряжение не опускается ниже 3,4 вольт. Батарея LiPo начинается с 4,2 В при полной зарядке и достигает 3,4 В только тогда, когда остается менее 15% заряда. Таким образом, с любым аккумулятором емкостью более ~ 200 мАч вы можете получить приличное время работы. Кроме этого, имейте в виду, что аккумулятор должен быть подключен через какой-нибудь, ну, разъем :) Потому что вы хотите отключить его от схемы и время от времени заряжать.

2. Код
Программа работает просто:она постоянно считывает вывод D3, а при обнаружении изменения помещает время этого изменения в массив из 20 элементов. Разница между первым и последним элементом, деленная на 20, представляет собой среднее время на удар (в миллисекундах). Таким образом, деление 1 минуты (60000 миллисекунд) на это число дает нам значение BPM. Вы можете настроить количество элементов в массиве. Меньшее количество элементов приведет к более быстрому отклику, но менее стабильным результатам (любая проблема с обнаружением биений приведет к большому скачку расчетного BPM). Чем больше количество элементов, тем более стабильные данные, но более медленный отклик при быстром изменении BPM.

Затем ВРМ отображается в цвете (синий-> зеленый-> желтый-> розовый-> красный, когда ВРМ идет от низкого к высокому) и количеству светодиодов:для 80 ударов в минуту горят восемь сегментов, для 110 - одиннадцать и т. Д. (масштаб также настраивается в коде).

  #include  
#ifdef __AVR__
#include
#endif
// Вывод DI кольца светодиода
#define PIN 11
// количество пикселей в кольце
#define NUMPIXELS 16
// входной контакт для подключения uECG
int in_pin =3;
Adafruit_NeoPixel Pixel =Adafruit_NeoPixel (NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup () {
pixels.begin (); // Это инициализирует библиотеку NeoPixel.
pinMode (in_pin, INPUT); // переводим вывод в режим ввода
digitalWrite (in_pin, 1); // включить PULLUP:это критично, uECG не имеет внутреннего подтягивания
}
// мы сохраняем последние 20 сердечных сокращений, чтобы усреднить BPM по ним
// с более высоким значением, это станет более надежным,
// но потребуется больше времени, чтобы увидеть изменение вывода при изменении BPM
#define BEAT_HIST 20
long beats [BEAT_HIST];
void push_beat (long мс) // сдвигаем все доли в массиве и вставляем текущую
{
for (int x =0; x {
beats [x] =beats [x + 1];
}
beats [BEAT_HIST-1] =ms;
}
int get_bpm () // с использованием разницы во времени между первой и последней долей
{
long dt =beats [BEAT_HIST-1] - beats [0];
long bpm =BEAT_HIST * 60000 / dt;
return bpm;
}
долго last_pix_upd =0; // чтобы отслеживать, когда мы обновляли пиксели в прошлый раз
int prev_in_state =0; // предыдущее состояние входного вывода:мы хотим обрабатывать только изменения состояния
void loop ()
{
long ms =millis ();
int in_state =digitalRead (in_pin ); // 1, если ритм не обнаружен, 0 в доле
if (in_state ==1 &&prev_in_state ==0) // реагируем только на изменение
{
push_beat (ms);
}
prev_in_state =in_state;
if (ms - last_pix_upd> 10) // не обновляйте пиксели слишком часто
{
int r, g, b;
last_pix_upd =ms;
int bpm =get_bpm ();
int max_bright =120; // значение максимальной яркости, max 255. Но вам не всегда нужно максимальное значение :)
float dd =20; // изменение BPM между цветовыми тонами (синий-> зеленый-> желтый-> розовый-> красный)
float t1 =90, t2, t3, t4; // t1 - "базовый" BPM, ниже t1 будет синий
t2 =t1 + dd;
t3 =t2 + dd;
t4 =t3 + dd;
/ / код для изменения цвета в зависимости от того, в каком диапазоне t1 ... t4 мы сейчас находимся
if (bpm иначе, если (уд / мин иначе, если (уд / мин иначе, если (уд / мин иначе {r =max_bright; г =0; b =0; }
if (in_state) // если не в доле, 1/4 интенсивности, поэтому выделяются только доли
{
r * =0,25;
g * =0,25;
b * =0,25;
}
int on_pixels =(bpm + 5) / 10; // количество используемых светодиодов:для 60 ударов в минуту будут гореть 6 светодиодов, для 120 - 12 и т. д.
for (int i =0; i {
if ( я }
pixels.show ();
}
}

3. Сборка как носимое устройство
Внутри кольца Arduino удобно размещать - она ​​практически идеально совпадает по размеру. Батарея тоже подходит рядом. Не забывайте, что УЭКГ кладется на грудь - значит, вам понадобится провод с разъемами, сначала вы его размещаете, затем надеваете рубашку с другими компонентами, а затем вставляете разъем. Иначе было бы очень неудобно надевать - поверьте, пробовал))

Вот и все - если все было сделано правильно, то через 30 секунд после подключения всех разъемов он начнет мигать и указывать BPM.

4. Полевые испытания
Я тестировал его при ходьбе и беге - и обнаружил, что во время бега батарея подпрыгивает прямо над датчиком ЭКГ, искажая его показания. Когда я немного сдвинул все это, оказалось, что провод, соединяющий УЭКГ с Ардуино, слишком короткий и он тянет датчик ЭКГ с каждым шагом, снова искажая показания. В целом, я получал надежные биения только при ходьбе и стоянии, но не при беге - но я думаю, что смогу это улучшить. Сам датчик, когда я использовал его с другой рубашкой, тоже правильно отображал BPM во время бега (проверено через его приложение).

Кроме того, оказывается, что светодиоды на груди могут выглядеть круто, но практически бесполезны. Смотреть вниз, чтобы проверить пульс, действительно неудобно. Думаю, в следующей итерации я сделаю какой-нибудь браслет на запястье, который будет показывать удары.

P.S. Если вас интересует проект uECG - вы можете проверить его домашнюю страницу, там много технических деталей, дизайнов печатных плат, обсуждения и логи проекта

Код

  • uECG_pixel_ring.ino
uECG_pixel_ring.ino Arduino
 #include  #ifdef __AVR__ #include  # endif // Вывод DI светодиодного кольца # определить PIN 11 // количество пикселей в кольце # определить NUMPIXELS 16 // ввод пин для подключения uECGint in_pin =3; Adafruit_NeoPixel пикселей =Adafruit_NeoPixel (NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); void setup () {pixels.begin (); // Это инициализирует библиотеку NeoPixel. pinMode (in_pin, ВХОД); // переводим вывод в режим ввода digitalWrite (in_pin, 1); // включить PULLUP:это критично, у ЭКГ нет внутреннего подтягивания} // мы сохраняем последние 20 сердечных сокращений, чтобы усреднить BPM по ним // с более высоким значением, это станет более надежным, // но это займет больше время увидеть изменение вывода при изменении BPM # define BEAT_HIST 20long beats [BEAT_HIST]; void push_beat (long ms) // сдвинуть все доли в массиве и вставить текущий {for (int x =0; x  10) // не обновляйте пиксели слишком часто {int r, g, b; last_pix_upd =мс; int bpm =get_bpm (); int max_bright =120; // значение максимальной яркости, max 255. Но вам не всегда нужно максимальное значение :) float dd =20; // изменение BPM между цветовыми тонами (синий-> зеленый-> желтый-> розовый-> красный) float t1 =90, t2, t3, t4; // t1 - "базовый" BPM, ниже t1 будет синий t2 =t1 + dd; t3 =t2 + dd; t4 =t3 + dd; // код для изменения цвета в зависимости от того, в каком диапазоне t1 ... t4 мы сейчас находимся if (bpm  

Схема


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

  1. Внешний дефибриллятор
  2. Скалка
  3. Искусственное сердце
  4. Искусственный клапан сердца
  5. Датчик движения с использованием Raspberry Pi
  6. Следите за температурой в доме с помощью Raspberry Pi
  7. Удаленный монитор сердечного ритма
  8. Система обеспечивает бесконтактный мониторинг сердечного ритма с помощью смарт-динамиков
  9. Электронная татуировка обеспечивает непрерывный мониторинг сердца в течение длительных периодов времени
  10. Понимание сустава сустава