脈拍センサーとSTM32Nucleoで心拍数を測ってみる
低速パルスである脈拍をカウントして一分間あたりの心拍数を表示するアプリケーションに挑戦してみましょう。
目次
フォトリフレクタおよびオペアンプを使った脈拍センサーの作成
脈拍をカウントして心拍数を表示するアプリケーションの解説をします。心拍数アプリを実現するためのアプリにはアナログ電子回路の知識、STM32マイコンのGPIO、割り込みおよびシリアル通信など学習に必要な要素がバランス良く盛り込まれています。
脈拍を検知するセンサーには電子工作でも一般的によく使われているフォトリフレクタと呼ばれる部品を使用します。
このフォトリフレクタは赤外線を発光するLEDと反射して返ってきた光を検出するトランジスタで構成されています。 電子工作では色による反射光量の違いで黒いラインのあるなしを判別することを利用したライントレースなどにも用いられます。
指先をフォトリフレクタに当てると指先にある毛細血管のヘモグロビン濃度変化を反射率の変化として検知できるのですが、この変化はとても微小でそのまま電気信号としてマイコンに入力してもカウント困難なのでまずオペアンプという部品を使って安定した脈拍パルスに増幅します。この増幅回路はさまざまなタイプがあり、採用しているのはその一例ですがインターネットでも十分な情報がありますのでいろいろ試してみるとよいと思います。
オペアンプは1段でも機能するかもしれませんがここでは2段使用しています。フォトリフレクタ信号の変化分だけパルスとしてとりだしたいので直流分をカットするコンデンサCと抵抗Rを組み合わせたRCハイパスフィルタ(カットオフ周波数:約1kHz)を入り口にいれています。
LTSpice®と呼ばれる回路シミュレーションを使用して上記回路の特性を調べてみます。入力信号には振幅1mV、オフセット2.5V、周期1sの矩形波としています。妥当な波形が出力にあらわれているのでこれで回路を構成することにします。
回路シミュレーションを利用するとおおまかな部品の選定や抵抗値、コンデンサ容量などのパラメータを実際の回路を制作する前に確認することができますので試作のかわりに強力なツールとして利用することをおすすめします。
製品として完成された脈拍センサーを使うと確実で簡単なのですが、ここではあえて学習用にフォトリフレクタという素子を使って電子工作を兼ねて心拍モニターを実現することにしています。
脈拍センサ信号および出力モニター用LEDをマイコンに接続
オペアンプ出力のVINを直接マイコンに入力として接続するので入力最大電圧がマイコン電源電圧を超えないようにオペアンプの電源をマイコン電源と共通のものにしています。(STM32では端子により5V入力が可能なものもありますが、すべてではありません。STM32F103RBの仕様書で確認してください。)
プログラム内容解説
オペアンプにより増幅した脈拍センサ信号は電圧パルス信号としてPA8に入力します。心拍モニターとして入力パルスに同調したLED点灯するためにPB6を汎用プッシュプル出力に設定をします。
PA8は外部割り込み信号として使うために割り込み設定をします。割り込み入力はパルスの立ち上がり時を条件としています。
割り込み設定は「さまざまな割り込み【STM32の割り込み詳細】」で詳細を解説しています。
RTOSを使って役割毎にタスクに分類します。脈拍パルス間隔を計測するためのタスクprvTask_pulse(10ms毎に実行)、LED点灯用のタスクprvTask_led(100ms毎に実行) 、そして演算して得た心拍数をPCに送るタスクprvTask_monitor(1000ms毎に実行) です。
リアルタイムOS(FreeRTOS)のタスクの使い方は「FreeRTOSタスク管理の基本【学習・実践向け:具体的な使い方】」で詳細を解説しています。
脈拍パルス数計測のタイムチャートです。PA8の割り込み入力パルス立ち上がりで割り込みが発生して割り込みハンドラEXTI9_5_IRQHandlerが呼び出されます。ここでフラグtriger_flag=1として、割り込みが発生したことを通知します。
10msごとに実行している 脈拍パルス間隔を計測するためのタスクprvTask_pulseがtrigger_flag=1で割り込み発生の通知を受けると 10msごとに加算カウント (10msクロックのカウント) した値(count_interval_cycle)を取得して心拍数(pulse_count)を演算します。演算処理後、割り込み通知用フラグtrigger_flagとカウント値count_interval_cycleをリセットします。 心拍数は割り込み入力の1分間における回数がわかればよく10msごとの クロックカウント値count_interval_cycle の場合は6000を count_interval_cycle で割ったものになります。
脈拍センサー入力
実際に構成した回路で脈拍センサー検知部のフォトリフレクタ-に指先をあてると脈拍を検知して信号がオペアンプで適度に増幅されている様子がわかります。シミュレーション結果と実際の回路による結果が同じようなものであることがわかります。
この心拍数計測のプログラムでは脈拍センサーによるアナログ信号をパルス入力として割り込みでカウントします。
LEDおよびモニター出力
脈拍パルスに同調したLED発光はprvTask_ledで行っています。実行頻度は100ms程度で十分です。
演算して得られた心拍数をシリアルUSART通信で心拍数をモニターするためのタスクがprvTask_monitorです。演算値を文字列に変換して1000msごとにPCモニターに表示させます。PC側のターミナルソフトで値が確認できます。
フォトリフレクタは指の押さえ方により敏感に反応してしまいますが安定するように押さえてやると妥当な心拍数が表示されていることがわかります。出力モニター用LEDは脈拍に同調して発光しています。
シリアル通信USARTの使い方は「シリアル通信USART【STM32のUSART詳細】」および「シリアルモニター【STM32シリアル通信】」で詳細を解説しています。
以上が 基本的な心拍数モニターのプログラム構成です。LEDの点滅をPWM出力の調光にしてみたり、シリアル通信をWiFiで実現してみたり、いろいろと組み合わせて発展していくとよいでしょう。