KY-039心拍センサーで心拍数を測定する
必要な部品と材料
| 部品 | 数量 | 備考 |
|---|---|---|
| Arduino UNO | 1 | |
| KY-039心拍センサー | 1 | 37種類センサーキットに含まれるもの |
| ジャンパーワイヤー | 1 |
プロジェクト概要
Arduino用37種類センサーセットに含まれる心拍センサー。名前からはデジタルで心拍数が出力されると思いがちですが、実際は赤外線LEDとフォトトランジスタで構成され、指を挟むことで血流変化による赤外線透過量の変化を0〜1023のアナログ値として出力するだけです。
基本的な手順
生の値をプロットすると非常に荒い波形になりますが、移動平均を取ると脈拍波形が明確になります。さらに50Hz/60Hzの商用電源ノイズを除去するため、20ms(50Hz環境)または16.67ms(60Hz環境)ごとの平均値を計算します。最終的に、立ち上がりエッジを検出して心拍間隔を計測し、BPM(拍動/分)を算出します。
ステップ詳細
1. 生データの取得
int sensorPin = A0;
void setup() { Serial.begin(9600); }
void loop() {
while(1) {
Serial.println(analogRead(sensorPin));
}
}
2. 平滑化(移動平均)
配列で直近Nサンプルの合計を維持し、平均を出力します。
#define samp_siz 20
int reads[samp_siz];
long sum = 0;
int ptr = 0;
int reader = analogRead(sensorPin);
sum -= reads[ptr];
sum += reader;
reads[ptr] = reader;
float last = (float)sum / samp_siz;
ptr = (ptr + 1) % samp_siz;
3. 50Hzノイズ除去(20ms区間平均)
int n = 0;
long start = millis();
float reader = 0;
do {
reader += analogRead(sensorPin);
n++;
} while (millis() < start + 20);
reader /= n;
4. 心拍検出とBPM計算
連続してrise_threshold回値が上昇したら「立ち上がり」とみなし、前回検出からの経過時間でBPMを計算。直近3拍の加重平均(0.4:0.3:0.3)で安定化します。
最終版コード
#define samp_siz 4
#define rise_threshold 4
int sensorPin = A0;
void setup() { Serial.begin(9600); }
void loop() {
float reads[samp_siz], sum = 0;
long now, ptr = 0;
float last, reader, start;
float first, second, third, before, print_value;
bool rising = false;
int rise_count = 0;
int n;
long last_beat = 0;
for (int i = 0; i < samp_siz; i++) reads[i] = 0;
while(1) {
// 20ms区間で平均を取り50Hzノイズ除去
n = 0; start = millis(); reader = 0;
do {
reader += analogRead(sensorPin);
n++;
now = millis();
} while (now < start + 20);
reader /= n;
// 移動平均配列を更新
sum -= reads[ptr];
sum += reader;
reads[ptr] = reader;
last = sum / samp_siz;
// 立ち上がり検出
if (last > before) {
rise_count++;
if (!rising && rise_count > rise_threshold) {
rising = true;
first = millis() - last_beat;
last_beat = millis();
// 加重平均でBPM計算
print_value = 60000.0 / (0.4 * first + 0.3 * second + 0.3 * third);
Serial.println(print_value);
third = second;
second = first;
}
} else {
rising = false;
rise_count = 0;
}
before = last;
ptr = (ptr + 1) % samp_siz;
}
}
動作確認動画も用意しています。ArduinoのRX LEDが心拍に同期して点滅します。
今後の発展
直近15秒分のBPMを蓄積し、外れ値を除外した平均を取るなど、より堅牢な算出ロジックへの改良が可能です。また、心拍数が180-200 BPMの場合など、立ち上がり検出が困難になるケースへの対応も検討課題です。
回路図

製造プロセス
- ppDAQC Pi-PlateからInitialStateへ温度データをストリーミング - ヘッドレスRaspberry Piで実現
- Raspberry PiとDS18B20でマルチセンサー温度・光監視システムを構築
- 4ドルのソーラーライトをスマートワイヤレスセンサーノードに変身: MSP430 + nRF24L01+で庭園監視
- Raspberry PiとTwilioで実現するトイレ占有センサー:音声通話とSMSで通知
- Windows 10 IoT Core on Raspberry Piで心拍パルスを読み取る - ステップバイステップガイド
- Raspberry Pi光センサーチュートリアル - LDRを配線してPythonで光量を読み取る
- デジタル光センサー:Windows 10 IoT Coreで周囲光に応じてLEDを制御
- リモート心拍数監視システム:AWS IoTアラート付き
- カラーセンサー:仕組みと主要応用
- OPT3007超薄型環境光センサー:スマートデバイス向け精密光測定
- 環境光センサー:機能、設計、主要アプリケーション