Spaces:
Sleeping
Sleeping
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()
|