スマートウォッチの機能の一つに心臓の鼓動を測定し、ストレス状態を教えてくれる心拍計があります。
今回はRaspberryPiを用いて、脈拍計(心拍計)を製作してみました。
脈拍波形の測定原理、電子回路の組み方、プログラムコードを分かりやすくまとめましたので、参考になれば嬉しいです。
今回使用したA/Dコンバータとプログラムの解説に関しては、記事が長く読みにくくなりそうなので、別記事にまとめました。
詳しく理解したい方はそちらの記事を参考にしてください。この記事だけで脈拍測定機は作れますので安心ください!!
- RaspberryPi 4 Model B
- 心拍センサ:KKHMF
- A/D コンバータ:MCP3002
今回使用した心拍センサはアナログ信号の出力です。Raspberry Piはデジタル信号しか扱えないので、アナログ信号に対応するためにA/D コンバータを使用します。
アナログ信号を扱えるAruduinoに比べて回路が複雑になりますが、プログラムも難しくなく綺麗に心拍の波形をとることができました。
脈拍測定の原理
脈拍センサは、LEDライトとフォトダイオード(明るさが変化すると、抵抗値が変化する電子部品)で構成されています。
センサのLED光は脈内のヘモグロビンに吸収されやすい性質を持っています。
脈の拍動により脈の体積が膨張すると、拍動に併せてヘモグロビン量も増加します。つまり、脈が拍動すると同時にヘモグロビンに吸収されるLED光の量も増えるので、センサ周辺が暗くなります。
センサ周辺が暗くなるとフォトレジスタの抵抗値は増加するので、センサ内の電流値は減少します。よって脈拍センサの電流値変化を計測することで、脈拍の拍動の波形を得ることができます。
これが、脈拍測定の原理になります。
回路の組み方
ブレッドボード上で図のようにRaspberry Pi と心拍センサ、A/Dコンバータを繋げます。
ワイヤは下記の通りに繋げています。
CS/SHDN → GPIO8(24番)
CH0はどこにも繋げない
CH1 → 脈拍センサの出力(右端のコード)
VSS → GND
VDD/VREF → 5V電源
CLK → SPI_CLK(23番)
DOUT → SPI_MISO(21番)
DIN → SPI_MOSI(19番)
脈拍センサの真ん中コード → 5V電源
脈拍センサの左端コード → GND
実際に組んでみるとこんな感じになります。
脈拍センサの裏面とマジックテープ(100均のケーブルバンド)をホットボンドで接着します。センサを固定しやすくしました。
リアルタイム表示
Pythonで作成したソースコードが下記になります。脈拍波形をリアルタイムで表示しています。リアルタイムでは荒い波形が表示されてしまいました。プロットには時間がかかるみたいです。。
import spidev #spi通信
import time
import matplotlib.pyplot as plt
import numpy as np
spi = spidev.SpiDev()
spi.open(0,0) #CS/SHDNを24番ピンに繋げば(0,0)、26番ピンに繋げば(0,1)とする。
spi.max_speed_hz = 1000000. #転送速度設定:1MHz
sleeptime = 0.001. #ここでサンプリング周波数を調整
x = []
y = []
start_time = time.perf_counter()
while True:
Dout = spi.xfer2([0x68, 0x00]) #Din入力
amp = ((Dout[0] << 8) + Dout[1]) & 0x3FF #Doutのデータを10進数に変換
elapsed_time = time.perf_counter() - start_time #測定経過時間を算出
y.append(volume)
x.append(elapsed_time)
plt.plot(x,y)
plt.xlim(elapsed_time-10,elapsed_time)
plt.draw()
plt.pause(sleeptime)
time.sleep(sleeptime)
plt.cla()
データ読み取り後、グラフ表示
次にデータ読み取りが完了した後にデータをグラフ化するコードを示します。
プログラムを実行後、波形データを読み取り続けます。”Ctrl” + ”C” を押すと、読み取りを終了し脈拍波形が表示されます。
import spidev
import time
import matplotlib.pyplot as plt
import numpy as np
spi = spidev.SpiDev()
spi.open(0,0) #CS/SHDNを24番ピンに繋げば(0,0)、26番ピンに繋げば(0,1)とする。
spi.max_speed_hz = 1000000 #転送速度設定:1MHz
sleeptime = 0.001 #ここでサンプリング周波数を調整
x = []
y = []
start_time = time.perf_counter()
while True:
try:
Dout = spi.xfer2([0x68, 0x00]) #Din入力
amp = ((Dout[0] << 8) + Dout[1]) & 0x3FF #Doutのデータを10進数に変換
elapsed_time = time.perf_counter() - start_time #測定経過時間を算出
y.append(amp)
x.append(elapsed_time)
time.sleep(sleeptime)
print(elapsed_time)
except KeyboardInterrupt:
spi.close() #spi通信終了
break
np.savetxt('data.txt',y) #脈拍波形データ保存後にグラフ表示
plt.plot(x,y)
plt.show()
綺麗な波形が表示されました。なかなか高精度にデータが取れました!!
まとめ
RaspberryPiでもA/Dコンバータを用いれば、脈拍波形を測定できるのを確認できました。
A/Dコンバータは今まで触れたことがなかったので苦手知識が強かったですが、意外と取り扱いが容易なことが分かりました。
A/Dコンバータからデータを読み取る方法やプログラミングの解説はこちらの記事でまとめておりますので、ぜひ参考にしてみてください。
コメント