Spaces:
Build error
Build error
Xavier L'Heureux
commited on
Modularize & add untested main program
Browse files
demo.py
CHANGED
|
@@ -1,115 +1,39 @@
|
|
| 1 |
-
from periphery import GPIO, PWM, SPI, I2C
|
| 2 |
-
from spidev import SpiDev
|
| 3 |
from time import sleep
|
|
|
|
| 4 |
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
led1_gnd = PWM(1, 0)
|
| 8 |
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
led2_gnd = GPIO("/dev/gpiochip0", 7, "out")
|
| 12 |
|
| 13 |
-
|
| 14 |
-
#led3_B = GPIO("/dev/gpiochip2", 5, "out")
|
| 15 |
-
led3_gnd = GPIO("/dev/gpiochip2", 8, "out")
|
| 16 |
-
|
| 17 |
-
aquisition = GPIO("/dev/gpiochip2", 20, "out")
|
| 18 |
-
|
| 19 |
-
frontend_nrst = GPIO("/dev/gpiochip2", 9, "out")
|
| 20 |
-
frontend_npwdn = GPIO("/dev/gpiochip2", 12, "out")
|
| 21 |
-
frontend_start = GPIO("/dev/gpiochip3", 29, "out")
|
| 22 |
-
frontend_ = SpiDev()
|
| 23 |
-
frontend_.open(0, 0)
|
| 24 |
-
frontend_.max_speed_hz = 8000000
|
| 25 |
-
frontend_.mode = 0b01
|
| 26 |
-
|
| 27 |
-
audio = I2C("/dev/i2c-1")
|
| 28 |
-
AUDIO_ADDR = 0x68
|
| 29 |
-
|
| 30 |
-
aquisition.write(True)
|
| 31 |
-
sleep(0.5)
|
| 32 |
-
aquisition.write(False)
|
| 33 |
-
sleep(0.5)
|
| 34 |
-
aquisition.write(True)
|
| 35 |
|
| 36 |
try:
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
|
| 49 |
-
assert data_in[2] == 0x3E, "Wrong output"
|
| 50 |
-
print("EEG Frontend responsive")
|
| 51 |
-
finally:
|
| 52 |
-
frontend_.close()
|
| 53 |
-
|
| 54 |
-
try:
|
| 55 |
-
for reg in [0x0000, 0x0002, 0x0004, 0x0006, 0x000A, 0x000E, 0x0010, 0x0014, 0x0020, 0x0022, 0x0024, 0x0026, 0x0028, 0x002A, 0x002C, 0x002E, 0x0030, 0x0032, 0x0034, 0x0036, 0x0038, 0x003A, 0x003C, 0x0100, 0x0102, 0x0104, 0x0106, 0x0108, 0x010A, 0x010C, 0x010E, 0x0110, 0x0116]:
|
| 56 |
-
msgs = [I2C.Message([reg >> 8, reg & 0xFF]), I2C.Message([0x00, 0x00], read=True)]
|
| 57 |
-
audio.transfer(AUDIO_ADDR, msgs)
|
| 58 |
-
print("0x{:04x}: 0x{:02x} 0x{:02x}".format(reg, msgs[1].data[0], msgs[1].data[1]))
|
| 59 |
-
finally:
|
| 60 |
-
audio.close()
|
| 61 |
-
|
| 62 |
-
state = 0
|
| 63 |
-
try:
|
| 64 |
-
led1_R.frequency = 1e3
|
| 65 |
-
led1_R.enable()
|
| 66 |
-
led1_B.frequency = 1e3
|
| 67 |
-
led1_B.enable()
|
| 68 |
-
led1_gnd.frequency = 1e3
|
| 69 |
-
led1_gnd.enable()
|
| 70 |
-
led1_gnd.duty_cycle = 0.0
|
| 71 |
-
for i in range(200):
|
| 72 |
-
led1_R.duty_cycle = (state % 10) / 10
|
| 73 |
-
led1_B.duty_cycle = (state // 10) / 10
|
| 74 |
-
state = (state + 1) % 100
|
| 75 |
-
sleep(0.02)
|
| 76 |
-
finally:
|
| 77 |
-
led1_R.duty_cycle = 0.0
|
| 78 |
-
led1_R.close()
|
| 79 |
-
led1_B.duty_cycle = 0.0
|
| 80 |
-
led1_B.close()
|
| 81 |
-
led1_gnd.duty_cycle = 0.0
|
| 82 |
-
led1_gnd.close()
|
| 83 |
-
|
| 84 |
-
state = 0
|
| 85 |
-
try:
|
| 86 |
-
led2_gnd.write(False)
|
| 87 |
-
for i in range(12):
|
| 88 |
-
led2_R.write(state % 2 == 1)
|
| 89 |
-
led2_B.write(state // 2 == 1)
|
| 90 |
-
state = (state + 1) % 4
|
| 91 |
-
sleep(0.2)
|
| 92 |
-
finally:
|
| 93 |
-
led2_R.write(False)
|
| 94 |
-
led2_R.close()
|
| 95 |
-
led2_B.write(False)
|
| 96 |
-
led2_B.close()
|
| 97 |
-
led2_gnd.write(False)
|
| 98 |
-
led2_gnd.close()
|
| 99 |
-
|
| 100 |
-
state = 0
|
| 101 |
-
try:
|
| 102 |
-
led3_gnd.write(False)
|
| 103 |
-
for i in range(12):
|
| 104 |
-
state = 3
|
| 105 |
-
led3_R.write(state % 2 == 1)
|
| 106 |
-
#led3_B.write(state // 2 == 1)
|
| 107 |
-
state = (state + 1) % 4
|
| 108 |
-
sleep(0.2)
|
| 109 |
finally:
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
#led3_B.write(False)
|
| 113 |
-
#led3_B.close()
|
| 114 |
-
led3_gnd.write(False)
|
| 115 |
-
led3_gnd.close()
|
|
|
|
|
|
|
|
|
|
| 1 |
from time import sleep
|
| 2 |
+
from playsound import playsound
|
| 3 |
|
| 4 |
+
from frontend import Frontend
|
| 5 |
+
from leds import LEDs
|
|
|
|
| 6 |
|
| 7 |
+
frontend = Frontend()
|
| 8 |
+
leds = LEDs()
|
|
|
|
| 9 |
|
| 10 |
+
playsound('sample.mp3')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
try:
|
| 13 |
+
data = frontend.read_reg(0x00, 1)
|
| 14 |
+
assert data == [0x3E], "Wrong output"
|
| 15 |
+
print("EEG Frontend responsive")
|
| 16 |
+
|
| 17 |
+
leds.aquisition(True)
|
| 18 |
+
sleep(0.5)
|
| 19 |
+
leds.aquisition(False)
|
| 20 |
+
sleep(0.5)
|
| 21 |
+
leds.aquisition(True)
|
| 22 |
+
|
| 23 |
+
for i in range(200):
|
| 24 |
+
red = (i % 10) * 10
|
| 25 |
+
blue = ((i % 100) // 10) * 10
|
| 26 |
+
leds.led1(red, 0, blue)
|
| 27 |
+
sleep(0.02)
|
| 28 |
+
|
| 29 |
+
for state in [RED, BLUE, PURPLE, CLOSED] * 3:
|
| 30 |
+
leds.led2(state)
|
| 31 |
+
sleep(0.2)
|
| 32 |
+
|
| 33 |
+
for state in [RED, CLOSED] * 3:
|
| 34 |
+
leds.led3(state)
|
| 35 |
+
sleep(0.2)
|
| 36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
finally:
|
| 38 |
+
frontend.close()
|
| 39 |
+
leds.close()
|
|
|
|
|
|
|
|
|
|
|
|
frontend.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from periphery import GPIO
|
| 2 |
+
from spidev import SpiDev
|
| 3 |
+
|
| 4 |
+
WAKEUP = 0x02
|
| 5 |
+
STANDBY = 0x04
|
| 6 |
+
RESET = 0x06
|
| 7 |
+
START = 0x08
|
| 8 |
+
STOP = 0x0A
|
| 9 |
+
|
| 10 |
+
RDATAC = 0x10
|
| 11 |
+
SDATAC = 0x11
|
| 12 |
+
RDATA = 0x12
|
| 13 |
+
|
| 14 |
+
RREG = 0x20
|
| 15 |
+
WREG = 0x40
|
| 16 |
+
|
| 17 |
+
class Frontend:
|
| 18 |
+
def __init__():
|
| 19 |
+
self.nrst = GPIO("/dev/gpiochip2", 9, "out")
|
| 20 |
+
self.npwdn = GPIO("/dev/gpiochip2", 12, "out")
|
| 21 |
+
self.start = GPIO("/dev/gpiochip3", 29, "out")
|
| 22 |
+
self.dev = SpiDev()
|
| 23 |
+
self.dev.open(0, 0)
|
| 24 |
+
self.dev.max_speed_hz = 8000000
|
| 25 |
+
self.dev.mode = 0b01
|
| 26 |
+
|
| 27 |
+
self.start.write(False)
|
| 28 |
+
self.powerup()
|
| 29 |
+
self.reset()
|
| 30 |
+
self.stop_continuous()
|
| 31 |
+
|
| 32 |
+
def powerup():
|
| 33 |
+
self.pwdn.write(True)
|
| 34 |
+
sleep(0.1)
|
| 35 |
+
|
| 36 |
+
def powerdown():
|
| 37 |
+
self.pwdn.write(False)
|
| 38 |
+
|
| 39 |
+
def reset():
|
| 40 |
+
self.nrst.write(False)
|
| 41 |
+
sleep(0.01)
|
| 42 |
+
self.nrst.write(True)
|
| 43 |
+
sleep(0.1)
|
| 44 |
+
|
| 45 |
+
def read_regs(start, len):
|
| 46 |
+
values = self.dev.xfer([RREG | (start & 0x1F), (len - 1) & 0x1F] + [0x00] * len)
|
| 47 |
+
return values[2:]
|
| 48 |
+
|
| 49 |
+
def write_regs(start, values):
|
| 50 |
+
self.dev.xfer([WREG | (start & 0x1F), (len(values) - 1) & 0x1F] + values)
|
| 51 |
+
|
| 52 |
+
def read(len):
|
| 53 |
+
values = self.dev.xfer([RDATA] + [0x00] * len)
|
| 54 |
+
return values[1:]
|
| 55 |
+
|
| 56 |
+
def start_continuous():
|
| 57 |
+
self.dev.xfer([RDATAC])
|
| 58 |
+
|
| 59 |
+
def stop_continuous():
|
| 60 |
+
self.dev.xfer([SDATAC])
|
| 61 |
+
|
| 62 |
+
def read_continuous(len):
|
| 63 |
+
values = self.dev.xfer([0x00] * len)
|
| 64 |
+
|
| 65 |
+
def close():
|
| 66 |
+
self.dev.close()
|
leds.py
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from periphery import GPIO, PWM
|
| 2 |
+
|
| 3 |
+
class LEDs:
|
| 4 |
+
def __init__():
|
| 5 |
+
self.led1_R = PWM(0, 0)
|
| 6 |
+
self.led1_B = PWM(2, 0)
|
| 7 |
+
self.led1_gnd = PWM(1, 0)
|
| 8 |
+
|
| 9 |
+
self.led2_R = GPIO("/dev/gpiochip0", 8, "out")
|
| 10 |
+
self.led2_B = GPIO("/dev/gpiochip0", 6, "out")
|
| 11 |
+
self.led2_gnd = GPIO("/dev/gpiochip0", 7, "out")
|
| 12 |
+
|
| 13 |
+
self.led3_R = GPIO("/dev/gpiochip2", 0, "out")
|
| 14 |
+
#self.led3_B = GPIO("/dev/gpiochip2", 5, "out")
|
| 15 |
+
self.led3_gnd = GPIO("/dev/gpiochip2", 8, "out")
|
| 16 |
+
|
| 17 |
+
self.aquisition = GPIO("/dev/gpiochip2", 20, "out")
|
| 18 |
+
|
| 19 |
+
# Init LEDs
|
| 20 |
+
# RGBs
|
| 21 |
+
self.led1_R.frequency = 1e3
|
| 22 |
+
self.led1_R.duty_cycle = 0.0
|
| 23 |
+
self.led1_R.enable()
|
| 24 |
+
|
| 25 |
+
self.led1_B.frequency = 1e3
|
| 26 |
+
self.led1_B.duty_cycle = 0.0
|
| 27 |
+
self.led1_B.enable()
|
| 28 |
+
|
| 29 |
+
self.led1_gnd.frequency = 1e3
|
| 30 |
+
self.led1_gnd.duty_cycle = 0.0
|
| 31 |
+
self.led1_gnd.enable()
|
| 32 |
+
|
| 33 |
+
# LED2
|
| 34 |
+
self.led2_R.write(False)
|
| 35 |
+
self.led2_B.write(False)
|
| 36 |
+
self.led2_gnd.write(False)
|
| 37 |
+
|
| 38 |
+
# LED3
|
| 39 |
+
self.led3_R.write(False)
|
| 40 |
+
#self.led3_B.write(False)
|
| 41 |
+
self.led3_gnd.write(False)
|
| 42 |
+
|
| 43 |
+
def aquisition(val):
|
| 44 |
+
self.aquisition.write(val)
|
| 45 |
+
|
| 46 |
+
# red, green & blue are between 0 and 100 inclusively
|
| 47 |
+
def led1(red, green, blue):
|
| 48 |
+
self.led1_R.duty_cycle = red / 100
|
| 49 |
+
self.led1_B.duty_cycle = blue / 100
|
| 50 |
+
|
| 51 |
+
def led2(value):
|
| 52 |
+
if value == RED:
|
| 53 |
+
self.led2_R.write(True)
|
| 54 |
+
self.led2_B.write(False)
|
| 55 |
+
elif value == BLUE:
|
| 56 |
+
self.led2_R.write(False)
|
| 57 |
+
self.led2_B.write(True)
|
| 58 |
+
elif value == PURPLE:
|
| 59 |
+
self.led2_R.write(True)
|
| 60 |
+
self.led2_B.write(True)
|
| 61 |
+
elif value == CLOSED:
|
| 62 |
+
self.led2_R.write(False)
|
| 63 |
+
self.led2_B.write(False)
|
| 64 |
+
else:
|
| 65 |
+
assert False, "Unknown color"
|
| 66 |
+
|
| 67 |
+
def led3(value):
|
| 68 |
+
if value == RED:
|
| 69 |
+
self.led3_R.write(True)
|
| 70 |
+
elif value == CLOSED:
|
| 71 |
+
self.led3_R.write(False)
|
| 72 |
+
else:
|
| 73 |
+
assert False, "Unknown color"
|
| 74 |
+
|
| 75 |
+
def close():
|
| 76 |
+
# LED1
|
| 77 |
+
self.led1_R.disable()
|
| 78 |
+
self.led1_B.disable()
|
| 79 |
+
self.led1_gnd.disable()
|
| 80 |
+
self.led1_R.close()
|
| 81 |
+
self.led1_B.close()
|
| 82 |
+
self.led1_gnd.close()
|
| 83 |
+
|
| 84 |
+
# LED2
|
| 85 |
+
self.led2_R.write(False)
|
| 86 |
+
self.led2_B.write(False)
|
| 87 |
+
self.led2_gnd.write(False)
|
| 88 |
+
self.led2_R.close()
|
| 89 |
+
self.led2_B.close()
|
| 90 |
+
self.led2_gnd.close()
|
| 91 |
+
|
| 92 |
+
# LED3
|
| 93 |
+
self.led3_R.write(False)
|
| 94 |
+
#self.led3_B.write(False)
|
| 95 |
+
self.led3_gnd.write(False)
|
| 96 |
+
self.led3_R.close()
|
| 97 |
+
#self.led3_B.close()
|
| 98 |
+
self.led3_gnd.close()
|
| 99 |
+
|
| 100 |
+
# AQUISITION
|
| 101 |
+
self.aquisition.write(False)
|
| 102 |
+
self.aquisition.close()
|
| 103 |
+
|
prog.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from time import sleep
|
| 2 |
+
from playsound import playsound
|
| 3 |
+
|
| 4 |
+
from frontend import Frontend
|
| 5 |
+
from leds import LEDs
|
| 6 |
+
|
| 7 |
+
FRONTEND_CONFIG = [
|
| 8 |
+
0x3E, # Overwrite ID?
|
| 9 |
+
0x95, # Datarate = 500 SPS
|
| 10 |
+
0xC0, # No tests
|
| 11 |
+
0xE1, # Power-down reference buffer, no bias
|
| 12 |
+
0x00, # No lead-off
|
| 13 |
+
0x60, # Channel 1 active, 24 gain, no SRB2 & normal input
|
| 14 |
+
0x60, # Channel 2 active, 24 gain, no SRB2 & normal input
|
| 15 |
+
0x60, # Channel 3 active, 24 gain, no SRB2 & normal input
|
| 16 |
+
0x60, # Channel 4 active, 24 gain, no SRB2 & normal input
|
| 17 |
+
0x60, # Channel 5 active, 24 gain, no SRB2 & normal input
|
| 18 |
+
0x60, # Channel 6 active, 24 gain, no SRB2 & normal input
|
| 19 |
+
0x60, # Channel 7 active, 24 gain, no SRB2 & normal input
|
| 20 |
+
0xE0, # Channel 8 disabled, 24 gain, no SRB2 & normal input
|
| 21 |
+
0x00, # No bias
|
| 22 |
+
0x00, # No bias
|
| 23 |
+
0xFF, # Lead-off on all positive pins?
|
| 24 |
+
0xFF, # Lead-off on all negative pins?
|
| 25 |
+
0x00, # Normal lead-off
|
| 26 |
+
0x00, # Lead-off positive status (RO) ?
|
| 27 |
+
0x01, # Lead-off negative status (RO) ?
|
| 28 |
+
0x00, # All GPIOs as output ???
|
| 29 |
+
0x20, # Disable SRB1
|
| 30 |
+
]
|
| 31 |
+
|
| 32 |
+
frontend = Frontend()
|
| 33 |
+
leds = LEDs()
|
| 34 |
+
|
| 35 |
+
playsound('sample.mp3')
|
| 36 |
+
|
| 37 |
+
try:
|
| 38 |
+
data = frontend.read_reg(0x00, 1)
|
| 39 |
+
assert data == [0x3E], "Wrong output"
|
| 40 |
+
print("EEG Frontend responsive")
|
| 41 |
+
|
| 42 |
+
print("Configuring EEG Frontend")
|
| 43 |
+
data = frontend.write_reg(0x00, FRONTEND_CONFIG)
|
| 44 |
+
print("EEG Frontend configured")
|
| 45 |
+
|
| 46 |
+
leds.aquisition(True)
|
| 47 |
+
sleep(0.5)
|
| 48 |
+
leds.aquisition(False)
|
| 49 |
+
sleep(0.5)
|
| 50 |
+
leds.aquisition(True)
|
| 51 |
+
|
| 52 |
+
for i in range(200):
|
| 53 |
+
red = (i % 10) * 10
|
| 54 |
+
blue = ((i % 100) // 10) * 10
|
| 55 |
+
leds.led1(red, 0, blue)
|
| 56 |
+
sleep(0.02)
|
| 57 |
+
|
| 58 |
+
for state in [RED, BLUE, PURPLE, CLOSED] * 3:
|
| 59 |
+
leds.led2(state)
|
| 60 |
+
sleep(0.2)
|
| 61 |
+
|
| 62 |
+
for state in [RED, CLOSED] * 3:
|
| 63 |
+
leds.led3(state)
|
| 64 |
+
sleep(0.2)
|
| 65 |
+
|
| 66 |
+
finally:
|
| 67 |
+
frontend.close()
|
| 68 |
+
leds.close()
|