@@ -985,12 +985,12 @@ def square_wave(self, on_time, delay_time):
985985 self .read_response ()
986986
987987 def logic_card_on (self , axis : str ):
988- """Turn on the logic card
988+ """Turn on the logic card output
989989
990990 Parameters
991991 ----------
992992 axis : str
993- The axis of the logic card
993+ The axis of the logic card output
994994 """
995995
996996 axis = int (axis ) + 32
@@ -1000,12 +1000,12 @@ def logic_card_on(self, axis : str):
10001000 self .read_response ()
10011001
10021002 def logic_card_off (self , axis : str ):
1003- """Turn off the logic card
1003+ """Turn off the logic card output
10041004
10051005 Parameters
10061006 ----------
10071007 axis : str
1008- The axis of the logic card
1008+ The axis of the logic card output
10091009 """
10101010 axis = int (axis ) + 32
10111011 self .send_command (f'6 M E = { axis } \r ' )
@@ -1079,19 +1079,31 @@ def SAM(self, axis: str, mode: int):
10791079 self .read_response ()
10801080
10811081 def setup_control_loop (self ,delays ,camera_delay ,rfvc_delay ,sweep_time : float , analog_outputs : dict ): # delay (ms), sweep_time (ms)
1082- # def setup_control_loop(self, analog_outputs: dict):
10831082 """
1084- Sets up the control loop
1083+ Sets up the control loop for triggering the RFVC, Galvo/s, and Camera Trigger
10851084
1086- Arguments: self, waveform type dict (axis, waveform)
1085+ Parameters
1086+ ----------
1087+ delays:
1088+
1089+ camera_delay:
1090+
1091+ rfvc_delay:
10871092
1093+ sweep_time:
1094+
1095+ analog_outputs:
1096+
1097+
10881098 If/Else statements: send the right loop
10891099
10901100 """
1091- # channels = analog_outputs.keys()
1101+ # Reference values for TTLs that correspond to outputs A-C
10921102 TTLs = {'A' : 42 , 'B' : 44 , 'C' : 46 }
1093- # if channels:
1094- start_delay = int (delays [0 ]* 4 ) #- int(round(period))
1103+
1104+ start_delay = int (delays [0 ]* 4 ) # Unit conversion from ms to 1/4 ms
1105+
1106+ # If/Else to handle either 1 or two galvos
10951107 if len (delays ) > 1 :
10961108 galvo2_delay = int ((delays [0 ] - delays [1 ])* 4 )
10971109 galvo1_axis = analog_outputs ["galvo 0" ]
@@ -1103,10 +1115,11 @@ def setup_control_loop(self,delays,camera_delay,rfvc_delay,sweep_time : float, a
11031115 galvo2_delay = 0
11041116 rfvc_axis = analog_outputs ["remote_focus" ]
11051117
1118+ sweep_time = int (sweep_time * 4 ) - 2 #Hardcoded -2 to account for delays within controller
11061119
1107-
1108- sweep_time = int ( sweep_time * 4 ) - 2
1109-
1120+ # Dynamic delay processing. Instead of having each delay handled seperately, to save some cell space delays are programmed based on some simple calculation logic.
1121+ # Cell 6 is the direct output for the logical loop, and cell 12 is the post-delay output. So whichever delay is longer (accounting for hardware delays), will get input from 12
1122+ # Additionally, delay is calculated as a shifted difference between the higher and lower delay
11101123 if rfvc_delay > camera_delay + 2 :
11111124 camera_output = 6
11121125 rfvc_output = 12
@@ -1121,188 +1134,126 @@ def setup_control_loop(self,delays,camera_delay,rfvc_delay,sweep_time : float, a
11211134 camera_output = 6
11221135 rfvc_output = 6
11231136 start_delay += int ((camera_delay + 2 ) * 4 )
1124- difference_delay = int ((rfvc_delay - (camera_delay + 2 )) * 4 )
1125-
1126-
1127- print (f"Delays: { delays } , RFVC Delay: { rfvc_delay } , Camera Delay: { camera_delay } " )
1128-
1129- print (f"Camera: { camera_output } , RFVC: { rfvc_output } " )
1130-
1131- print (f'Sweep Time Cycles: { sweep_time } ' )
1132- print (f"Start Delay: { start_delay } , Difference Delay: { difference_delay } " )
1133- print (f"Galvo2_delay: { galvo2_delay } " )
1137+ difference_delay = 0
11341138
11351139 commands = [
1140+ # Resets programmable logic cell configurations to constant cells
1141+ # This handles configuring cell 1 and cell 8
11361142 '6 CCA X=0' ,
1137-
1138- # Set cell 2 to one shot to trigger TTL for galvo, For I am the LORD
1143+ # Cell 2, a one-shot triggered by the rising edge of Cell 1
11391144 '6 m e = 2' ,
11401145 '6 cca y = 8' ,
11411146 '6 cca z = 10' ,
11421147 '6 ccb x = 1' ,
11431148 '6 ccb y = 192' ,
1144- # Set cell 3 to delay cell to give time to send serial commands, For I am the LORD
1149+ # Cell 3, delay cell that is used to sync up the loop after Galvo initialization
1150+ # Delay time is based on the start delay variable (in 1/4 ms)
11451151 '6 m e = 3' ,
11461152 '6 cca y = 9' ,
11471153 f'6 cca z = { start_delay } ' ,
11481154 '6 ccb x = 1' ,
11491155 '6 ccb y = 192' ,
1150- # Set cell 4 to JK-Flop, to trigger & cell, For I am the LORD
1156+ # Cell 4, JK flop used for toggling on and off state of the loop
1157+ # Cells 3 and 8 serve as the inputs of this cell
11511158 '6 m e = 4' ,
11521159 '6 cca y = 13' ,
11531160 '6 ccb x = 3' ,
11541161 '6 ccb y = 8' ,
11551162 '6 ccb z = 192' ,
1156- # Set cell 5 to & cell for loop, For I am the LORD
1163+ # Cell 5, AND cell used to check if the loop is still operating
1164+ # Cell inputs are the output of cell 4 and the inverse of cell 7 (64+7)
11571165 '6 m e = 5' ,
11581166 '6 cca y = 5' ,
11591167 '6 ccb x = 4' ,
11601168 '6 ccb y = 71' ,
1161- # Set cell 6 to one-shot to trigger TTL for RFVC repeatedly and to trigger CT, For I am the LORD
1169+ # Cell 6, a one-shot triggered by the rising edge of Cell 5
11621170 '6 m e = 6' ,
11631171 '6 cca y = 8' ,
11641172 '6 cca z = 10' ,
11651173 '6 ccb x = 5' ,
11661174 '6 ccb y = 192' ,
1167- # Set cell 7 to delay cell for loop, For I am the LORD
1175+ # Cell 7, delay cell that waits for the sweep time until retriggering. Used for the main loop
1176+ # Timing is dependent on the sweep_time variable
11681177 '6 m e = 7' ,
11691178 '6 cca y = 9' ,
11701179 f'6 cca z= { sweep_time } ' ,
11711180 '6 ccb x = 6' ,
11721181 '6 ccb y = 192' ,
1173- #Sets cell 9 to a delay cell to account for the second galvo
1182+ # Cell 9, delay used to sync the phase of the Galvos
1183+ # This is because the Tiger Controller can not arbitrarily start waveforms
11741184 '6 m e = 9' ,
11751185 '6 cca y = 9' ,
11761186 f'6 cca z = { galvo2_delay } ' ,
11771187 '6 ccb x = 2' ,
11781188 '6 ccb y = 192' ,
1179- #Sets cell 10 to a one shot to trigger Galvo 2
1180- 'm e = 10' ,
1181- 'cca y = 8' ,
1182- 'cca z = 10' ,
1183- 'ccb x = 9' ,
1184- 'ccb y = 192' ,
1185- #Sets cell 11 to a delay reading the output of cell 6
1189+ # Cell 10, a one- shot triggered by the rising edge of Cell 9
1190+ '6 m e = 10' ,
1191+ '6 cca y = 8' ,
1192+ '6 cca z = 10' ,
1193+ '6 ccb x = 9' ,
1194+ '6 ccb y = 192' ,
1195+ # Cell 11, delay cell used to sync up the camera trigger and remote focus oupout based on configuration
11861196 '6 m e = 11' ,
11871197 '6 cca y = 9' ,
11881198 f'6 cca z = { difference_delay } ' ,
11891199 '6 ccb x = 6' ,
11901200 '6 ccb y = 192' ,
1191- #Sets cell 12 to one shot to trigger camera
1192- 'm e = 12' ,
1193- 'cca y = 8' ,
1194- 'cca z = 10' ,
1195- 'ccb x = 11' ,
1196- 'ccb y = 192' ,
1197- #Sets TTL2 to output from the RFVC cell in this case , For I am the LORD
1201+ # Cell 12, a one- shot triggered by the rising edge of Cell 11
1202+ '6 m e = 12' ,
1203+ '6 cca y = 8' ,
1204+ '6 cca z = 10' ,
1205+ '6 ccb x = 11' ,
1206+ '6 ccb y = 192' ,
1207+ # Routes the output of the RFVC trigger to the TTL output from the PLC
11981208 f'6 m e = { TTLs [rfvc_axis ]+ 1 } ' ,
11991209 '6 cca y = 1' ,
12001210 f'6 cca z = { rfvc_output } ' ,
1201- #Sets TTL1 to output the same thing as TTL0, For I am the LORD
1211+ # Routes the TTL output from the preious section to a different TTL to actually trigger the waveform
12021212 f'6 m e = { TTLs [rfvc_axis ]} ' ,
12031213 '6 cca y = 1' ,
12041214 f'6 cca z = { TTLs [rfvc_axis ]+ 1 } ' ,
1205- #Sets PLC output 3 to cell 6
1215+ # Sets the camera signal output to the first physical PLC output
12061216 '6 m e = 33' ,
12071217 f'6 cca z = { camera_output } ' ,
12081218 ]
1209- # if galvos exist
1219+ # Creates object to hold galvo commands
12101220 galvo_commands = []
1211- if len (delays ) > 0 :
1221+ # Single Galvo case, just sets up the first Galvo
1222+ if len (delays ) == 1 :
12121223 galvo_commands = [
1213- #Sets TTL4 to output for the first Galvo, For I am the LORD
1224+ # Sets the output of Cell 2 as the input to the TTL corresponding to the first Galvo pair
12141225 f'6 m e = { TTLs [galvo1_axis ]+ 1 } ' ,
12151226 '6 cca y = 1' ,
12161227 '6 cca z = 2' ,
1217- #Sets TTL3 to output the same thing as TTL2
1228+ # Sets the output of the first Galvo TTL to the Galvo TTL that actually triggers it
12181229 f'6 m e = { TTLs [galvo1_axis ]} ' ,
1219- 'cca y = 1' ,
1220- f'cca z = { TTLs [galvo1_axis ]+ 1 } ' ,
1230+ '6 cca y = 1' ,
1231+ f'6 cca z = { TTLs [galvo1_axis ]+ 1 } ' ,
12211232 ]
1222-
1223- if len (delays ) > 1 :
1233+ # Multiple Galvo case, has the first set of commands and the commands for the second Galvo
1234+ elif len (delays ) > 1 :
12241235 galvo_commands = [
1225- # Sets TTL4 to output for the first Galvo, For I am the LORD
1236+ # Sets the output of Cell 2 as the input to the TTL corresponding to the first Galvo pair
12261237 f'6 m e = { TTLs [galvo1_axis ]+ 1 } ' ,
12271238 '6 cca y = 1' ,
12281239 '6 cca z = 2' ,
1229- #Sets TTL3 to output the same thing as TTL2
1240+ # Sets the output of the first Galvo TTL to the Galvo TTL that actually triggers it
12301241 f'6 m e = { TTLs [galvo1_axis ]} ' ,
1231- 'cca y = 1' ,
1232- f'cca z = { TTLs [galvo1_axis ]+ 1 } ' ,
1233- #Sets TTL4 to output for the first Galvo, For I am the LORD
1242+ '6 cca y = 1' ,
1243+ f'6 cca z = { TTLs [galvo1_axis ]+ 1 } ' ,
1244+ # Sets the output of Cell 10 as the input to the TTL corresponding to the second Galvo pair
12341245 f'6 m e = { TTLs [galvo2_axis ]+ 1 } ' ,
12351246 '6 cca y = 1' ,
12361247 '6 cca z = 10' ,
1237- #Sets TTL3 to output the same thing as TTL2
1248+ # Sets the output of the second Galvo TTL to the Galvo TTL that actually triggers it
12381249 f'6 m e = { TTLs [galvo2_axis ]} ' ,
1239- 'cca y = 1' ,
1240- f'cca z = { TTLs [galvo2_axis ]+ 1 } ' ,
1250+ '6 cca y = 1' ,
1251+ f'6 cca z = { TTLs [galvo2_axis ]+ 1 } ' ,
12411252 ]
1242- print (galvo_commands )
1243-
1244- print (analog_outputs )
1245- print (f"{ TTLs [galvo1_axis ]+ 1 } " )
1253+ # Runs the main setup commands, followed by the Galvo specific commands
12461254 for command in commands :
1247- # Send data
12481255 self .send_command (f'{ command } \r ' )
12491256 self .read_response ()
12501257 for command in galvo_commands :
12511258 self .send_command (f'{ command } \r ' )
1252- self .read_response ()
1253-
1254- def tweak_control_loop (self , delays , sweep_time ):
1255-
1256- start_delay = int (delays [0 ]* 4 ) #- int(round(period))
1257- if len (delays ) > 1 :
1258- galvo2_delay = int ((delays [0 ] - delays [1 ])* 4 )
1259- else :
1260- galvo2_delay = 0
1261-
1262- sweep_time = int (sweep_time * 4 ) - 2
1263-
1264- print (f'Sweep Time Cycles: { sweep_time } ' )
1265-
1266- commands = [
1267- # Set cell 3 to delay cell to give time to send serial commands, For I am the LORD
1268- '6 m e = 3' ,
1269- '6 cca y = 9'
1270- f'6 cca z = { start_delay } ' ,
1271- '6 ccb x = 1' ,
1272- '6 ccb y = 192' ,
1273- # Set cell 7 to delay cell for loop, For I am the LORD
1274- '6 m e = 7' ,
1275- '6 cca y = 9'
1276- f'6 cca z= { sweep_time } ' ,
1277- '6 ccb x = 6' ,
1278- '6 ccb y = 192' ,
1279- #Sets cell 9 to a delay cell to account for the second galvo
1280- '6 m e = 9' ,
1281- '6 cca y = 9'
1282- f'6 cca z = { galvo2_delay } ' ,
1283- '6 ccb x = 2' ,
1284- '6 ccb y = 192' ,
1285- ]
1286- for command in commands :
1287- # Send data
1288- self .send_command (f'{ command } \r ' )
1289- self .read_response ()
1290-
1291- def send_ttl_pulse (self , channel : int , pulse_width_ms : int , delay_ms : int ) -> str :
1292-
1293- command = f"TTL X={ channel } P={ pulse_width_ms } D={ delay_ms } "
1294- self .send_command (command )
1295- response = self .read_response ()
1296- return response
1297-
1298- # def trigger_acquisition(self):
1299- # commands = [
1300- # #Changes the TTL input from cell 2 to cell 6, For I am the LORD
1301- # '6 m e = 43',
1302- # '6 cca z = 6',
1303- # ]
1304- # for command in commands:
1305- # # Send data
1306- # self.send_command(f'{command}\r')
1307- # self.read_response()
1308-
1259+ self .read_response ()
0 commit comments