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

KY-039에서 심박수까지

구성품 및 소모품

Arduino UNO
× 1
KY-039 하트비트 센서
× 1
점퍼 와이어(일반)
× 1

이 프로젝트 정보

Arduino용 37개 센서 세트 , 심장 박동 센서가 있습니다. 이름은 너무 많은 것을 약속합니다. 사람들은 이것이 I2C 또는 이와 유사한 것을 통해 디지털 숫자를 제공한다고 생각하는 경향이 있습니다. 숫자는 심장 박동수입니다. 센서가 제공하는 것은 0에서 1023 사이의 "아날로그" 값으로, 광 센서가 수신하는 적외선의 양 또는 실제로 어떤 것이 광 센서를 얼마나 어둡게 하는지 알려줍니다. . 값이 높을수록 적외선이 적습니다.

간단히 말해서:IR LED와 센서의 광 트랜지스터 사이에 손가락을 놓습니다. 심장 박동은 손가락의 혈관을 확장시켜 적외선을 걸러냅니다. 이것은 맥동 신호를 생성합니다.

이 프로젝트에서는 이 신호가 66BPM(분당 비트 수)과 같은 심장 박동수로 변환되는 방법을 설명합니다.

간단한 단계

KY-039 센서의 값을 읽고 플롯하면 다음과 같이 됩니다.

값은 정수 값입니다. 매우 정확하지 않습니다. 대신 그것들의 무리의 평균을 계산하고 평균을 플로팅하십시오. 당신은 이것을 얻습니다:

여기에서 이미 심장의 맥박을 볼 수 있습니다. 펄스의 각 중요한 상승 사이의 시간 차이를 구합니다. 이를 통해 BPM으로 심박수를 계산할 수 있습니다.

(위 이미지의 작은 지그재그 패턴은 인공 조명, 50Hz, 또 다른 처리해야 할 사항으로 인한 것입니다.)

단계 설명

다음은 KY-039 센서에서 읽은 내용을 출력하는 간단한 코드입니다.

// 펄스 모니터 테스트 Scriptint sensorPin =0;void setup() { Serial.begin(9600);}void 루프(){ while(1) { Serial.print(analogRead(sensorPin)); Serial.print('\n'); }}  

얻을 수 있는 내용은 다음과 같습니다.

이것은 9600 보드에서 Arduino의 직렬 출력을 읽는 직렬 모니터 창의 캡션이므로 전체 프로세스는 Serial.print()에 의해 시간이 지정됩니다. 값을 읽고 플로팅하는 속도를 설정하는 기능입니다. 어쨌든 곡선은 360과 383 사이에서 다양하고 정수 값만 있기 때문에 매우 들쭉날쭉합니다.

스무딩

더 부드러운 출력을 얻으려면 센서에서 평균 20번의 마지막 판독값을 취하십시오. 방법은 다음과 같습니다. 원하는 판독값을 나타내는 상수를 정의합니다.

#define samp_siz 20 

그런 다음 해당 수의 판독값을 보유하는 배열이 있습니다.

int 읽기[samp_siz];  

각각의 새로운 판독값에 대해 합계에서 가장 오래된 판독값을 빼고 합계에 최신 판독값을 더합니다. 배열에서 가장 오래된 판독값을 최신 판독값으로 바꿉니다.

 리더 =analogRead(sensorPin); // 센서 합계 읽기 -=reads[ptr]; // 합계에서 가장 오래된 판독값을 뺍니다. sum +=reader; // 합계에 최신 판독값을 추가합니다. reads[ptr] =reader; // 배열에 최신 판독값을 저장합니다. last =float(sum) / samp_siz; // 이제 평균을 계산합니다. ptr++; // 배열의 인덱스를 업데이트하고 ptr %=samp_siz를 갖습니다. // 필요할 때 0에서 다시 시작 

직렬 모니터에서 어레이 크기가 20이고 전송 속도가 9600인 경우 다음과 같은 플로팅을 얻을 수 있습니다.

여기에서 실제 심장 박동이 가파른 상승 곡선으로 나타나는 것을 볼 수 있습니다. 그러나 작은 지그재그 패턴도 보입니다. 더 작은 지그재그는 내 주방 조명에서 나오고 세 개의 LED 전구가 방을 비춥니다. 우리 집의 주 전원은 240V, 50Hz AC입니다. 따라서 초당 50회 빛의 강도가 증가하며 IR 대역에서도 분명히 나타납니다. 그 50Hz 노이즈를 없애고 싶습니다. 20ms 기간 동안 센서에서 값을 읽고 모든 값의 평균을 취하면 작동해야 합니다. 보자...

<사전><코드> n =0; 시작 =밀리(); 리더 =0.; do { 리더 +=analogRead(sensorPin); // 값을 읽고 추가합니다... n++; 지금 =millis(); } 동안 (지금 <시작 + 20); // ... 20ms가 경과할 때까지 판독기 /=n; // 값의 평균을 구합니다.

이 스니펫을 사용하여 센서 판독값을 20ms 청크로 가져와 인공 조명으로 인한 50Hz 깜박임을 균일하게 합니다. 60Hz 국가에 거주하는 경우 16.67ms 청크를 대신 사용하십시오. 또는 16667µs.

이미 20ms 섹션에서 곡선을 매끄럽게 하기 때문에 이전에 사용한 배열이 실제로 필요하지 않지만 배열이 있고 크기를 쉽게 조정할 수 있으므로 그대로 둡니다. 그리고 5의 배열 크기를 사용하면 마지막 성가신 노이즈를 균일하게 만드는 것 같습니다. 이것이 내가 가진 것입니다:

마지막으로 해야 할 일은 반복되는 패턴의 일부를 인식하는 것입니다. 상승 경사가 더 규칙적이기 때문에 나는 그것을 간다. 모든 그래프에서 y축 값이 어떻게 매우 다른지 확인하십시오. 절대적인 가치에만 의존할 수는 없습니다. 나는 곡선의 상승과 하락에만 의존할 수 있습니다. 수학자들은 도함수에 대해 이야기할 것입니다. n을(를) 찾으면 만족합니다. 연속적인 상승 값, 여기서 n 편리한 조정 가능한 값이 될 수 있습니다. 5부터 시작합니다. 이를 위해 rise_threshold가 있습니다. 코드에 정의된 상수입니다. 5개의 연속적인 상승 값을 찾으면 내가 위쪽으로 향하는 곡선의 맨 아래에 있다는 것을 알 수 있습니다. 시간이 걸립니다. 나는 하락 곡선을 기다린 다음 다음 5개의 상승 값을 기다렸다가 시간을 기록합니다. 그런 다음 해당 BPM을 인쇄합니다.

테스트를 했습니다 그리고 계산 어떻게 많은 연속 상승 가치 거기 있다 안에 곡선 그리고 찾음 밖으로 거기 이전 사이 10 그리고 15. 그래서 만약 카운트 ~으로 5, 대부분 물론 알다 나는 찾음 시작 심장박동

각 하트비트 후에만 인쇄하기 때문에 인쇄가 많지 않습니다. 센서를 읽는 데 더 많은 시간이 소요됩니다. 플로터가 켜져 있지 않기 때문에 볼 수 없는 더 높은 빈도의 노이즈를 잡을 수 있습니다. 어떻게 작동하는지 봅시다.

최종 코드

#define samp_siz 4#define rise_threshold 5// 펄스 모니터 테스트 Scriptint sensorPin =0;void setup() { Serial.begin(9600);}void 루프(){ float reads[samp_siz], sum; 이제 long int, ptr; float 마지막, 리더, 시작; float 첫 번째, 두 번째, 세 번째, 이전, print_value; 부울 상승; int 상승 카운트; 정수 n; 긴 정수 last_beat; for (int i =0; i  before) { rise_count++; if (!rising &&rise_count> rise_threshold) { // 좋아, 상승 곡선을 감지했으며 이는 다음을 의미합니다. heartbeat. // 마지막 비트 이후의 시간을 기록하고 이전의 두 시간(첫 번째, 두 번째, 세 번째)을 추적하여 가중 평균을 얻습니다. // 상승 플래그는 같은 상승을 감지하는 것을 방지합니다. // 한 번. 상승 =true, 첫 번째 =밀리 () - last_beat; last_beat =millis(); // 심박수의 가중 평균을 계산합니다 // 마지막 세 박자에 따라 print_value =60000. / (0.4 * 첫 번째 + 0.3 * 두 번째 + 0.3 * 세 번째); Serial.print(print_value); Serial.print('\n'); 세 번째 =두 번째 두 번째 =첫 번째; } } else { // 좋습니다. 곡선이 떨어지고 있습니다. rises =false; 상승 횟수 =0; } 이전 =마지막; ptr++; 포인트 %=samp_siz; }}  

꽤 잘 작동합니다. 여기 동영상이 있습니다.

작은 RX led가 내 마음과 동기화하여 Arduino에서 깜박입니다. 단순히 심장 박동이 있을 때 속도가 계산되고 LED가 깜박이는 직렬에 인쇄되기 때문입니다. 손가락이 약간 움직이면 오류 판독값이 표시됩니다.

추가 개발

지금 인쇄된 비율은 마지막 세 비트를 기반으로 계산됩니다. 그러나 15초 주기를 기준으로 계산하는 것이 더 적절할 수 있습니다. 15개의 연속된 비율 값을 저장하고 평균을 계산한 다음 평균에서 가장 멀리 떨어져 있는 5개의 값을 제외하고 새 평균을 계산할 수 있습니다. 이렇게 하면 심박수를 안정적이고 안정적으로 측정할 수 있습니다.

저는 아내와 저에게만 센서를 테스트했습니다. 이전 판독 값을 기반으로 한 신호를 향상시키는 각 단계. 다른 사람은 다른 모양의 곡선을 일으키는 다른 종류의 심장 박동을 가질 수 있으며, 이는 박동을 찾기 위한 다른 접근 방식이 필요합니다. 아마도 더 쉽게 알아볼 수 있는 것은 하강 곡선일 것입니다. 또는 맨 위에 있습니다. 펄스가 180 - 200BPM이면 어떻게 됩니까? 상승 곡선을 찾는 것은 더 까다로울 수 있습니다.

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

코드

<울>
  • 최종 버전
  • 최종 버전C/C++
    프로그램은 하트비트를 읽고 직렬 창에 속도를 인쇄합니다.
    #define samp_siz 4#define rise_threshold 4// 펄스 모니터 테스트 Scriptint sensorPin =0;void setup() { Serial.begin(9600);}void 루프 (){ float 읽기[samp_siz], 합계; 이제 long int, ptr; float 마지막, 리더, 시작; float 첫 번째, 두 번째, 세 번째, 이전, print_value; 부울 상승; int 상승 카운트; 정수 n; 긴 정수 last_beat; for (int i =0; i  before) { rise_count++; if (!rising &&rise_count> rise_threshold) { // 좋아, 상승 곡선을 감지했으며 이는 다음을 의미합니다. heartbeat. // 마지막 비트 이후의 시간을 기록하고 이전의 두 시간(첫 번째, 두 번째, 세 번째)을 추적하여 가중 평균을 얻습니다. // 상승 플래그는 동일한 상승을 두 번 이상 감지하는 것을 방지합니다. 상승 =true, 첫 번째 =millis() - 마지막_비트; last_beat =millis(); // 심박수의 가중 평균을 계산합니다 // 마지막 세 박자에 따라 print_value =60000. / (0.4 * 첫 번째 + 0.3 * 두 번째 + 0.3 * 세 번째); Serial.print(print_value); Serial.print('\n'); 세 번째 =두 번째 두 번째 =첫 번째; } } else { // 좋습니다. 곡선이 떨어지고 있습니다. rises =false; 상승 횟수 =0; } 이전 =마지막; ptr++; 포인트 %=samp_siz; }} 

    회로도


    제조공정

    1. 컬러 센서 – 작업 및 응용
    2. OPT3007 초박형 주변광 센서
    3. InitialState를 사용하여 ppDAQC Pi 플레이트에서 센서 데이터 스트리밍
    4. Raspberry Pi 온도 및 광 센서
    5. MSP430 무선 센서 노드에 대한 태양광 진입로 조명
    6. Raspberry Pi 및 Twilio를 사용한 음성 및 SMS 지원 광 센서
    7. Windows 10 IoT Core – 심박수 펄스 읽기
    8. Raspberry Pi 광 센서:간단한 LDR 자습서
    9. 디지털 광 센서
    10. 원격 심박수 모니터