-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathopto_serena.py
More file actions
165 lines (117 loc) · 6.65 KB
/
opto_serena.py
File metadata and controls
165 lines (117 loc) · 6.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
from PulsePal import PulsePalObject
# this file contains a real case of use in our lab
# in this case, we configure the PulsePal to generate
# 4 different pulse trains all triggered by the same trigger channel
# the first train is a single long pulse with ramp down
# the other trains are pulse trains of varying frequencies
# all trains are pulse-gated, meaning that they start when the trigger goes high
# and stop when the trigger goes low
# ---- CREATE PULSE PAL OBJECT ----
# Update with the correct serial port address for your system.
address = "/dev/tty.usbmodem1301"
pulse_pal = PulsePalObject(address)
# ---- CLEAR EXISTING SETTINGS ----
for channel in range(1, 5):
pulse_pal.programOutputChannelParam("isBiphasic", channel, 0)
pulse_pal.programOutputChannelParam("phase1Voltage", channel, 0)
pulse_pal.programOutputChannelParam("phase2Voltage", channel, 0)
pulse_pal.programOutputChannelParam("phase1Duration", channel, 0)
pulse_pal.programOutputChannelParam("phase2Duration", channel, 0)
pulse_pal.programOutputChannelParam("interPhaseInterval", channel, 0)
pulse_pal.programOutputChannelParam("interPulseInterval", channel, 0)
pulse_pal.programOutputChannelParam("burstDuration", channel, 0)
pulse_pal.programOutputChannelParam("interBurstInterval", channel, 0)
pulse_pal.programOutputChannelParam("pulseTrainDuration", channel, 0)
pulse_pal.programOutputChannelParam("pulseTrainDelay", channel, 0)
pulse_pal.programOutputChannelParam("customTrainID", channel, 0)
pulse_pal.programOutputChannelParam("customTrainTarget", channel, 0)
pulse_pal.programOutputChannelParam("customTrainLoop", channel, 0)
pulse_pal.programOutputChannelParam("restingVoltage", channel, 0)
pulse_pal.programOutputChannelParam("linkTriggerChannel1", channel, 0)
pulse_pal.programOutputChannelParam("linkTriggerChannel2", channel, 0)
pulse_pal.setRampEnabled(channel, False)
pulse_pal.setRampDuration(channel, 0)
# ---- TRIGGER CHANNEL 1: UPPER TV ---- OUTPUT CHANNEL 1 ---- PULSE TRAIN ----
# 1) Program a 5 V pulse train in channel 1 at 20 Hz for a total duration of 10 s.
# Since 20 Hz means 20 cycles per second, each cycle lasts 1 / 20 = 0.05 s (50 ms).
# Within each 50 ms cycle, the signal should be ON for 5 ms and OFF for 45 ms. 10% ON.
trigger_channel = 1
output_channel = 1
voltage = 5 # volts
phase_duration = 0.005 # seconds
inter_pulse_interval = 0.045 # seconds
duration = 10 # seconds
pulse_pal.programOutputChannelParam("phase1Voltage", output_channel, voltage)
pulse_pal.programOutputChannelParam("phase1Duration", output_channel, phase_duration)
pulse_pal.programOutputChannelParam(
"interPulseInterval", output_channel, inter_pulse_interval)
pulse_pal.programOutputChannelParam("pulseTrainDuration", output_channel, duration)
# 2) Link trigger channel 1 to output channel 1 (0 = not linked, 1 = linked).
pulse_pal.programOutputChannelParam("linkTriggerChannel1", output_channel, 1)
# 3) Set trigger channel 1
# (0 = normal, 1 = toggle, 2 = pulse-gated).
pulse_pal.programTriggerChannelParam("triggerMode", trigger_channel, 2)
# ---- TRIGGER CHANNEL 1: UPPER TV ---- OUTPUT CHANNEL 2 ---- SINGLE PULSE WITH RAMP ----
# 1) Create a 30 s monophasic 5 V pulse on output channel 2.
# Because this train contains a single pulse, the train duration must match
# the pulse duration (phase1Duration).
trigger_channel = 1
output_channel = 2
voltage = 5 # volts
duration = 10 # second (maximum duration)
pulse_pal.programOutputChannelParam("phase1Voltage", output_channel, voltage)
pulse_pal.programOutputChannelParam("phase1Duration", output_channel, duration)
pulse_pal.programOutputChannelParam("pulseTrainDuration", output_channel, duration)
# 2) Enable ramp-down on output channel 2 and set ramp duration to 0.5 s.
pulse_pal.setRampEnabled(output_channel, True)
pulse_pal.setRampDuration(output_channel, 0.5) # seconds
# 3) Link trigger channel 1 to output channel 2 (0 = not linked, 1 = linked).
pulse_pal.programOutputChannelParam("linkTriggerChannel1", output_channel, 1)
# 4) Set trigger channel 1 to pulse-gated mode already done above
# ---- TRIGGER CHANNEL 2: LOWER TV ---- OUTPUT CHANNEL 3 ---- PULSE TRAIN ----
# 1) Program a 5 V pulse train in channel 3 at 20 Hz for a total duration of 10 s.
# Since 20 Hz means 20 cycles per second, each cycle lasts 1 / 20 = 0.05 s (50 ms).
# Within each 50 ms cycle, the signal should be ON for 5 ms and OFF for 45 ms. 10% ON.
trigger_channel = 2
output_channel = 3
voltage = 5 # volts
phase_duration = 0.005 # seconds
inter_pulse_interval = 0.045 # seconds
duration = 10 # seconds
pulse_pal.programOutputChannelParam("phase1Voltage", output_channel, voltage)
pulse_pal.programOutputChannelParam("phase1Duration", output_channel, phase_duration)
pulse_pal.programOutputChannelParam(
"interPulseInterval", output_channel, inter_pulse_interval)
pulse_pal.programOutputChannelParam("pulseTrainDuration", output_channel, duration)
# 2) Link trigger channel 2 to output channel 3 (0 = not linked, 1 = linked).
pulse_pal.programOutputChannelParam("linkTriggerChannel2", output_channel, 1)
# 3) Set trigger channel 2
# (0 = normal, 1 = toggle, 2 = pulse-gated).
pulse_pal.programTriggerChannelParam("triggerMode", trigger_channel, 2)
# ---- TRIGGER CHANNEL 2: LOWER TV ---- OUTPUT CHANNEL 4 ---- SINGLE PULSE WITH RAMP ----
# 1) Create a 30 s monophasic 5 V pulse on output channel 4.
# Because this train contains a single pulse, the train duration must match
# the pulse duration (phase1Duration).
trigger_channel = 2
output_channel = 4
voltage = 5 # volts
duration = 10 # second (maximum duration)
pulse_pal.programOutputChannelParam("phase1Voltage", output_channel, voltage)
pulse_pal.programOutputChannelParam("phase1Duration", output_channel, duration)
pulse_pal.programOutputChannelParam("pulseTrainDuration", output_channel, duration)
# 2) Enable ramp-down on output channel 4 and set ramp duration to 0.5 s.
pulse_pal.setRampEnabled(output_channel, True)
pulse_pal.setRampDuration(output_channel, 0.5) # seconds
# 3) Link trigger channel 2 to output channel 4 (0 = not linked, 1 = linked).
pulse_pal.programOutputChannelParam("linkTriggerChannel2", output_channel, 1)
# 4) Set trigger channel 2 to pulse-gated mode already done above
# ---- SAVE SETTINGS ----
# Save configuration to a file (e.g., default.pps).
pulse_pal.saveSDSettings("default.pps")
# ---- CONFIRMATION ----
print("Pulse Pal configured successfully!")
# ---- IMPORTANT ----
# Always verify pulses with an oscilloscope before experimental use.
# You may first test them using the joystick to manually trigger pulses, but you should
# always run a final test with the actual Bpod task and Bpod-generated triggers to
# ensure full compatibility.