Skip to content

Commit 57d5adf

Browse files
authored
Merge pull request adafruit#1079 from jedgarpark/pulse-ox-log
includes RTC date/time and data logging to SD card.
2 parents b9505c6 + 596d77d commit 57d5adf

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
"""
2+
Read data from a BerryMed pulse oximeter, model BM1000C, BM1000E, etc.
3+
Run this on Feather nRF52840
4+
Log data to SD card on Autologger FeatherWing
5+
"""
6+
7+
# Protocol defined here:
8+
# https://github.com/zh2x/BCI_Protocol
9+
# Thanks as well to:
10+
# https://github.com/ehborisov/BerryMed-Pulse-Oximeter-tool
11+
# https://github.com/ScheindorfHyenetics/berrymedBluetoothOxymeter
12+
#
13+
# The sensor updates the readings at 100Hz.
14+
15+
import time
16+
import adafruit_sdcard
17+
import board
18+
import busio
19+
import digitalio
20+
import storage
21+
import adafruit_pcf8523
22+
import _bleio
23+
import adafruit_ble
24+
from adafruit_ble.advertising.standard import Advertisement
25+
from adafruit_ble.services.standard.device_info import DeviceInfoService
26+
from adafruit_ble_berrymed_pulse_oximeter import BerryMedPulseOximeterService
27+
28+
# Logging setup
29+
SD_CS = board.D10
30+
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
31+
cs = digitalio.DigitalInOut(SD_CS)
32+
sd_card = adafruit_sdcard.SDCard(spi, cs)
33+
vfs = storage.VfsFat(sd_card)
34+
storage.mount(vfs, "/sd_card")
35+
36+
log_interval = 2 # you can adjust this to log at a different rate
37+
38+
# RTC setup
39+
I2C = busio.I2C(board.SCL, board.SDA)
40+
rtc = adafruit_pcf8523.PCF8523(I2C)
41+
42+
days = ("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")
43+
44+
set_time = False
45+
if set_time: # change to True if you want to write the time!
46+
# year, mon, date, hour, min, sec, wday, yday, isdst
47+
t = time.struct_time((2020, 4, 21, 18, 13, 0, 2, -1, -1))
48+
# you must set year, mon, date, hour, min, sec and weekday
49+
# yearday not supported, isdst can be set but we don't use it at this time
50+
print("Setting time to:", t) # uncomment for debugging
51+
rtc.datetime = t
52+
print()
53+
54+
# PyLint can't find BLERadio for some reason so special case it here.
55+
ble = adafruit_ble.BLERadio() # pylint: disable=no-member
56+
57+
pulse_ox_connection = None
58+
59+
while True:
60+
t = rtc.datetime
61+
print("Scanning for Pulse Oximeter...")
62+
for adv in ble.start_scan(Advertisement, timeout=5):
63+
name = adv.complete_name
64+
if not name:
65+
continue
66+
# "BerryMed" devices may have trailing nulls on their name.
67+
if name.strip("\x00") == "BerryMed":
68+
pulse_ox_connection = ble.connect(adv)
69+
print("Connected")
70+
break
71+
72+
# Stop scanning whether or not we are connected.
73+
ble.stop_scan()
74+
print("Stopped scan")
75+
76+
try:
77+
if pulse_ox_connection and pulse_ox_connection.connected:
78+
print("Fetch connection")
79+
if DeviceInfoService in pulse_ox_connection:
80+
dis = pulse_ox_connection[DeviceInfoService]
81+
try:
82+
manufacturer = dis.manufacturer
83+
except AttributeError:
84+
manufacturer = "(Manufacturer Not specified)"
85+
try:
86+
model_number = dis.model_number
87+
except AttributeError:
88+
model_number = "(Model number not specified)"
89+
print("Device:", manufacturer, model_number)
90+
else:
91+
print("No device information")
92+
93+
pulse_ox_service = pulse_ox_connection[BerryMedPulseOximeterService]
94+
95+
while pulse_ox_connection.connected:
96+
values = pulse_ox_service.values
97+
if values is not None:
98+
# unpack the message to 'values' list
99+
valid, spo2, pulse_rate, pleth, finger = values
100+
if not valid:
101+
continue
102+
if (
103+
pulse_rate == 255
104+
): # device sends 255 as pulse until it has a valid read
105+
continue
106+
print(
107+
"SpO2: {}% | ".format(spo2),
108+
"Pulse Rate: {} BPM | ".format(pulse_rate),
109+
"Pleth: {}".format(pleth),
110+
)
111+
# print((pleth,)) # uncomment to see graph on Mu plotter
112+
113+
try: # logging to SD card
114+
with open("/sd_card/log.txt", "a") as sdc:
115+
t = rtc.datetime
116+
sdc.write(
117+
"{} {}/{}/{} {}:{}:{} ".format(
118+
days[t.tm_wday],
119+
t.tm_mday,
120+
t.tm_mon,
121+
t.tm_year,
122+
t.tm_hour,
123+
t.tm_min,
124+
t.tm_sec
125+
)
126+
)
127+
sdc.write(
128+
"{}, {}, {:.2f}\n".format(
129+
spo2, pulse_rate, pleth
130+
)
131+
)
132+
133+
time.sleep(log_interval)
134+
except OSError:
135+
pass
136+
except RuntimeError:
137+
pass
138+
except _bleio.ConnectionError:
139+
try:
140+
pulse_ox_connection.disconnect()
141+
except _bleio.ConnectionError:
142+
pass
143+
pulse_ox_connection = None

0 commit comments

Comments
 (0)