산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

심박수 모니터(ECG를 사용하는 웨어러블 및 무선)

구성품 및 소모품

uECG 장치
실제 BPM 측정용. nRF24 호환 프로토콜을 통해 데이터를 보낼 수 있습니다.
× 1
Arduino Nano R3
× 1
nRF24 모듈(일반)
모든 모듈이 여기에서 작동합니다. uECG에서 BPM 데이터를 수신하는 데 필요
× 1
Adafruit NeoPixel 링:WS2812 5050 RGB LED
× 1
LiPo 배터리
200mAh 용량 이상의 모든 배터리
× 1

필요한 도구 및 기계

납땜 인두(일반)

이 프로젝트 정보

이것은 내 심장 모니터링 프로젝트의 두 번째 반복입니다. 이전 프로젝트는 가슴에서 심장 박동을 보여주고 유선을 통해 uECG에 연결되었습니다. 멋져 보이지만 전혀 실용적이지 않습니다. 현재 정확히 몇 개의 LED가 켜져 있는지 잘 알 수 없고, 일반적인 시야 범위를 벗어납니다. uECG 장치에 와이어를 연결하면 센서 자체에 많은 문제가 발생합니다. , 따라서 실행하면 기본적으로 작동하지 않습니다.

이 버전은 이러한 모든 문제를 해결합니다. 손목에 착용하여 도로에서 눈을 떼지 않고 볼 수 있으며 무선이므로 판독값의 왜곡이 없으며 달리기에 실제로 작동하고 심장 부하를 추적할 수 있습니다.

1. 구성 요소

이전 프로젝트와 마찬가지로 모든 힘든 작업은 uECG에 의해 수행됩니다. uECG는 데이터를 측정하고 온보드 BPM을 계산합니다. 또한 직접 링크 모드로 전환되면 일반 nRF24 칩과 호환되는 무선 프로토콜을 통해 이 모든 정보(여기에서 사용하지 않는 고해상도 ECG 데이터와 함께)를 보냅니다. 따라서 두 번째 중요한 구성 요소는 nRF24 모듈입니다. 그리고 Arduino Nano는 작은 LED 링 아래에 딱 맞는 크기를 가지고 있어 컨트롤러로 사용하고 있습니다.

2. 회로도

nRF24 모듈을 연결하는 것은 간단하지 않습니다. 모든 SPI 와이어(MISO, MOSI, SCK, CS)와 칩 인에이블 와이어 및 전원 공급 장치를 연결해야 합니다. 그리고 합리적으로 작은 크기를 원한다면 모든 핀 헤더를 제거하고 와이어를 패드에 직접 납땜해야 합니다. 따라서 nRF만 연결하려면 7개의 와이어, 14개의 납땜 지점이 필요합니다. 좋은 소식은 다른 모든 것이 간단하다는 것입니다. LED 링에는 1개의 데이터 와이어와 2개의 전원 와이어가 필요하고 또 다른 2개의 전원 와이어는 배터리 커넥터에 연결됩니다.

연결 목록은 다음과 같습니다.
nRF24 핀 1(GND) - Arduino의 GND
nRF24 핀 2(Vcc) - Arduino의 3.3v
nRF24 핀 3(Chip Enable) - Arduino의 D9
nRF24 핀 4(SPI:CS) - Arduino의 D8
nRF24 핀 5(SPI:SCK) - Arduino의 D13
nRF24 핀 6(SPI:MOSI) - Arduino의 D11
nRF24 핀 7( SPI:MISO) - Arduino의 D12
LED 링 전원 - Arduino의 5V
LED 링 GND - Arduino의 GND
LED 링 DI - Arduino의 D5
배터리 포지티브(빨간색) - Arduino의 5V
배터리 네거티브(검은색) - Arduino의 GND
(배터리에는 커넥터가 필요하므로 연결을 끊고 충전할 수 있음)

중요 사항:MOSI, MISO, SCK 와이어는 다른 Arduino 핀에 연결할 수 없습니다. SPI 하드웨어는 D11, D12, D13에 있으며 거기에 연결되어 있지 않으면 작동하지 않습니다. 다른 모든 핀은 변경할 수 있습니다(프로그램에서 해당 변경을 수행하는 경우).

3. 프로그램

여기에서 소프트웨어에 대한 유일한 복잡한 것은 RF 채널 구성입니다. 나는 uECG와 nRF24가 파이프 주소에 다른 비트 순서를 사용한다는 것을 깨닫기 전에 그것을 작동시키려고 꽤 오랜 시간을 보냈습니다. 내가 그것을 고쳤을 때 모든 것이 즉시 작동하기 시작했습니다 :) 기본적으로 우리는 들어오는 패킷을 읽고 5번째 바이트를 BPM으로 사용하고 필터링합니다(RF 채널은 잡음이 있으므로 때때로 올바른 읽기 대신 임의의 값을 얻습니다. 하드웨어 CRC는 호환성을 위해 비활성화됨). 그 후 BPM은 색상과 활성 픽셀 수로 변환됩니다.

#include 
#ifdef __AVR__
#include
#endif
#include
#include
#include
#include
int rf_cen =9; //nRF24 칩 활성화 핀
int rf_cs =8; //nRF24 CS 핀
RF24 rf(rf_cen, rf_cs);
//파이프 주소 - uECG 측에 하드코딩됨
uint8_t pipe_rx[8] ={0x0E, 0xE6, 0x0D, 0xA7, 0 , 0, 0, 0};
// Arduino의 어떤 핀이 NeoPixels에 연결되어 있나요?
#define PIN 5
// Arduino에 연결된 NeoPixels는 몇 개인가요?
#define NUMPIXELS 16
Adafruit_NeoPixel 픽셀 =Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
uint8_t swapbits(uint8_t a){ //uECG 파이프 주소는 스왑된 비트 순서를 사용합니다.
uint8_t v =0;
if(a &0x80) v |=0x01;
if(a &0x40) v |=0x02;
if(a &0x20) v |=0x04;
if(a &0x10) v |=0x08;
if(a &0x08) v |=0x10;
if(a &0x04) v |=0x20;
if(a &0x02) v |=0x40;
if(a &0x01) v |=0x80;
반환 v;
}
무효 설정() {
pixels.begin(); // NeoPixel 라이브러리를 초기화합니다.
for(int i=0;ipixels.setPixelColor(i,pixels.Color(1,1,1));
}
pixels.show();
//nRF24는 비교적 느린 SPI가 필요하며 2MHz에서도 작동할 수 있습니다.
SPI.begin();
SPI.setBitOrder(MSBFIRST );
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
for(int x =0; x <8; x++) //nRF24와 uECG는 파이프 주소의 비트 순서가 다릅니다
pipe_rx[x] =swapbits(pipe_rx[x]);
//무선 매개변수 구성
rf.begin();
rf.setDataRate(RF24_1MBPS);
rf.setAddressWidth(4);
rf.setChannel(22);
rf.setRetries(0, 0);
rf.setAutoAck(0);
rf.disableDynamicPayloads( );
rf.setPayloadSize(32);
rf.openReadingPipe(0, pipe_rx);
rf.setCRCLength(RF24_CRC_DISABLED);
rf.disableCRC();
rf.startListening(); //uECG 데이터 수신
//uECG는 원시 데이터 모드로 전환되어야 합니다(긴 버튼 누름)
//호환 가능한 패킷을 보내려면 기본적으로 BLE 모드로 데이터를 보냅니다
//nRF24에서 수신할 수 없음
}
long last_pix_upd =0;
byte in_pack[32];
int rf_bpm =0;
int bpm_hist [5]; //CRC를 비활성화했기 때문에 들어오는 데이터를 필터링해야 합니다.
void loop()
{
if(rf.available())
{
rf.read( in_pack, 32);
int bb =in_pack[5]; //BPM은 패킷의 5번째 바이트에 있습니다.
//자세한 패킷 구조는 uECG 문서에 있습니다.
//호환성을 위해 CRC가 없으므로 필터링해야 합니다.
// 들어오는 데이터, 라디오 채널에 잡음이 있을 수 있습니다. 우리는 마지막 5개
//수신된 BPM 값을 비교하고 5개가 모두 동일한 경우에만 하나를 사용합니다.
//uECG는 초당 약 100개의 패킷을 보내기 때문에 발생하지 않습니다.
// 데이터 표시에서 눈에 띄는 지연
for(int n =0; n <5-1; n++) //bpm 기록 배열을 1만큼 이동
bpm_hist[n] =bpm_hist[n+1];
bpm_hist[4] =bb; //새 bpm 값 추가
for(int n =0; n <5; n++) //모두 동일한지 확인
if(bpm_hist[n] !=bb) bb =-1;
if(bb> 0) //예인 경우 - 새로 수신된 BPM으로 저장
rf_bpm =bb;
}
long ms =millis();
if( ms - last_pix_upd> 10) //픽셀을 너무 자주 업데이트하지 마십시오.
{
int r, g, b;
last_pix_upd =ms;
int bpm =rf_bpm;
float dd =25; //색조 간의 BPM 변화(파랑->초록->노랑->분홍->빨강)
float t1 =90, t2, t3, t4; //t1 - "기본" BPM, t1보다 낮으면 파란색
t2 =t1 + dd;
t3 =t2 + dd;
t4 =t3 + dd;
/ /현재 t1...t4 범위에 따라 색상을 변경하는 코드
if(bpm else if(bpm else if(bpm else if(bpm 그 외 {r =max_bright; g =0; b =0; }
int on_pixels =(bpm-80)/8; //실행을 위한 것이기 때문에
//80BPM 미만을 표시하지 않습니다. 이렇게 하면 부하가 높은 영역에서 더 민감합니다.
for(int i=0;i{
//픽셀은 특별한 이유 없이 마지막에서 처음으로 설정됩니다.
//첫 번째에서 마지막으로 설정해도 잘 작동합니다.
if(i elsepixels.setPixelColor(NUMPIXELS-i-1,pixels.Color(0, 0,0)); //다른 모든 LED 끄기
}
pixels.show();
}
}

4. 팔찌 조립

모든 전선이 납땜되면 프로그램이 깜박이고 uECG 데이터가 수신되었음을 확인했습니다. 이제 모든 것을 함께 가져올 시간입니다.

나는 그것을 모두 함께 고정하는 매우 간단한 방법인 열 접착제를 선택했습니다. 부품 자체가 이미 거의 맞기 때문에(Nano는 외부 링 크기에 맞고 nRF24 모듈은 내부 링 크기에 맞고 배터리는 어떤 부품에도 맞지 않지만 어떻게든 방해가 되지 않습니다. 작동 방식을 잘 모르겠지만 그냥 붙였습니다. 거기에 있었고 어떻게 든 괜찮 았습니다 :) 그런 다음 손에 들고 있던 임의의 팔찌 (납땜 스테이션 팩에서 남은 것, 납땜하는 동안 접지에 사용되는 밴드)에 꿰매 었습니다. 그게 다입니다!

5. 테스트

테스트를 위해 실행에 갔고 한 가지 놀라움을 제외하고는 잘 작동했습니다. 나는 192BPM에서 모든 LED가 켜져 있는 설정을 사용했는데, 모든 권장 사항에 따르면 이러한 심박수가 내 매개변수에 비해 너무 높기 때문입니다. 놀랍게도 나는 그것을 눈치채지 못한 채 단 몇 분 만에 그것을 초과했습니다. 나는 그것이 센서 오류 일 수 있다고 생각했지만 아니요. 멈추었을 때 즉시 떨어지지 않고 천천히 이완되었습니다 (센서는 많은 움직임이 없을 때 100 % 신뢰할 수 있음). 그래서 한동안 나는 내 건강한 기준(적어도 내 나이/체중의 표준 성인이 건강해야 하는 것) 이상으로 훈련하고 있음이 밝혀졌습니다. 흥미롭습니다. 저는 어렸을 때부터 (아마추어) 스포츠를 좋아했지만 십대에 심장에 문제가 있었고 시간이 지나면서 사라지는 것 같았습니다. 그러나 경험을 통해 빠른 걷기보다 더 높은 하중이 저에게 정말 힘들다는 것을 압니다. 그러나 계속 훈련했습니다. 그리고 시간이 지남에 따라 한계가 증가하여 지금은 제 자신이 아주 잘 맞는다고 생각하게 되었습니다. 그리고 이제 질문이 있습니다. 청소년기의 심장 문제로 인해 내 BPM이 정상보다 높습니까? 아니면 나도 모르게 너무 세게 밀고 있습니까? 어쨌든 모니터의 최대 BPM을 높이거나 덜 집중적으로 훈련해야 합니다. :)

추신 놀랍게도 uECG는 EMG 센서로 매우 잘 수행되었습니다. 제 Robotic Hand Control 프로젝트에서 이에 대해 읽을 수 있습니다.

<섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드">

코드

<울>
  • bpm_watch.ino
  • bpm_watch.ino아두이노
    #include #ifdef __AVR__ #include #endif#include #include #include #include int rf_cen =9; //nRF24 칩 활성화 pinint rf_cs =8; //nRF24 CS pinRF24 rf(rf_cen, rf_cs);//파이프 주소 - uECG에 하드코딩된 sideuint8_t pipe_rx[8] ={0x0E, 0xE6, 0x0D, 0xA7, 0, 0, 0, 0};// 어느 핀에 Arduino가 NeoPixels에 연결되어 있습니까?#define PIN 5// 얼마나 많은 NeoPixels가 Arduino에 연결되어 있습니까?#define NUMPIXELS 16Adafruit_NeoPixel pixels =Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);uint8_t swapbits(uint8_ECG) address는 교환된 비트 순서를 사용합니다. // 단일 바이트에서 비트 순서를 반대로 합니다. uint8_t v =0; if(a &0x80) v |=0x01; if(a &0x40) v |=0x02; if(a &0x20) v |=0x04; if(a &0x10) v |=0x08; if(a &0x08) v |=0x10; if(a &0x04) v |=0x20; if(a &0x02) v |=0x40; if(a &0x01) v |=0x80; return v;} 무효 setup() {pixels.begin(); // NeoPixel 라이브러리를 초기화합니다. for(int i=0;i 0) //예인 경우 - 새로 수신된 BPM으로 저장 rf_bpm =bb; } 긴 ms =millis(); if(ms - last_pix_upd> 10) //픽셀을 너무 자주 업데이트하지 않음 { int r, g, b; last_pix_upd =ms; 정수 bpm =rf_bpm; int max_bright =160; //최대 밝기 값, 최대 255. 하지만 항상 최대 밝기를 원하는 것은 아닙니다. float dd =25; //색조 간의 BPM 변화(파란색->녹색->노란색->분홍색->빨간색) float t1 =90, t2, t3, t4; //t1 - "기본" BPM, t1보다 낮으면 파란색 t2 =t1 + dd; t3 =t2 + dd; t4 =t3 + dd; // 현재 t1...t4 범위에 따라 색상을 변경하는 코드 if(bpm   

    회로도

    문서가 없습니다.

    nrf24_led_ring_o2Gij5oigT.fzz

    제조공정

    1. Renesas와 Altran은 3db Access UWB를 사용하여 웨어러블 칩셋을 개발합니다.
    2. DIY 환경 및 대기 질 모니터
    3. Python 및 Raspberry Pi 온도 센서
    4. Raspberry Pi를 사용하여 집 온도 모니터링
    5. 원격 심박수 모니터
    6. Arduino를 사용하여 모니터 Ambilight 만들기
    7. Arduino와 스마트폰을 사용한 DIY 전압계
    8. IoT를 사용한 심박수 모니터
    9. 의류에 통합된 센서는 심박수를 모니터합니다.
    10. CNC 기계를 사용하여 만든 재료 및 부품