Arduino UNOでリアルタイム心電図表示 - uECGデバイスとOLED活用
必要な部品と材料
| 部品 | 数量 | 備考 |
|---|---|---|
| Arduino UNO | 1 | |
| uECGデバイス | 1 | 心電図測定用ウェアラブル |
| nRF24L01+ モジュール | 1 | 2.4GHz無線通信 |
| 0.96インチ OLEDディスプレイ (128x64, SSD1306, I2C) | 1 | ElectroPeak製等 |
プロジェクト概要
uECGデバイスから心電図データを無線(nRF24)で受信し、Arduino UNOでOLEDにリアルタイム波形表示するプロジェクト。作者が公開している
1. 回路図・配線
- nRF24: SPI接続(D13=SCK, D12=MISO, D11=MOSI)、CS→D10, CE→D9
- 重要:nRF24は必ず3.3V電源で駆動(5V不可)。3.3V-GND間に1-10µFコンデンサー推奨(電圧安定化)
- OLED: I2C接続(SDA→A4, SCL→A5)、電源5V。モジュールにI2Cプルアップ抵抗内蔵なら追加不要。無い場合は4.7kΩを3.3Vにプルアップ
完成写真:コンパクトにまとまったプロトタイプ
2. コード解説
ライブラリの例題としても同梱。主な流れ:
#include <uECG.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#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; // nRF24 CE
int rf_cs = 10; // nRF24 CS
void setup() {
Serial.begin(115200);
while(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { /* エラー処理 */ }
display.display(); delay(100);
uECG.begin(rf_cs, rf_cen); // nRF24初期化
delay(100);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.cp437(true);
display.display();
delay(100);
}
uint32_t prev_data_count = 0;
uint32_t prev_displ = 0;
uint8_t ecg_screen[128]; // 波形描画用バッファ(128ピクセル幅)
int ecg_screen_len = 128;
float ecg_avg = 0, ecg_max = 1, 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); // 生ECGデータ取得
for(int x=0; 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[ecg_screen_len-1-new_data+x] = ecg_y;
}
// 描画は30msごとに4フェーズで分割実行(loopブロッキング回避)
if (ms - prev_displ > 30) {
prev_displ = ms;
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
ポイント
uECG.run()を毎ループ必ず呼ぶ(パケット取りこぼし防止)。delay()は使わずmillis()でタイミング制御- 描画を4フェーズに分割し、1フレームあたりの処理時間を短くしてデータ取りこぼしを防止
- 波形は動的レンジ調整(移動平均・最大最小追従)で画面にフィット
- BPM、RR間隔、歩数、バッテリー残量も同時表示
3. 取得可能なデータ
デバイス側で処理済みの統計値:
- 心拍数(BPM)、最後のRR間隔、HRVパラメータ、HRVヒストグラム(16ビン)
- 歩数、加速度(姿勢推定程度のリフレッシュレート)
- 生ECG波形データ(パケットロスありだが実用可)
波形表示例のスクリーンショットも掲載。ライブラリ導入で手軽に心電図モニターが作れます。
ライブラリと回路図
- uECG Arduinoライブラリ: GitHub(OLED例題・シリアル出力例題内蔵)
- 回路図画像提供
製造プロセス
- GY-91モジュールでRaspberry Pi上に堅牢な温度・センサーAPIを構築
- TJBot入門:組み立て、設定、音声制御で自分だけのAIロボットを構築
- Arduino UNOとOLEDディスプレイでクラシックPongゲームを自作:ステップバイステップチュートリアル
- JX Wave Generator – Arduino互換DDS発振器(OLEDディスプレイ搭載)
- Arduino Nanoと128x64 OLEDで実行するセルラーオートマトン「ライフゲーム」
- Arduino LCDプロジェクト: 16x2ディスプレイとプッシュボタンで作るサッカーゲーム
- Arduino初心者チュートリアル01: 最初のプロジェクトを始めよう
- Maxim MAX86150:モバイルヘルスモニタリング向け統合PPG&ECGモジュール
- Verilogモジュールの基礎:構造と構文
- Verilogパラメータのマスター:再利用可能でスケーラブルなモジュールの構築
- Java 9モジュールシステム:リンクタイムとカスタムランタイムイメージ