This is the BH1790GLC an Optical Hearth Rate Monitor Sensor developed by ROHM semiconductor. This sensor has an integrated optical and LED driver design to detect green light photo diode. This device drives LED and provides an intensity of light reflected from the human skin. The LED brightness can be adjust by LED driver current and light emitting period. The device photodiode has a high sensitivity for a green light, excellent wavelength selectivity and excellent IRcut characteristics that achieves accurate pulse wave detection. This device runs on 3v and uses I2C/TWI protocol for ease of control. This device is suitable for Wearable Device, Smart Phones, Tablets, Smart Watch, Smart Head Gears, Exercise Equipment & Fitness, Smart Suits and Mobile Medical Equipment’s. For more details and data communicate address please refer to the datasheet.
Required Components
- Arduino IDE | Atmel Studio | Energia | Processing
- Arduino PRO, FIO, NANO, UNO, MINI, MEGA, PRO MINI, LEO, BT, DUE, ETHERNET,LILYPAD, NodeMCU, Teensy Board, TeensyDuino, ESP8266 12, 12E, ESP32, LinkItOne, ESP8266 NodeMCU, ESPDuino, ATMEGA328 16/12, ATMEGA32u4 16/8/ MHz, ESP8266, MSP430 ,ATMEGA250 16 MHz, ATSAM3x8E, STM32.
- Note: For AVR (If your using AVR please see the flash size of the MCU)
- Note: The Diagram below is using NANO. (please refer to each MCU’s respective pin-outs & bus configurations)
- ROHM BH1790GLC Optical Heart Rate Monitor Sensor
- Step-down Voltage Regulator (See below required values)
- Capacitors (See below required values)
- Resistors (See below required values)
- PCB Designer (Circuit simulation to PCB Layout)
Wiring Guide
Source Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
#include <avr/sleep.h> #include <Wire.h> #include <FlexiTimer2.h> extern "C" { #include <bh1792.h> } bh1792_t senseBH1792; bh1792_data_t senseBH1792_DATA; void timer_isr(void); void bh1792_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); void setup() { int32_t ret = 0; set_sleep_mode(SLEEP_MODE_IDLE); Serial.begin(115200); Serial.println("14CORE | BH1790GLC Optical Heart Rate Monitor Sensor Test Code"); Serial.println("Initializing.................................................."); delay(4000); while (!Serial); Wire.begin(); Wire.setClock(400000L); senseBH1792.fnWrite = i2c_write; senseBH1792.fnRead = i2c_read; ret = bh1792_Init(&m_bh1792); error_check(ret, "bh1792_Init"); senseBH1792.prm.sel_adc = BH1792_PRM_SEL_ADC_GREEN; senseBH1792.prm.msr = BH1792_PRM_MSR_SINGLE;//BH1792_PRM_MSR_1024HZ; senseBH1792.prm.led_en = (BH1792_PRM_LED_EN1_0 << 1) | BH1792_PRM_LED_EN2_0; senseBH1792.prm.led_cur1 = BH1792_PRM_LED_CUR1_MA(1); senseBH1792.prm.led_cur2 = BH1792_PRM_LED_CUR2_MA(0); senseBH1792.prm.ir_th = 0xFFFC; senseBH1792.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"); attachInterrupt(0, bh1792_isr, LOW); FlexiTimer2::stop(); if (m_bh1792.prm.msr <= BH1792_PRM_MSR_1024HZ) { FlexiTimer2::set(2000, 5.0/10000, timer_isr); // 1Hz timer } else { FlexiTimer2::set(250, 1.0/8000, timer_isr); // 32Hz timer } FlexiTimer2::start(); } void loop() { sleep_mode(); } void timer_isr(void) { int32_t ret = 0; uint8_t tmp_eimsk; tmp_eimsk = EIMSK; EIMSK = 0; interrupts(); 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) { tmp_eimsk = 0; } else { ret = bh1792_ClearFifoData(); error_check(ret, "bh1792_ClearFifoData"); tmp_eimsk = bit(INT0); } } } else { ret = bh1792_StartMeasure(); error_check(ret, "bh1792_StartMeasure"); } noInterrupts(); EIMSK |= tmp_eimsk; } void bh1792_isr(void) { int32_t ret = 0; uint8_t i = 0; EIMSK = 0; interrupts(); ret = bh1792_GetMeasData(&senseBH1792_DATA); error_check(ret, "bh1792_GetMeasData"); if(m_bh1792.prm.msr <= BH1792_PRM_MSR_1024HZ) { for (i = 0; i < senseBH1792_DATA.fifo_lev; i++) { Serial.print(senseBH1792_DATA.fifo[i].on, DEC); Serial.print(F(",")); Serial.println(senseBH1792_DATA.fifo[i].off, DEC); } } else { if(m_bh1792.prm.sel_adc == BH1792_PRM_SEL_ADC_GREEN) { Serial.print(senseBH1792_DATA.green.on, DEC); Serial.print(F(",")); Serial.println(senseBH1792_DATA.green.off, DEC); } else { Serial.print(senseBH1792_DATA.ir.on, DEC); Serial.print(F(",")); Serial.println(senseBH1792_DATA.ir.off, DEC); } } noInterrupts(); EIMSK = bit(INT0); } int32_t i2c_write(uint8_t slv_adr, uint8_t reg_adr, uint8_t *reg, uint8_t reg_size) //I2C should completed within 0.5ms see datasheet { byte rc; if (m_bh1792.prm.msr <= BH1792_PRM_MSR_1024HZ) { if((slv_adr != BH1792_SLAVE_ADDR) || (reg_adr != BH1792_ADDR_MEAS_SYNC)) { while(FlexiTimer2::count == 1999); } } Wire.beginTransmission(slv_adr); Wire.write(reg_adr); Wire.write(reg, reg_size); rc = Wire.endTransmission(true); return rc; } int32_t i2c_read(uint8_t slv_adr, uint8_t reg_adr, uint8_t *reg, uint8_t reg_size) //I2C should completed within 0.5ms see datasheet { byte rc; uint8_t cnt; if (m_bh1792.prm.msr <= BH1792_PRM_MSR_1024HZ) { while(FlexiTimer2::count == 1999); } 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) //ERROR HANDLER { 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); } } |
Downloads
- BH1790GLC Optical Heart Rate Monitor Sensor Arduino Library
- BH1790GLC Optical Heart Rate Monitor Datasheet
While using Nodemcu – flexitimer2.h i get a error as
\arduino-1.8.5\libraries\FlexiTimer2/FlexiTimer2.h:7:2: error: #error FlexiTimer2 library only works on AVR architecture
#error FlexiTimer2 library only works on AVR architecture
Do u have any alternative for this?
Have you try to use timer2/mstimer2 instead of using flexitimer2?
https://playground.arduino.cc/Main/MsTimer2
When I using Wemos D1- flexitimer2 and mstimer2 is not working!!
“” library only works on AVR architecture””
And i found esp8266 is use “SimpleTimer.h”, but i don’t know to change HeartRate.ino code!
please help me!!!!!
Hi! try this code library.
https://www.14core.com/wp-content/uploads/2019/05/BH1790GLC_HeartRate_Library.zip
Sorry, the BH1790GLC_HeartRate code is still not working in “Wemos D1”.
They still display “” library only works on AVR architecture”” and “#error FlexiTimer2 library only works on AVR architecture”.
Please, Thanks!
i have this error when compiling:
m_bh1792′ was not declared in this scope.
Can advice? Am i missing some libraries?
change it to senseBH1792, note m_bh1792 is a variable declared in the i2c library just to senseBH1792.
Hi ineed help as well , when i charge the program i dont get values , iget like this “§§§§ùùùù????????????????????????????????????????????”
idont undersand why
Check or log to serial mon, check if you get the correct value? or change the encoding.