GR-SAKURA
GR-KURUMI
GR-COTTON
GR-CITRUS
GR-PEACH
GR-KAEDE
GR-ADZUKI
GR-LYCHEE
GR-ROSE
GR-MANGO(*)
SNShield
Web Compiler
IDE for GR
TOPPERS関連
女子美コラボ
その他
※プロデューサミーティング中
作り方使い方資料
イベント関連
作品記事
体験記事
ライブラリ
ツール
その他・過去ファイル
GR LYCHEEデザインコンテスト2018でもオプションで提供している脈拍センサー「BH1792GLC」を試してみました。
使うときの手順を簡単に記載します。
1. 以下のロームのページにArduino用サンプルがありますので、zipをダウンロードします。
https://www.rohm.co.jp/sensor-shield-support/pulse-wave-sensor2
2. Webコンパイラか、IDE for GRにインポートします。
3. 写真を参考に以下のように接続します。
4. 以下に示すプログラムを実行します。
脈拍モジュールを指で軽く押さえ、Arduino IDEのSerial Ploterで表示すると、以下のように表示されます。ボーレートは115200bpsです。
ちなみに、ロームさんのexampleはGR-LYCHEEでは動きません。割り込み処理でネイティブのコードを使った処理をしており、Mbed OSとの相性がよくなかったです。
またFlexiTimer2を使ってますが、ここはGR-LYCHEEでデフォルトで使えるMsTimer2に置き換えました。
サンプルが結構複雑な感じなので、理解するのに苦労するのですが、興味ある方は試して活用してみていただければ嬉しく思います。
#include <Arduino.h>#include <Wire.h>#include <MsTimer2.h>extern "C" {#include <bh1792.h>}bh1792_t m_bh1792;bh1792_data_t m_bh1792_dat;#define INTPIN 13void timer_isr(void);int32_t i2c_write(uint8_t slv_adr, uint8_t reg_adr, uint8_t *reg, uint8_t reg_size);int32_t i2c_read(uint8_t slv_adr, uint8_t reg_adr, uint8_t *reg, uint8_t reg_size);void error_check(int32_t ret, String msg);bool g_timer_on = false;void setup() { int32_t ret = 0; pinMode(PIN_LED_RED, OUTPUT); pinMode(PIN_LED_ORANGE, OUTPUT); pinMode(INTPIN, INPUT_PULLUP); // Serial Port Serial.begin(115200); while (!Serial); // I2C Wire.begin(); Wire.setFrequency(400000L); // BH1792 m_bh1792.fnWrite = i2c_write; m_bh1792.fnRead = i2c_read; ret = bh1792_Init(&m_bh1792); error_check(ret, "bh1792_Init"); m_bh1792.prm.sel_adc = BH1792_PRM_SEL_ADC_GREEN; m_bh1792.prm.msr = BH1792_PRM_MSR_SINGLE;//BH1792_PRM_MSR_1024HZ; m_bh1792.prm.led_en = (BH1792_PRM_LED_EN1_0 << 1) | BH1792_PRM_LED_EN2_0; m_bh1792.prm.led_cur1 = BH1792_PRM_LED_CUR1_MA(1); m_bh1792.prm.led_cur2 = BH1792_PRM_LED_CUR2_MA(0); m_bh1792.prm.ir_th = 0xFFFC; m_bh1792.prm.int_sel = BH1792_PRM_INT_SEL_SGL;//BH1792_PRM_INT_SEL_WTM; ret = bh1792_SetParams(); error_check(ret, "bh1792_SetParams"); Serial.println(F("GDATA(@LED_ON),GDATA(@LED_OFF)")); ret = bh1792_StartMeasure(); error_check(ret, "bh1792_StartMeasure"); MsTimer2::stop(); if (m_bh1792.prm.msr <= BH1792_PRM_MSR_1024HZ) { MsTimer2::set(1000, timer_isr); // 1Hz timer } else { MsTimer2::set(33, timer_isr); // 32Hz timer } MsTimer2::start();}void loop() { if(g_timer_on){ digitalWrite(PIN_LED_RED, HIGH); int32_t ret = 0; if (m_bh1792.prm.msr <= BH1792_PRM_MSR_1024HZ) { ret = bh1792_SetSync(); error_check(ret, "bh1792_SetSync"); if (m_bh1792.sync_seq < 3) { if (m_bh1792.sync_seq == 1) { } else { ret = bh1792_ClearFifoData(); error_check(ret, "bh1792_ClearFifoData"); } } } else { ret = bh1792_StartMeasure(); error_check(ret, "bh1792_StartMeasure"); } g_timer_on = false; } if(digitalRead(INTPIN) == LOW){ digitalWrite(PIN_LED_ORANGE, HIGH); int32_t ret = 0; uint8_t i = 0; ret = bh1792_GetMeasData(&m_bh1792_dat); error_check(ret, "bh1792_GetMeasData"); if(m_bh1792.prm.msr <= BH1792_PRM_MSR_1024HZ) { for (i = 0; i < m_bh1792_dat.fifo_lev; i++) { Serial.print(m_bh1792_dat.fifo[i].on, DEC); Serial.print(F(",")); Serial.println(m_bh1792_dat.fifo[i].off, DEC); } } else { if(m_bh1792.prm.sel_adc == BH1792_PRM_SEL_ADC_GREEN) { Serial.print(m_bh1792_dat.green.on, DEC); Serial.print(F(",")); Serial.println(m_bh1792_dat.green.off, DEC); } else { Serial.print(m_bh1792_dat.ir.on, DEC); Serial.print(F(",")); Serial.println(m_bh1792_dat.ir.off, DEC); } } } delay(5);}void timer_isr(void) { g_timer_on = true;}// Note: I2C access should be completed within 0.5msint32_t i2c_write(uint8_t slv_adr, uint8_t reg_adr, uint8_t *reg, uint8_t reg_size){ byte rc; if (m_bh1792.prm.msr <= BH1792_PRM_MSR_1024HZ) { if((slv_adr != BH1792_SLAVE_ADDR) || (reg_adr != BH1792_ADDR_MEAS_SYNC)) { while(MsTimer2::count >= 999); } } Wire.beginTransmission(slv_adr); Wire.write(reg_adr); Wire.write(reg, reg_size); rc = Wire.endTransmission(true); return rc;}// Note: I2C access should be completed within 0.5msint32_t i2c_read(uint8_t slv_adr, uint8_t reg_adr, uint8_t *reg, uint8_t reg_size){ byte rc; uint8_t cnt; if (m_bh1792.prm.msr <= BH1792_PRM_MSR_1024HZ) { while(MsTimer2::count >= 999); } Wire.beginTransmission(slv_adr); Wire.write(reg_adr); rc = Wire.endTransmission(false); if (rc == 0) { Wire.requestFrom((int32_t)slv_adr, (int32_t)reg_size, true); cnt = 0; while(Wire.available()) { reg[cnt] = Wire.read(); cnt++; } if(cnt < reg_size) { rc = 4; } } return rc;}void error_check(int32_t ret, String msg){ if(ret < 0) { msg = "Error: " + msg; msg += " function"; Serial.println(msg); Serial.print("ret = "); Serial.println(ret, DEC); if(ret == BH1792_I2C_ERR) { Serial.print("i2c_ret = "); Serial.println(m_bh1792.i2c_err, DEC); } while(1); }}
すみません、元々のサンプルの波形はロームさんの以下ですが(最後の方に出てきます)、こちらで編集したものは5ms周期でINT端子をポーリングしているため、カクカクしたり、位相ずれが起きているかもしれません。