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

아두이노 우노로 OLED에 실시간 ECG 파형 표시하기

부품 및 소모품

부품수량
아두이노 우노1
uECG 장치1
nRF24 모듈 (범용)1
0.96" OLED 128×64 디스플레이 (SSD1306)1

프로젝트 개요

uECG 장치에서 무선(nRF24)으로 심전도(ECG) 데이터를 수신해 아두이노 우노로 실시간 파형을 OLED에 표시하는 프로젝트입니다. 기존의 지저분한 코드를 정리해 uECG 아두이노 라이브러리(GitHub: ultimaterobotics/uECG_library)를 공개했으며, RF24 라이브러리와 Adafruit SSD1306 라이브러리가 필요합니다.

회로도

아두이노 우노로 OLED에 실시간 ECG 파형 표시하기

코드 (라이브러리 예제 포함)

#include 
#include 
#include 

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

int rf_cen = 9, rf_cs = 10;
uint8_t ecg_screen[128];
float ecg_avg = 0, ecg_max = 1, ecg_min = -1;
int ecg_size = 40;
uint32_t prev_data_count = 0, prev_displ = 0;
int displ_phase = 0;

void setup() {
  Serial.begin(115200);
  while(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
  }
  display.display(); delay(100);
  uECG.begin(rf_cs, rf_cen);
  delay(100);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.cp437(true);
  display.display();
  delay(100);
}

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) {
    int16_t ecg_data[8];
    uECG.getECG(ecg_data, new_data);
    for(int x = 0; x < new_data; x++) Serial.println(ecg_data[x]);

    // 화면 스크롤 버퍼 업데이트
    for(int x = new_data; x < 128; x++) ecg_screen[x-new_data] = ecg_screen[x];
    for(int x = 0; x < new_data; 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] < ecg_min) ecg_min = ecg_data[x];
      int ecg_y = 63 - ecg_size*(ecg_data[x] - ecg_min) / (ecg_max - ecg_min + 1);
      ecg_screen[127-new_data+x] = ecg_y;
    }

    // 30ms마다 디스플레이 업데이트 (4단계로 분할)
    if(millis() - prev_displ > 30) {
      prev_displ = millis();
      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("steps: "); display.print(uECG.getSteps());
        // 배터리 표시
        int batt_mv = uECG.getBattery();
        int batt_perc = constrain((batt_mv - 3300)/8, 0, 100);
        // 배터리 바 그리기...
      }
      if(displ_phase == 1) {
        for(int x=1; x<64; x++) display.drawLine(x-1, ecg_screen[x-1], x, ecg_screen[x], WHITE);
      }
      if(displ_phase == 2) {
        for(int x=64; x<127; x++) display.drawLine(x-1, ecg_screen[x-1], x, ecg_screen[x], WHITE);
      }
      if(displ_phase == 3) display.display();
      displ_phase = (displ_phase + 1) % 4;
    }
  }
}

데이터 처리 기능

장치 내부에서 BPM, GSR, RR 간격, HRV 파라미터(16개 빈), 걸음 수, 가속도계(자세 추정용) 등을 계산 제공. 로우 ECG 데이터도 패킷 손실이 있지만 사용 가능 수준.

라이브러리 및 참고

제조공정

  1. 맥심 MAX86150: 모바일 건강 모니터링용 통합 PPG·ECG 모듈
  2. 라즈베리 파이에서 GY-91 모듈로 견고한 온도 및 센서 API 구축하기
  3. TJBot 시작하기: 나만의 AI 로봇 제작, 설정, 음성 제어
  4. Verilog 모듈 기초: 구조, 문법, 계층적 설계의 핵심
  5. Verilog 파라미터 마스터하기: 재사용 가능하고 확장 가능한 모듈 구축
  6. Java 9 모듈 시스템: 향상 사항, 링크 타임, 커스텀 런타임 이미지
  7. 아두이노 우노와 OLED 디스플레이로 클래식 퐁(Pong) 게임 만들기: 단계별 튜토리얼
  8. 아두이노 나노 + 128x64 OLED로 실시간 셀룰러 오토마타 (생명 게임) 구현
  9. DIY Arduino LCD 프로젝트: 저항, 푸시버튼, 16x2 디스플레이로 축구 게임 만들기
  10. 아두이노 입문 튜토리얼 01: 첫 프로젝트 시작하기