心電計

ふと自分の心電図を見たくなったので心電計を作ってみました。1チャンネルのみの簡易的なものですが、なかなかうまく波形を出せたのではないかと思います。波形を眺めて楽しむためのものなので、もちろんホビー用途限定です。

心電計の完成写真

心電計の完成写真

動画

心電図

心電図は、心臓の活動によって体表に現れる電位の変化を記録したものです。なぜこの電圧が生まれるのかや具体的な読み方は専門の解説に譲りますが、ここでは心電図を眺めて楽しめるようになるための最低限の電子回路的な情報だけ記しておきます。

理想的な心電図の波形には、P波、Q波、R波、S波、T波と呼ばれる部分があります。心臓が一回脈打つとこれらの波形が生まれます。ピークであるR波の電圧は1mV程度で、全体としては1.5mVpp程度、帯域は0.05~100Hz程度とされています。心拍数を測るにはR波同士の間隔を見ればよいです。

心電図の波形

心電図の波形

最も一般的に用いられる心電図の検査方法は12誘導心電図というもので、四肢誘導と胸部誘導合わせて10個の電極を用いて12種の波形を得ます。12も波形を得ようとすると非常に大規模になってしまうので、今回の製作では1チャンネルのみの心電計にしました。

四肢誘導の中のⅠ誘導は左室の側壁を見る誘導で、右腕側を正極にして観測したものです。左右の腕の電極を差動アンプで受ければこの誘導をとらえることができます。もちろん電極をつなぐ位置を変えればⅡ誘導、Ⅲ誘導も見ることができます。

四肢誘導の図

四肢誘導

回路図

心電計の回路図

心電計の回路図

計装アンプ、LT1167のデータシートにある「Nerve Impulse Amplifier」を参考にしました。Ⅰ誘導を見る場合であれば、J2のターミナルには1に左手電極、2に右足電極(計測用グランド)、3に右手電極を取り付けます。計測用グランドは使わなくても心電図を得ることはできますが、ノイズ耐性が落ちるので使った方がよいです。

基本的には、計装アンプで約10倍に増幅したのちに非反転増幅回路で301倍している回路です。回路全体で約3000倍の利得があるので、入力信号が1.5mVppであるとすると4.5Vppの信号となり、PICマイコンのADCのダイナミックレンジを大きく生かすことができます。なぜ二段で増幅しているかというと、電極から得た電位を計装アンプで増幅しただけではDCオフセットが大きくなってしまうからです。初段の増幅率は上げすぎると出力が飽和してしまうので、10~20倍程度にとどめておくのがよさそうです。直流成分の除去と、ADCのアンチエイリアスのためにカットオフ周波数0.3Hzのハイパスフィルタと、カットオフ周波数530Hzのローパスフィルタを形成しています。

U1Bのオペアンプは、右足駆動回路やDRL回路(Driven-right-leg Circuit)と呼ばれる回路を形成しています。これはアクティブに計測用グランドを生成する回路で、コモンモード電圧のみを取り出してフィードバックすることでコモンモードノイズを打ち消す働きがあります。これを利用せずとも心電図はとれるのですが、使った方がノイズ耐性が上がります。

回路の設計中に知ったのですが、上記を含む多くの回路機能を内蔵したアナログ・デバイセズのAD8232というチップがあり、これを乗せたモジュールも販売されているのでそちらを使うと非常に簡単に心電計が組めそうです。

アナログ部で増幅した信号を、PIC18F27Q43のADCで取り込んでいます。PIC内でハムノイズの除去、基線動揺の除去(DCサーボ)、R波の検出、心拍数の算出を行い、128×160の液晶(ST7735S)に表示する処理を行っています。

ノイズ対策

心電図のノイズ源はいくつかあります。その中でも特に目立つものを挙げると、

  • ① 50Hzないし60Hzのハムノイズ
  • ② 発汗による電位変動
  • ③ 電極と皮膚との圧力変動によるノイズ
  • ④ 筋電図の混入

があります。一般家庭での実験の場合、最も目立つのはハムノイズになります。これはノッチフィルタで除去します。②と③は電極と皮膚との接触を工夫することで抑えられます。④の筋電図は比較的周波数が高いためローパスフィルタで除去します。また、これらに加えて基線動揺という長期的なレベル変動が起こります。これは被検者の呼吸などの動きに伴う変動で、DCサーボをかけることで除去します。

ハムノイズはハムノイズ1周期分の長さをもつバッファの移動平均を求めることで除去します。今回はADCのサンプリングレートを1.6kHz、バッファの長さを32段としました。こうすることでバッファは20msec分のデータを蓄え、50Hzのハムノイズを1波形分収めることになります。ハムノイズは正弦波なので、1波形分を平均すればゼロになります。移動平均のアルゴリズムは以下の通りです。毎回全要素を足し合わせるのではなく、差分のみ合計することで演算量を抑えています。

adc_tmp = get_adc();
sum = sum - adc_fifo[ptr] + adc_tmp;
ave = sum / adc_fifo_length;
ptr++;
if (ptr == adc_fifo_length) ptr = 0;

DCサーボは以下のように実現しています。係数0.01の部分で時定数の調整、定数1500の部分でDCオフセットの調整ができます。このプログラムでは長期的に見たときにdc_servoの値が1500で一定になるように動作します。

integrator = integrator + (Din - integrator) * 0.01;
dc_servo = Din - integrator + 1500;

電極には、ステンレス製の一文字繋手を曲げたものを使いました。ステンレスであれば、銅やアルミニウムなどよりは汗による影響を受けにくくなります。この電極をできるだけ接触面積が大きくなるようにゴムバンドなどで手足に固定します。接触直後はノイズが多いですが、時間がたち皮膚となじむとノイズが減ります。測定の際には全身の力を抜き、リラックスすることが重要です。どこかに力が入っていると筋電図が混入したり、DCサーボでも取り切れないオフセットが現れたりします。
実際の医療現場では導電性ゲルでできたものを使うことが多いようですが、高価なうえ個人で入手できるようなものでもなさそうです。

心電計の電極

心電計の電極

R波の検出

心拍数を算出するために、R波の位置を正確に知る必要があります。単純な閾値によっても求まりそうに見えますが、心電図の波形は個人差が大きいうえに、同じ人でもR波の形は毎波形ごとに変わっていくのでなかなかうまく求まりません。R波を検出するアルゴリズムとして最も有名なものはPan–Tompkinsアルゴリズムと呼ばれるものです。これはバンドパスフィルタによって心電図のQRS群のみを誇張したのち、微分したものを二乗して閾値を設定してQRS群を検出するものです。古くから使われており、高い確度があるようですが8bitのPICに処理させるには重すぎます。そこで今回は矩形波相関フィルタというもので検出を行いました。

矩形波相関フィルタのイメージ

矩形波相関フィルタのイメージ

このフィルタは、QRS群を正負の符号をもち、1:2:1の時間幅を持つ矩形パルス窓を使って相関値を求めるものです。QRS群の波形が記録されると相関値が大きくなるので、相関値に閾値を設けたり最大値を検出すればR波の位置が分かります。

correlation = - (buf[0] + buf[1] +......+ buf[n/4-1])
            + (buf[n/4] + buf[n/4+1] +......+ buf[3*n/4-1])
            - (buf[3*n/4] + buf[3*n/4+1] +......+ buf[n])

QRS群の長さは60~100msecほどが正常値のようですが、今回のサンプリング周波数は1.6kHzなのでバッファの長さを100とすれば窓の長さを62.5msecにできます。相関値を求める式の最後の項、buf[n]は、バッファの外を参照してしまうのでバッファの中身ではなく最新の波形データを使えばよいです。
今回の心電計での実装は以下の通りです。差分のみ計算することで計算量を抑えています。

// 初期化コード
// FIFO
uint32_t fifo[rr_buf_length] = {0};
// 差分の合計
int32_t correlation = 0;
// FIFOのポインタ
uint8_t ptr = 0;
// 矩形波近似フィルタのポインタ
uint8_t ptr1 = 0;
uint8_t ptr2 = buf_length / 4;
uint8_t ptr3 = 3 * buf_length / 4;
// 矩形波近似フィルタ
correlation = correlation - fifo[ptr1] + 2 * fifo[ptr2] - 2 * fifo[ptr3] + newData;

// FIFO操作
fifo[ptr]=newData;
if (ptr  == buf_length) ptr = 0;
if (ptr1 == buf_length) ptr1 = 0;
if (ptr2 == buf_length) ptr2 = 0;
if (ptr3 == buf_length) ptr3 = 0;

安全上の注意

⚠️ 重要な安全上の注意

直に体に電極を当てるので、万が一の時に体に電流が流れるようなことがないようにする必要があります。電源は電池や絶縁電源を使う必要があります。パソコンなどにシリアル通信等で計測データを送る場合にもフォトカプラなどで絶縁する必要があります。

参考にした資料等