Heart rate monitor ・ 心率监测
指先にセンサーを当てて心拍数と血中酸素濃度を測定します。
この構成をエディタで開く・編集する →| 部品 | 役割 | ポート | リンク・価格 |
|---|---|---|---|
| M5Stack Core2 | Controller | grove_i2c, grove_analog, grove_uart, mbus | official page — $46.9 |
| Unit Heart | Heart rate / SpO2 sensor | grove_i2c | official page — $9.95 |
M5Stack Core2とUnit Heart(MAX30100)で作る、指先で心拍数と血中酸素濃度(SpO2)を測定する装置です。センサーに指を置くだけで、リアルタイムに測定値を画面に表示します。
# M5Stack Core2 + Unit Heart (MAX30100) fingertip heart rate & SpO2 monitor
# Wiring: Unit Heart -> Core2 red Port.A (I2C)
import time
from machine import Pin, I2C
from m5stack import lcd
# Initialize I2C on Port.A (Core2: SDA=21, SCL=22)
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
# MAX30100 I2C address is 0x57
MAX30100_ADDR = 0x57
# Register addresses
REG_INTR_STATUS_1 = 0x00
REG_INTR_STATUS_2 = 0x01
REG_INT_ENABLE_1 = 0x02
REG_INT_ENABLE_2 = 0x03
REG_FIFO_WR_PTR = 0x04
REG_OVF_COUNTER = 0x05
REG_FIFO_RD_PTR = 0x06
REG_FIFO_DATA = 0x07
REG_MODE_CONFIG = 0x09
REG_SPO2_CONFIG = 0x0A
REG_LED_CONFIG = 0x0C
REG_TEMP_INTEGER = 0x16
REG_TEMP_FRACTION = 0x17
REG_REVISION_ID = 0xFE
REG_PART_ID = 0xFF
def write_reg(reg, value):
i2c.writeto_mem(MAX30100_ADDR, reg, bytes([value]))
def read_reg(reg):
return i2c.readfrom_mem(MAX30100_ADDR, reg, 1)[0]
def read_fifo():
data = i2c.readfrom_mem(MAX30100_ADDR, REG_FIFO_DATA, 4)
# data[0:2] = IR, data[2:4] = Red
ir = (data[0] << 8) | data[1]
red = (data[2] << 8) | data[3]
return ir, red
def setup_sensor():
# Reset
write_reg(REG_MODE_CONFIG, 0x40)
time.sleep(0.1)
# Set mode to SpO2/HR (0x03)
write_reg(REG_MODE_CONFIG, 0x03)
# Configure SPO2: 100Hz, 1600us pulse width, 14.2mA LED current
write_reg(REG_SPO2_CONFIG, 0x27) # 0b00100111
# Enable all interrupts
write_reg(REG_INT_ENABLE_1, 0xE0) # A_FULL, PPG_RDY, ALC_OVF
write_reg(REG_INT_ENABLE_2, 0x00)
# Set LED currents: IR=50mA, Red=50mA
write_reg(REG_LED_CONFIG, 0x7F) # 0b01111111
# Clear FIFO
write_reg(REG_FIFO_WR_PTR, 0x00)
write_reg(REG_OVF_COUNTER, 0x00)
write_reg(REG_FIFO_RD_PTR, 0x00)
def read_temp():
integer = read_reg(REG_TEMP_INTEGER)
fraction = read_reg(REG_TEMP_FRACTION)
return integer + fraction * 0.0625
# Simple heart rate detection (basic peak detection)
class HeartRateMonitor:
def __init__(self):
self.buffer = []
self.bpm = 0
self.spo2 = 0
self.last_beat = 0
self.ir_prev = 0
self.threshold = 50000 # adjust based on signal
def process(self, ir, red):
# Simple peak detection
if ir > self.threshold and self.ir_prev <= self.threshold:
now = time.ticks_ms()
if self.last_beat > 0:
interval = now - self.last_beat
if 300 < interval < 2000: # 30-200 BPM
self.bpm = 60000 // interval
self.last_beat = now
self.ir_prev = ir
# SpO2 estimation (very basic)
if ir > 0 and red > 0:
ratio = red / ir
self.spo2 = 110 - 25 * ratio # rough approximation
if self.spo2 > 100:
self.spo2 = 100
if self.spo2 < 0:
self.spo2 = 0
else:
self.spo2 = 0
setup_sensor()
lcd.clear()
lcd.print('Place finger...', 10, 20)
monitor = HeartRateMonitor()
while True:
# Check interrupt status
status = read_reg(REG_INTR_STATUS_1)
if status & 0x40: # PPG_RDY
# Read all available samples (up to 32)
for _ in range(32):
ir, red = read_fifo()
if ir > 0 or red > 0:
monitor.process(ir, red)
# Display
lcd.clear()
if monitor.bpm > 0:
lcd.print('HR: %d BPM' % monitor.bpm, 10, 20)
lcd.print('SpO2: %d %%' % monitor.spo2, 10, 60)
else:
lcd.print('No finger', 10, 20)
# Clear interrupt
write_reg(REG_INTR_STATUS_1, 0xFF)
time.sleep(0.01)
この作り方はAIが構成から生成したものです(未検証)。通電前に配線とコードをご確認ください。
この構成はAIが実在するM5Stack部品から設計し、ポート互換をサーバで検証したものです。編集・共有できます。
エディタで開く →UnitKit は M5Stack® 製品向けの非公式ツール。作りたいものを書くと、部品リストと配線図が出ます。