Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • card10/firmware
  • annejan/firmware
  • astro/firmware
  • fpletz/firmware
  • gerd/firmware
  • fleur/firmware
  • swym/firmware
  • l/firmware
  • uberardy/firmware
  • wink/firmware
  • madonius/firmware
  • mot/firmware
  • filid/firmware
  • q3k/firmware
  • hauke/firmware
  • Woazboat/firmware
  • pink/firmware
  • mossmann/firmware
  • omniskop/firmware
  • zenox/firmware
  • trilader/firmware
  • Danukeru/firmware
  • shoragan/firmware
  • zlatko/firmware
  • sistason/firmware
  • datenwolf/firmware
  • bene/firmware
  • amedee/firmware
  • martinling/firmware
  • griffon/firmware
  • chris007/firmware
  • adisbladis/firmware
  • dbrgn/firmware
  • jelly/firmware
  • rnestler/firmware
  • mh/firmware
  • ln/firmware
  • penguineer/firmware
  • monkeydom/firmware
  • jens/firmware
  • jnaulty/firmware
  • jeffmakes/firmware
  • marekventur/firmware
  • pete/firmware
  • h2obrain/firmware
  • DooMMasteR/firmware
  • jackie/firmware
  • prof_r/firmware
  • Draradech/firmware
  • Kartoffel/firmware
  • hinerk/firmware
  • abbradar/firmware
  • JustTB/firmware
  • LuKaRo/firmware
  • iggy/firmware
  • ente/firmware
  • flgr/firmware
  • Lorphos/firmware
  • matejo/firmware
  • ceddral7/firmware
  • danb/firmware
  • joshi/firmware
  • melle/firmware
  • fitch/firmware
  • deurknop/firmware
  • sargon/firmware
  • markus/firmware
  • kloenk/firmware
  • lucaswerkmeister/firmware
  • derf/firmware
  • meh/firmware
  • dx/card10-firmware
  • torben/firmware
  • yuvadm/firmware
  • AndyBS/firmware
  • klausdieter1/firmware
  • katzenparadoxon/firmware
  • xiretza/firmware
  • ole/firmware
  • techy/firmware
  • thor77/firmware
  • TilCreator/firmware
  • fuchsi/firmware
  • dos/firmware
  • yrlf/firmware
  • PetePriority/firmware
  • SuperVirus/firmware
  • sur5r/firmware
  • tazz/firmware
  • Alienmaster/firmware
  • flo_h/firmware
  • baldo/firmware
  • mmu_man/firmware
  • Foaly/firmware
  • sodoku/firmware
  • Guinness/firmware
  • ssp/firmware
  • led02/firmware
  • Stormwind/firmware
  • arist/firmware
  • coon/firmware
  • mdik/firmware
  • pippin/firmware
  • royrobotiks/firmware
  • zigot83/firmware
  • mo_k/firmware
106 results
Select Git revision
Show changes
Commits on Source (2)
......@@ -97,6 +97,7 @@ autodoc_mock_imports = [
"ucollections",
"urandom",
"utime",
"vibra",
]
autodoc_member_order = "bysource"
......
......@@ -26,6 +26,7 @@ Last but not least, if you want to start hacking the lower-level firmware, the
pycardium/bme680
pycardium/max30001
pycardium/buttons
pycardium/button_gestures
pycardium/color
pycardium/display
pycardium/gpio
......
``button_gestures`` - Button Gesture Detection
==============================================
.. automodule:: button_gestures
:members:
import button_gestures as bg
import os
import display
import leds
......@@ -26,17 +27,23 @@ COLOR_WRITE_FG = [255, 255, 255]
COLOR_WRITE_BG = [255, 0, 0]
current_mode = MODE_FINGER
# FIFO from callback
new_datasets = []
history = []
filebuffer = bytearray()
write = 0
recording_timestamp = 0
bias = True
update_screen = 0
samples_since_draw = 0
pause_screen = 0
pause_histogram = False
histogram_offset = 0
sensor = 0
disp = display.open()
mapper = bg.ActionMapper()
KEYMAP_PAUSED = {}
KEYMAP_NORMAL = {}
leds.dim_top(1)
COLORS = [((23 + (15 * i)) % 360, 1.0, 1.0) for i in range(11)]
......@@ -47,9 +54,9 @@ alpha = 2
beta = 3
def update_history(datasets):
def update_history(samples):
global history, moving_average, alpha, beta
for val in datasets:
for val in samples:
history.append(val - moving_average)
moving_average = (alpha * moving_average + beta * val) / (alpha + beta)
......@@ -75,8 +82,8 @@ def neighbours(n, lst):
yield lst[i : i + n]
def detect_pulse(num_new_samples):
global history, pulse, samples_since_last_pulse, q_threshold, r_threshold, q_spike
def detect_pulse(all_samples, num_new_samples):
global pulse, samples_since_last_pulse, q_threshold, r_threshold, q_spike
# look at 3 consecutive samples, starting 2 samples before the samples that were just added, e.g.:
# existing samples: "ABCD"
......@@ -84,7 +91,7 @@ def detect_pulse(num_new_samples):
# consider ["CDE", "DEF"]
# new samples: "GHI" => "ABCDEFGHI"
# consider ["EFG", "FGH", "GHI"]
for [prev, cur, next_] in neighbours(3, history[-(num_new_samples + 2) :]):
for [prev, cur, next_] in neighbours(3, all_samples[-(num_new_samples + 2) :]):
samples_since_last_pulse += 1
if prev > cur < next_ and cur < q_threshold:
......@@ -110,32 +117,36 @@ def detect_pulse(num_new_samples):
pulse = -1
def callback_ecg(datasets):
global update_screen, history, filebuffer, write
update_screen += len(datasets)
def callback_ecg(dataset):
new_datasets.append(dataset)
def process_samples(samples):
global samples_since_draw, history, filebuffer, recording_timestamp
samples_since_draw += len(samples)
# update histogram datalist
if not pause_histogram:
update_history(datasets)
detect_pulse(len(datasets))
update_history(samples)
detect_pulse(history, len(samples))
# buffer for writes
if write > 0:
for value in datasets:
if recording_timestamp > 0:
for value in samples:
filebuffer.extend(struct.pack("h", value))
if len(filebuffer) >= FILEBUFFERBLOCK:
write_filebuffer()
# don't update on every callback
if update_screen >= DRAW_AFTER_SAMPLES:
if samples_since_draw >= DRAW_AFTER_SAMPLES:
draw_histogram()
samples_since_draw = 0
def write_filebuffer():
global write, filebuffer
global recording_timestamp, filebuffer
# write to file
chars = ""
lt = utime.localtime(write)
lt = utime.localtime(recording_timestamp)
filename = "/ecg-{:04d}-{:02d}-{:02d}_{:02d}{:02d}{:02d}.log".format(*lt)
# write stuff to disk
......@@ -145,7 +156,7 @@ def write_filebuffer():
f.close()
except OSError as e:
print("Please check the file or filesystem", e)
write = 0
recording_timestamp = 0
pause_screen = -1
disp.clear(COLOR_BACKGROUND)
disp.print("IO Error", posy=0, fg=COLOR_TEXT)
......@@ -156,7 +167,7 @@ def write_filebuffer():
close_sensor()
except:
print("Unexpected error, stop writeing logfile")
write = 0
recording_timestamp = 0
filebuffer = bytearray()
......@@ -172,8 +183,8 @@ def open_sensor():
def close_sensor():
global sensor
sensor.close()
pass
def toggle_mode():
......@@ -191,30 +202,52 @@ def toggle_bias():
def toggle_write():
global write, disp, pause_screen
global recording_timestamp, disp, pause_screen
pause_screen = utime.time_ms() + 1000
disp.clear(COLOR_BACKGROUND)
if write > 0:
if recording_timestamp > 0:
write_filebuffer()
write = 0
recording_timestamp = 0
disp.print("Stop", posx=50, posy=20, fg=COLOR_TEXT)
disp.print("logging", posx=30, posy=40, fg=COLOR_TEXT)
else:
filebuffer = bytearray()
write = utime.time()
recording_timestamp = utime.time()
disp.print("Start", posx=45, posy=20, fg=COLOR_TEXT)
disp.print("logging", posx=30, posy=40, fg=COLOR_TEXT)
disp.update()
def toggle_pause():
def set_paused(paused):
global pause_histogram, histogram_offset, history
if pause_histogram:
pause_histogram = False
history = []
pause_histogram = paused
histogram_offset = 0
if paused:
mapper.set_mapping(KEYMAP_PAUSED)
else:
pause_histogram = True
mapper.set_mapping(KEYMAP_NORMAL)
history = []
def scroll_left():
global histogram_offset
l = len(history)
histogram_offset += ECG_RATE / 2
if l - histogram_offset < WIDTH:
histogram_offset = l - WIDTH
def scroll_right():
global histogram_offset
histogram_offset -= ECG_RATE / 2
histogram_offset -= histogram_offset % (ECG_RATE / 2)
if histogram_offset < 0:
histogram_offset = 0
......@@ -226,7 +259,7 @@ def draw_leds(val):
def draw_histogram():
global disp, history, current_mode, bias, write, pause_screen, update_screen
global disp, history, current_mode, bias, recording_timestamp, pause_screen
# skip rendering due to message beeing shown
if pause_screen == -1:
......@@ -294,17 +327,29 @@ def draw_histogram():
)
# announce writing ecg log
if write > 0:
if recording_timestamp > 0:
t = utime.time()
if write > 0 and t % 2 == 0:
if recording_timestamp > 0 and t % 2 == 0:
disp.print("LOG", posx=0, posy=60, fg=COLOR_WRITE_FG, bg=COLOR_WRITE_BG)
disp.update()
update_screen = 0
def main():
global pause_histogram, histogram_offset
global new_datasets, KEYMAP_NORMAL, KEYMAP_PAUSED
KEYMAP_NORMAL = {
(buttons.BOTTOM_LEFT, bg.SHORT_PRESS): toggle_write,
(buttons.BOTTOM_RIGHT, bg.SHORT_PRESS): toggle_bias,
(buttons.TOP_RIGHT, bg.SHORT_PRESS): toggle_mode,
(buttons.TOP_RIGHT, bg.LONG_PRESS): lambda: set_paused(True),
}
KEYMAP_PAUSED = {
(buttons.BOTTOM_LEFT, bg.SHORT_PRESS): scroll_left,
(buttons.BOTTOM_RIGHT, bg.SHORT_PRESS): scroll_right,
(buttons.TOP_RIGHT, bg.SHORT_PRESS): lambda: set_paused(False),
}
# show button layout
disp.clear(COLOR_BACKGROUND)
......@@ -317,71 +362,17 @@ def main():
# start ecg
open_sensor()
while True:
button_pressed = {"BOTTOM_LEFT": 0, "BOTTOM_RIGHT": 0, "TOP_RIGHT": 0}
while True:
v = buttons.read(
buttons.BOTTOM_LEFT | buttons.BOTTOM_RIGHT | buttons.TOP_RIGHT
)
# BOTTOM LEFT
if button_pressed["BOTTOM_LEFT"] == 0 and v & buttons.BOTTOM_LEFT != 0:
button_pressed["BOTTOM_LEFT"] = utime.time_ms()
if not pause_histogram:
toggle_write()
else:
l = len(history)
histogram_offset += ECG_RATE / 2
if l - histogram_offset < WIDTH:
histogram_offset = l - WIDTH
if button_pressed["BOTTOM_LEFT"] > 0 and v & buttons.BOTTOM_LEFT == 0:
duration = utime.time_ms() - button_pressed["BOTTOM_LEFT"]
button_pressed["BOTTOM_LEFT"] = 0
# BOTTOM RIGHT
if button_pressed["BOTTOM_RIGHT"] == 0 and v & buttons.BOTTOM_RIGHT != 0:
button_pressed["BOTTOM_RIGHT"] = utime.time_ms()
if not pause_histogram:
toggle_bias()
else:
histogram_offset -= ECG_RATE / 2
histogram_offset -= histogram_offset % (ECG_RATE / 2)
if histogram_offset < 0:
histogram_offset = 0
if button_pressed["BOTTOM_RIGHT"] > 0 and v & buttons.BOTTOM_RIGHT == 0:
duration = utime.time_ms() - button_pressed["BOTTOM_RIGHT"]
button_pressed["BOTTOM_RIGHT"] = 0
# TOP RIGHT
# down, and still pressed
if button_pressed["TOP_RIGHT"] > 0 and v & buttons.TOP_RIGHT != 0:
duration = utime.time_ms() - button_pressed["TOP_RIGHT"]
if duration > 1000:
button_pressed["TOP_RIGHT"] = -1
toggle_pause()
# register down event
elif button_pressed["TOP_RIGHT"] == 0 and v & buttons.TOP_RIGHT != 0:
button_pressed["TOP_RIGHT"] = utime.time_ms()
# register up event but event already called
if button_pressed["TOP_RIGHT"] == -1 and v & buttons.TOP_RIGHT == 0:
button_pressed["TOP_RIGHT"] = 0
mapper.set_mapping(KEYMAP_NORMAL)
while True:
mapper.update()
# register normal up event
elif button_pressed["TOP_RIGHT"] > 0 and v & buttons.TOP_RIGHT == 0:
duration = utime.time_ms() - button_pressed["TOP_RIGHT"]
button_pressed["TOP_RIGHT"] = 0
if pause_histogram:
toggle_pause()
else:
toggle_mode()
processed_datasets = 0
for dataset in new_datasets:
process_samples(dataset)
processed_datasets += 1
new_datasets = new_datasets[processed_datasets:]
if __name__ == "__main__":
main()
This diff is collapsed.
......@@ -9,6 +9,7 @@ python_modules = files(
'pride.py',
'ledfx.py',
'simple_menu.py',
'button_gestures.py',
# MicroPython Standard-Library
'col_defaultdict.py',
......