velxio/test/test_100_days/Pulse_Monitor/source/main.py

78 lines
2.0 KiB
Python

from machine import ADC, Pin, SoftI2C
import ssd1306
import time
# OLED setup
i2c = SoftI2C(scl=Pin(22), sda=Pin(21))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# Sensor setup
sensor = ADC(Pin(34))
sensor.atten(ADC.ATTN_11DB)
# BPM variables
THRESHOLD = 2500
MIN_PEAK_INTERVAL = 300
last_peak_time = 0
peak_times = []
bpm = 0
# Graph buffer
graph = [0] * 80
def draw_heart(x, y):
oled.pixel(x+1, y, 1); oled.pixel(x+2, y, 1)
oled.pixel(x+4, y, 1); oled.pixel(x+5, y, 1)
oled.pixel(x, y+1, 1); oled.pixel(x+1, y+1, 1)
oled.pixel(x+2, y+1, 1); oled.pixel(x+3, y+1, 1)
oled.pixel(x+4, y+1, 1); oled.pixel(x+5, y+1, 1)
oled.pixel(x+6, y+1, 1)
oled.pixel(x+1, y+2, 1); oled.pixel(x+2, y+2, 1)
oled.pixel(x+3, y+2, 1); oled.pixel(x+4, y+2, 1)
oled.pixel(x+5, y+2, 1)
oled.pixel(x+2, y+3, 1); oled.pixel(x+3, y+3, 1)
oled.pixel(x+4, y+3, 1)
oled.pixel(x+3, y+4, 1)
while True:
value = sensor.read()
current_time = time.ticks_ms()
# Peak detection
if value > THRESHOLD:
if time.ticks_diff(current_time, last_peak_time) > MIN_PEAK_INTERVAL:
last_peak_time = current_time
peak_times.append(current_time)
if len(peak_times) > 10:
peak_times.pop(0)
if len(peak_times) >= 2:
intervals = [time.ticks_diff(peak_times[i+1], peak_times[i])
for i in range(len(peak_times)-1)]
avg_interval = sum(intervals) / len(intervals)
bpm = int(60000 / avg_interval)
# Update graph buffer
graph_val = int((value / 4095) * 30)
graph.pop(0)
graph.append(graph_val)
# Draw OLED
oled.fill(0)
# Draw waveform (top half)
for i in range(len(graph) - 1):
y1 = 32 - graph[i]
y2 = 32 - graph[i+1]
oled.line(i + 48, y1, i + 49, y2, 1)
# Divider line
oled.hline(0, 38, 128, 1)
# Heart symbol + BPM (bottom half)
draw_heart(4, 44)
oled.text(": " + str(bpm) + " BPM", 14, 45)
oled.show()
time.sleep_ms(10)