ESP-WROOM-02で心拍センサーを動かしてみた [Arduino]
ESP-WROOM-02で心拍センサーを動かしてみました。
ESP-WROOM-02のADCは0Vから1Vの範囲しか測定できないので、3.3Vの心拍センサーの出力をだいたい1/3に分圧して入力しています。
スケッチを設計するポイントは、
・ シグナル値の読み込みに analobRead() 関数ではなく sysytem_adc_read() 関数を使用
・ 割り込みの設定に、timer0_isr_init()、timer0_attachInterrupt()、timer0_write() 関数を使用
・ 時間取得に、ESP.getCycleCount() 関数を使用
の3点です。
さて、きちんと動くかなー?
システムから時間をとっているせいか、Arduno Pro Mini で使ったアルゴリズムよりも精度よく測定しているような気がします。次はいよいよバッテリー駆動にチャレンジかなぁ。
σ(^_^)
ESP-WROOM-02のADCは0Vから1Vの範囲しか測定できないので、3.3Vの心拍センサーの出力をだいたい1/3に分圧して入力しています。
スケッチを設計するポイントは、
・ シグナル値の読み込みに analobRead() 関数ではなく sysytem_adc_read() 関数を使用
・ 割り込みの設定に、timer0_isr_init()、timer0_attachInterrupt()、timer0_write() 関数を使用
・ 時間取得に、ESP.getCycleCount() 関数を使用
の3点です。
extern "C" { #include "user_interface.h" } #define N 10 volatile int BPM; volatile int Signal; volatile int IBI = 600; volatile boolean Pulse = false; volatile boolean QS = false; volatile int Rate[N]; volatile unsigned long CurrBeatTime = 0; volatile unsigned long LastBeatTime = 0; volatile int P = 500; volatile int T = 500; volatile int Threshold = 512; volatile int Amplifier = 100; int PulseSensorPin = 17; int FadePin = 4; int FadeRate = 0; void timer0_ISR (void) { noInterrupts(); Signal = system_adc_read(); CurrBeatTime = getCurrentTime(); // msec unsigned long interval = CurrBeatTime - LastBeatTime; // hold bottom if ((Signal < Threshold) && (interval > (IBI*3) / 5)) { if (Signal < T) { T = Signal; } } // hold peak if (Signal > Threshold && Signal > P) { P = Signal; } if (interval > 250 /* ms */) { // check if Signal is over Threshold if ((Signal > Threshold) && !Pulse && (interval > (IBI*3) / 5)) { Pulse = true; IBI = interval; if (Rate[0] < 0) { // first time Rate[0] = 0; LastBeatTime = getCurrentTime(); setupTimer(10); noInterrupts(); return; } else if (Rate[0] == 0) { // second time for (int i = 0; i < N; ++i) { Rate[i] = IBI; } } word running_total = 0; for (int i = 0; i < N-1; ++i) { Rate[i] = Rate[i+1]; running_total += Rate[i]; } Rate[N-1] = IBI; running_total += IBI; running_total /= N; BPM = 60000 / running_total; QS = true; LastBeatTime = getCurrentTime(); } } // check if Signal is under Threshold if ((Signal < Threshold) && Pulse) { Pulse = false; Amplifier = P - T; Threshold = Amplifier / 2 + T; // revise Threshold P = Threshold; T = Threshold; } // check if no Signal is over 2.5 sec if (interval > 2500 /* ms */) { Threshold = 512; P = 500; T = 500; LastBeatTime = getCurrentTime(); for (int i = 0; i < N; ++i) { Rate[i] = -1; } } setupTimer(10); interrupts(); } void setupTimer(int m /* msec */) { timer0_isr_init(); timer0_attachInterrupt(timer0_ISR); timer0_write(ESP.getCycleCount() + 80000L * m); // 80MHz/1000 == 1msec } unsigned long getCurrentTime() { return ESP.getCycleCount() / 80000L; } void setup() { pinMode(FadePin, OUTPUT); analogWriteRange(255); Serial.begin(115200); noInterrupts(); setupTimer(10); interrupts(); LastBeatTime = getCurrentTime(); // msec } void loop() { if (QS) { FadeRate = 255; Serial.print("BPM: "); Serial.println(BPM); QS = false; } FadeRate -= 15; FadeRate = constrain(FadeRate, 0, 255); analogWrite(FadePin, FadeRate); delay(20); }
さて、きちんと動くかなー?
システムから時間をとっているせいか、Arduno Pro Mini で使ったアルゴリズムよりも精度よく測定しているような気がします。次はいよいよバッテリー駆動にチャレンジかなぁ。
σ(^_^)
コメント 0