From fdeae14375cfb7079cb251afa98e0520e717fd42 Mon Sep 17 00:00:00 2001 From: Andrew Nelson <33523882+ajn2004@users.noreply.github.com> Date: Wed, 16 Oct 2019 07:50:47 -0400 Subject: [PATCH 1/4] ignores and basic commits --- .gitignore | 4 ++++ Stim Stage/__pycache__/ardcom.cpython-36.pyc | Bin 2057 -> 2060 bytes Stim Stage/__pycache__/pyasi.cpython-36.pyc | Bin 662 -> 665 bytes Stim Stage/positions.csv | 9 ++++++++- Stim Stage/stim_Stage.py | 2 +- 5 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..347cb93 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ + +*.csv +Stim Stage/stim_stage.bat +Stim Stage/positions.csv diff --git a/Stim Stage/__pycache__/ardcom.cpython-36.pyc b/Stim Stage/__pycache__/ardcom.cpython-36.pyc index e5deb3ccdbb3c44181ff7d1c4af457f2001a8e25..23f90949781499ced5f59b1da71b3a434e476f5a 100644 GIT binary patch delta 39 ucmeAa=n-Hy=H=z`IlpuvJEM?mvQUZ@(PlBm&ujqU^$a-x delta 36 rcmeAX=oDZ#=H=zemzcDWosr)u*(xTqIJKxa#>>;!H*&Ki<7YMitRV_o diff --git a/Stim Stage/__pycache__/pyasi.cpython-36.pyc b/Stim Stage/__pycache__/pyasi.cpython-36.pyc index 12bb6a604524687ef57e74a56e541ff47f982397..9e6d77415a399f1b46ad27b2e73fe34f4e5e7bb8 100644 GIT binary patch delta 40 vcmbQnI+K;%n3tE!=ls%*?3Ro|F3DCgp~b01#W5insR~Z1iA9_J8QmEH?VSt_ delta 37 scmbQqI*paxn3tC;Ut-cmc1uQn$7HLR(Bjmh;utSaU*E{hL5%K<0Jc5~E&u=k diff --git a/Stim Stage/positions.csv b/Stim Stage/positions.csv index 416648d..c5db990 100644 --- a/Stim Stage/positions.csv +++ b/Stim Stage/positions.csv @@ -1,2 +1,9 @@ 0,0,0 -0,0,0 +27711.82,34966.6,-354.607 +17852.05,21654.23,-292.969 +23101.44,37092.71,-338.013 +14493.5,41557.26,-263.626 +19166.87,43673.67,-224.716 +31786.92,38255.55,-305.397 +31786.92,45122.87,-272.781 +29713.68,54929.33,-190.956 diff --git a/Stim Stage/stim_Stage.py b/Stim Stage/stim_Stage.py index c0c6d28..2236a46 100644 --- a/Stim Stage/stim_Stage.py +++ b/Stim Stage/stim_Stage.py @@ -350,5 +350,5 @@ def write_marks(self): f.close() root = tk.Tk() -my = myGui(root,'COM3', 'COM10', 0) +my = myGui(root,'COM3', 'COM9', 0) root.mainloop() \ No newline at end of file From 8deb05beb955fedf6fb35bb61addbc56593e9b0f Mon Sep 17 00:00:00 2001 From: Andrew Nelson <33523882+ajn2004@users.noreply.github.com> Date: Wed, 16 Oct 2019 07:51:56 -0400 Subject: [PATCH 2/4] Changed gui over to 'master' --- Stim Stage/stim_Stage.py | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/Stim Stage/stim_Stage.py b/Stim Stage/stim_Stage.py index 2236a46..65c2e58 100644 --- a/Stim Stage/stim_Stage.py +++ b/Stim Stage/stim_Stage.py @@ -1,4 +1,5 @@ # This gui is to unify the stage controls with the arduino stimulation controls +# Stim_Stage 1.1 import tkinter as tk import ardcom as ac import serial @@ -26,23 +27,28 @@ def setup_stage(self, ser): # Setup widgets and positions related to the 'stage' portion of the gui self.ser_s = serial.Serial(ser, 9600) self.ser_s.write(b'vb z=3\r') - self.ser_s.readline() + #self.ser_s.readline() self.stage = tk.Frame(self.root, bd = 2, relief = 'sunken') # Define frame for self.build_axes() self.build_focus() - self.build_stage_marks() - if self.debug_state >= 1: - self.build_com_box() - self.build_storm_wave() - + self.build_stage_marks() self.get_position() # Widget Positioning self.axes_frame.grid(row = 0, column = 0, padx = 2, pady = 2) self.focus_frame.grid(row = 0, column = 1, padx = 2, pady = 2) self.stage_mark_frame.grid(row = 1, column = 0, columnspan = 2, padx = 2, pady = 2) - if self.debug_state >= 1: + if self.debug_state == 1: # Andrew's Scope's configuration + self.build_com_box() + self.build_storm_wave() self.com_frame.grid(row = 2, column = 0, columnspan = 2, padx = 2, pady = 2) self.storm_wave_frame.grid(row = 3, column = 0) + if self.debug_state == 2: # SYN-ATP scope Config + print('NO') + if self.debug_state == 3: # The Bear scope Config + print('NO') + if self.debug_state == 4: # Michelle scope Config + print('NO') + def build_axes(self): # Axes variables and current position widget self.axes_frame = tk.Frame(self.stage, bd = 2, relief = 'groove') @@ -129,7 +135,7 @@ def build_com_box(self): self.response = tk.StringVar() self.response.set('NA') self.command_response = tk.Label(self.com_frame, textvariable = self.response) - self.cmd_button = tk.Button(self.com_frame, text = "Send", command = self.send_command) + self.cmd_button = tk.Button(self.com_frame, text = "Send", command = self.send_asi_command) self.com_frame_title.grid(row = 0, column = 0 , columnspan = 2) self.command_line.grid(row = 1) self.command_response.grid(row = 2) @@ -142,6 +148,7 @@ def build_storm_wave(self): self.wave_range = tk.StringVar() self.wave_dz.set('10') self.wave_range.set('1') + self.uv_state = 0 self.wave_dz_title = tk.Label(self.storm_wave_frame, text = 'dz') self.wave_dz_entry = tk.Entry(self.storm_wave_frame, textvariable = self.wave_dz, width = 5) self.wave_range_title = tk.Label(self.storm_wave_frame, text = 'Range') @@ -151,6 +158,7 @@ def build_storm_wave(self): self.wave_button = tk.Button(self.storm_wave_frame, text = 'Turn Wave On', bg = 'magenta', command = self.wave) self.wave_state = 0 self.wave_title.grid(row=0, column = 0) + self.uv_laser_button = tk.Button(self.storm_wave_frame, text = "Turn 405 On", bg = 'magenta', command = self.uv_laser) self.wave_dz_title.grid(row=1, column = 0, sticky = 'E') self.wave_dz_entry.grid(row=1, column = 1, sticky = 'W') self.wave_dz_label.grid(row=1, column = 2) @@ -158,6 +166,7 @@ def build_storm_wave(self): self.wave_range_entry.grid(row=2, column = 1, sticky = 'W') self.wave_range_label.grid(row=2, column = 2) self.wave_button.grid(row = 3, column = 1) + self.uv_laser_button.grid(row=3, column = 0) def setup_arduino(self, ser): self.ser_arduino = serial.Serial(ser, 9600) @@ -279,15 +288,22 @@ def wave(self): pyasi.send_command(self.ser_s,'TTL X=0\r') self.wave_button.configure(text = 'Turn Wave On', bg = 'magenta') + def uv_laser(self): + ac.send_command(self.ser_arduino, '4') + self.uv_state = (self.uv_state + 1) % 2 + if self.uv_state is 1: + self.uv_laser_button.config(text = 'Turn 405 Off', bg = 'green') + else: + self.uv_laser_button.config(text = 'Turn 405 On', bg = 'magenta') + def change_stim(self, *args): self.com_response.set(ac.send_command(self.ser_arduino,"s",self.stimset.get())) def change_stim_number(self, *args): self.com_response.set(ac.send_command(self.ser_arduino,"n",self.stimN.get())) - def send_command(self): - self.response.set(pyasi.send_command(self.ser,self.cmd.get() + '\r')) - + def send_asi_command(self): + self.response.set(pyasi.send_command(self.ser_s,self.cmd.get() + '\r')) def change_frequency(self, *args): self.com_response.set(ac.send_command(self.ser_arduino,"f",self.frequency.get())) @@ -350,5 +366,5 @@ def write_marks(self): f.close() root = tk.Tk() -my = myGui(root,'COM3', 'COM9', 0) +my = myGui(root,'COM1', 'COM2', 0) root.mainloop() \ No newline at end of file From 386067fec1f479b8f6a80eb5fa9c0cd8baea1d19 Mon Sep 17 00:00:00 2001 From: Andrew Nelson <33523882+ajn2004@users.noreply.github.com> Date: Wed, 16 Oct 2019 14:36:11 -0400 Subject: [PATCH 3/4] Dual-camera system implemented --- Stim Stage/__pycache__/ardcom.cpython-36.pyc | Bin 2060 -> 2753 bytes Stim Stage/__pycache__/pyasi.cpython-36.pyc | Bin 665 -> 730 bytes Stim Stage/ardcom.py | 25 ++++- Stim Stage/pyasi.py | 8 +- Stim Stage/stim_Stage.py | 100 ++++++++++++++++--- 5 files changed, 113 insertions(+), 20 deletions(-) diff --git a/Stim Stage/__pycache__/ardcom.cpython-36.pyc b/Stim Stage/__pycache__/ardcom.cpython-36.pyc index 23f90949781499ced5f59b1da71b3a434e476f5a..f91f5ece54ec7c9d1b822bd2ae17bef194cd9bd0 100644 GIT binary patch delta 1032 zcmaKq-)j>=5XX1+?viUv(wwn2KiVd3)20Wtf~~dw0E>bTB1Nq)25Jf2Lt=l)+_n0U zDy51qzLb3v>8r2)3qI+;;DMm{ZwNYbCP#u`j@{YJXXiUJyZbixX=r&qlS#d~^kJ=( z6ym4o`5Clcrs1E^q=bSk(fDhj0ZJ<4m1sy+J6?WxuB6KJC#y!(DA_?ZrYdA}s;b7x zI%+~ql0B_pRk%~fCtp*8BzcpyAL&CFss#fLi0wkW&#S{4P#Su1WcK7@+(c0PfFbM6v{q?P;?_rqPXl{GhTz~3eYgg$PaxFJQ zIzme5e)@+jTG9rb)xYHfr%H5^hR;a_V3oY{)`AN-r?<_LQzP$m53fbsi}^S)w}+2M ze6!256U1g?u7AlztJQ@LCq5rTz)Ahmx>^|~k1IpN4-o6THqau|NOZcommJDZk>dgl z-=s-E8gNQ0<08!IcShaes70oors`2q80RezyWGPI5nqjYk=V5!UgWwmY4W%d=gDAQ ze>dHHiI&%SUtC2gQhF9Em5D}Arc+6olx`$C5}&PFeuOsM>XR6uEmsO5ti-tpcg_Hp z^xZ@uKT4k4eLDle}OlV|Sm8`y?2~LP8TPB$N?iu$wep^@jmuGE;BFKxVDW{*Hldk+v_t{n!sl`jlf{ka5C+lTJD9jH|e+ zvl)B}Mk-f_K@Kh)%aP7yCXN)|%XKbtIhG(!E&F2tk&DA?V=*$hq22Ub*%Y*m*-8U{ zUAAKc+5#mTt~8DOGkNZR%a`3{S_&zlJgkhsLL{xSe$L$WUsU&_)wLU>9dZ@{*!I87 zCiML6%1YcJq&vfPd~7xhrhq+vQ@7%TxZVt(O!)07zd+o|48P!G`>+-flFC929b(60 zHBIV-tg%j$5fA~^Cz)PPGc6Ln&WgWPE>fl^l~qD0#g6SIOXS{R!8FAZNggx`*h(c{ z35iY>(iIC_^SePKX^^{F3TkkL&3RV-Gpb4K{ZdqO5*7b1>Y_#L<5CnODU~-@REB$a zuzOr+cW|`{4!7@uM QSZ#G!xBLir=*cAP55kLb5dZ)H diff --git a/Stim Stage/__pycache__/pyasi.cpython-36.pyc b/Stim Stage/__pycache__/pyasi.cpython-36.pyc index 9e6d77415a399f1b46ad27b2e73fe34f4e5e7bb8..ba569381634e219e2eb7891db9066c8c69d62eca 100644 GIT binary patch delta 456 zcmYjNO-sW-5Z&2L(j=G~Y7vBj;w@*dy;YC)qR(y&(4!zZ`3w93 z{+s;={RdvOZeq|L=FOYoy~i+by40;R$FV)hNoIFhJku5&`~do6VVwW~ delta 371 zcmcb`I+K;tn3tE!=ls&xH4{1g>RA{V7@UE)xBy7hFk~^LFg7zXf>?~r47H3UOf`%t zOew6bOp*-EjI~T)70g&vut8NYgH^C#QNa#X!BWFi!(79X#vII`$zkMI401uZLIm$i zW{@)=yhvUsBZ~Ls-~a#r7lGu!geLQ3M@C~tp2?+*u~H&HQ3ggXMh->+CSzH9G8eG}sVHV=UzZ{dAghQ6PVfR*w|I(E^HSoI^K)|(^HPL> wBE@V#f`O3_Xhji-ugQFitvIzPGcl)#56A_JAsGTT4r~&KP4495OhSzO0AyiEcmMzZ diff --git a/Stim Stage/ardcom.py b/Stim Stage/ardcom.py index c8e5918..458f245 100644 --- a/Stim Stage/ardcom.py +++ b/Stim Stage/ardcom.py @@ -17,7 +17,12 @@ def send_command(ser,cmd,var = None): # Switch Statement "n": set_stim_number, "P": set_pulse_width, "p": set_period, - 'a': arm + 'a': arm, + 'e': ext_trig, + 'k': simultaneous, + 'i': invert, + '4': uv_laser, + 'c': camera_period } func = switch.get(cmd,send_string) if(var != None): @@ -25,11 +30,27 @@ def send_command(ser,cmd,var = None): # Switch Statement else: func(ser) - string = ser.readline() return string[0:-1] def arm(ser): ser.write(b'a') + +def uv_laser(ser): + ser.write(b'4') + +def ext_trig(ser): + ser.write(b'e') + +def simultaneous(ser): + ser.write(b'k') + +def invert(ser): + ser.write(b'i') + +def camera_period(ser,period): + string = "c" + str(period) + send_string(ser,string) + def send_string(ser,string): ser.write(string.encode()) diff --git a/Stim Stage/pyasi.py b/Stim Stage/pyasi.py index 85dc569..bc13b28 100644 --- a/Stim Stage/pyasi.py +++ b/Stim Stage/pyasi.py @@ -1,10 +1,14 @@ import serial def get_positions(ser): + ser.reset_input_buffer() ser.write(b'W X\r') string = ser.readline() - x = float(string[3:-3]) - + try: + x = float(string[3:-3]) + except: + x = 'Error' + ser.write(b'W Y\r') string = ser.readline() y = float(string[3:-3]) diff --git a/Stim Stage/stim_Stage.py b/Stim Stage/stim_Stage.py index 65c2e58..e606f88 100644 --- a/Stim Stage/stim_Stage.py +++ b/Stim Stage/stim_Stage.py @@ -22,10 +22,31 @@ def __init__(self, master, ser_stage, ser_arduino, bugable): self.arduino.grid(row = 1, column = 0) self.stage.grid(row = 1, column = 1) self.close.grid(row = 0) + if self.debug_state == 1: # Andrew's Scope's configuration + self.build_com_box() + self.build_storm_wave() + self.com_frame.grid(row = 2, column = 1, columnspan = 2, padx = 2, pady = 2) + self.storm_wave_frame.grid(row = 2, column = 0) + if self.debug_state == 2: # SYN-ATP scope Config + print('NO') + if self.debug_state == 3: # The Bear scope Config + self.build_dual_camera() + self.dual_camera_frame.grid(row = 2, column = 0) + if self.debug_state == 4: # Michelle scope Config + print('NO') def setup_stage(self, ser): # Setup widgets and positions related to the 'stage' portion of the gui - self.ser_s = serial.Serial(ser, 9600) + flag = 1 + print('Opening Stage communication... ', end ='') + + while flag is 1: + try: + self.ser_s = serial.Serial(ser, 9600) + flag = 0 + except: + count = 1 + print('complete\n') self.ser_s.write(b'vb z=3\r') #self.ser_s.readline() self.stage = tk.Frame(self.root, bd = 2, relief = 'sunken') # Define frame for @@ -37,17 +58,55 @@ def setup_stage(self, ser): self.axes_frame.grid(row = 0, column = 0, padx = 2, pady = 2) self.focus_frame.grid(row = 0, column = 1, padx = 2, pady = 2) self.stage_mark_frame.grid(row = 1, column = 0, columnspan = 2, padx = 2, pady = 2) - if self.debug_state == 1: # Andrew's Scope's configuration - self.build_com_box() - self.build_storm_wave() - self.com_frame.grid(row = 2, column = 0, columnspan = 2, padx = 2, pady = 2) - self.storm_wave_frame.grid(row = 3, column = 0) - if self.debug_state == 2: # SYN-ATP scope Config - print('NO') - if self.debug_state == 3: # The Bear scope Config - print('NO') - if self.debug_state == 4: # Michelle scope Config - print('NO') + + def build_dual_camera(self): + self.dual_camera_frame =tk.Frame(self.root, bd =2 , relief = 'sunken') + self.external_trigger_button = tk.Button(self.dual_camera_frame, text = 'Ext. Trigger', bg = 'magenta', command = self.external_trigger) + self.inverter_button = tk.Button(self.dual_camera_frame, text = 'Inverter', bg = 'magenta', command = self.invert) + self.simultaneous_button = tk.Button(self.dual_camera_frame, text = 'Simultaneous', bg = 'magenta', command = self.simultaneous) + self.simul_tog = 0 + self.inver_tog = 0 + self.exttr_tog = 0 + self.camera_period_label = tk.Label(self.dual_camera_frame, text = 'Camera period') + self.camera_period_units = tk.Label(self.dual_camera_frame, text = 'ms') + self.camera_period = tk.StringVar() + self.camera_period.set('100') + self.camera_period.trace_add("write", self.change_period) + self.camera_period_entry = tk.Entry(self.dual_camera_frame, textvariable = self.camera_period) + #Organization + self.external_trigger_button.grid(row = 1, column = 0, columnspan = 3, padx = 2, pady = 2) + self.inverter_button.grid(row = 1, column = 3, columnspan = 3, padx = 2, pady = 2) + self.simultaneous_button.grid(row = 2, column = 0, columnspan = 3, padx = 2, pady = 2) + self.camera_period_label.grid(row = 2, column = 3, columnspan = 1, padx = 2, pady = 2) + self.camera_period_entry.grid(row = 2, column = 4, columnspan = 1, padx = 2, pady = 2) + self.camera_period_units.grid(row = 2, column = 5, columnspan = 1, padx = 2, pady = 2) + + def external_trigger(self): + self.com_response.set(ac.send_command(self.ser_arduino,"e")) + self.exttr_tog = (self.exttr_tog + 1)%2 + if self.exttr_tog is 1: + self.external_trigger_button.configure(bg = 'green') + else: + self.external_trigger_button.configure(bg = 'magenta') + + def invert(self): + self.com_response.set(ac.send_command(self.ser_arduino,"i")) + self.inver_tog = (self.inver_tog + 1)%2 + if self.inver_tog is 1: + self.inverter_button.configure(bg = 'green') + else: + self.inverter_button.configure(bg = 'magenta') + + def simultaneous(self): + self.com_response.set(ac.send_command(self.ser_arduino,"k")) + self.simul_tog = (self.simul_tog + 1)%2 + if self.simul_tog is 1: + self.simultaneous_button.configure(bg = 'green') + else: + self.simultaneous_button.configure(bg = 'magenta') + + def change_period(self, *args): + self.com_response.set(ac.send_command(self.ser_arduino,"c",self.camera_period.get())) def build_axes(self): # Axes variables and current position widget @@ -169,7 +228,15 @@ def build_storm_wave(self): self.uv_laser_button.grid(row=3, column = 0) def setup_arduino(self, ser): - self.ser_arduino = serial.Serial(ser, 9600) + flag = 1 + print('Connecting to Arduino... ', end='') + while flag is 1: + try: + self.ser_arduino = serial.Serial(ser, 9600) + flag = 0 + except: + count = 1 + print('Complete\n') self.arduino = tk.Frame(self.root, bd =2, relief = 'groove') self.camera_frame_setup() @@ -193,13 +260,13 @@ def camera_frame_setup(self): self.stimf_text = tk.Label(self.arduino, text = "Stimulate on Frame:") # Create text that goes with entry widget # Number of Stimuli / Train section self.stimN = tk.StringVar() - self.stimN.set("1") + self.stimN.set("20") self.stimN.trace_add("write" , self.change_stim_number) self.stimN_frame = tk.Entry(self.arduino, textvariable = self.stimN, width = w) self.stimN_text = tk.Label(self.arduino, text = "Number of Stimuli/Train:") # Frequency Section self.frequency = tk.StringVar() - self.frequency.set("1") + self.frequency.set("20") self.frequency.trace_add("write", self.change_frequency) self.frequency_frame = tk.Entry(self.arduino, textvariable = self.frequency, width = w) self.frequency_text = tk.Label(self.arduino, text = "Frequency of train:") @@ -304,6 +371,7 @@ def change_stim_number(self, *args): def send_asi_command(self): self.response.set(pyasi.send_command(self.ser_s,self.cmd.get() + '\r')) + def change_frequency(self, *args): self.com_response.set(ac.send_command(self.ser_arduino,"f",self.frequency.get())) @@ -366,5 +434,5 @@ def write_marks(self): f.close() root = tk.Tk() -my = myGui(root,'COM1', 'COM2', 0) +my = myGui(root,'COM3', 'COM9', 3) root.mainloop() \ No newline at end of file From 70252f5b586153bbfebdb99bab1fd6ea1873adb8 Mon Sep 17 00:00:00 2001 From: Andrew Nelson <33523882+ajn2004@users.noreply.github.com> Date: Wed, 16 Oct 2019 14:47:07 -0400 Subject: [PATCH 4/4] Alphabetize stim-stage Alphabetizing stim-stage functions will make searching and editing easier in the future. --- Stim Stage/stim_Stage.py | 366 +++++++++++++++++++-------------------- 1 file changed, 183 insertions(+), 183 deletions(-) diff --git a/Stim Stage/stim_Stage.py b/Stim Stage/stim_Stage.py index e606f88..7b45996 100644 --- a/Stim Stage/stim_Stage.py +++ b/Stim Stage/stim_Stage.py @@ -35,78 +35,14 @@ def __init__(self, master, ser_stage, ser_arduino, bugable): if self.debug_state == 4: # Michelle scope Config print('NO') - def setup_stage(self, ser): - # Setup widgets and positions related to the 'stage' portion of the gui - flag = 1 - print('Opening Stage communication... ', end ='') - - while flag is 1: - try: - self.ser_s = serial.Serial(ser, 9600) - flag = 0 - except: - count = 1 - print('complete\n') - self.ser_s.write(b'vb z=3\r') - #self.ser_s.readline() - self.stage = tk.Frame(self.root, bd = 2, relief = 'sunken') # Define frame for - self.build_axes() - self.build_focus() - self.build_stage_marks() - self.get_position() - # Widget Positioning - self.axes_frame.grid(row = 0, column = 0, padx = 2, pady = 2) - self.focus_frame.grid(row = 0, column = 1, padx = 2, pady = 2) - self.stage_mark_frame.grid(row = 1, column = 0, columnspan = 2, padx = 2, pady = 2) - - def build_dual_camera(self): - self.dual_camera_frame =tk.Frame(self.root, bd =2 , relief = 'sunken') - self.external_trigger_button = tk.Button(self.dual_camera_frame, text = 'Ext. Trigger', bg = 'magenta', command = self.external_trigger) - self.inverter_button = tk.Button(self.dual_camera_frame, text = 'Inverter', bg = 'magenta', command = self.invert) - self.simultaneous_button = tk.Button(self.dual_camera_frame, text = 'Simultaneous', bg = 'magenta', command = self.simultaneous) - self.simul_tog = 0 - self.inver_tog = 0 - self.exttr_tog = 0 - self.camera_period_label = tk.Label(self.dual_camera_frame, text = 'Camera period') - self.camera_period_units = tk.Label(self.dual_camera_frame, text = 'ms') - self.camera_period = tk.StringVar() - self.camera_period.set('100') - self.camera_period.trace_add("write", self.change_period) - self.camera_period_entry = tk.Entry(self.dual_camera_frame, textvariable = self.camera_period) - #Organization - self.external_trigger_button.grid(row = 1, column = 0, columnspan = 3, padx = 2, pady = 2) - self.inverter_button.grid(row = 1, column = 3, columnspan = 3, padx = 2, pady = 2) - self.simultaneous_button.grid(row = 2, column = 0, columnspan = 3, padx = 2, pady = 2) - self.camera_period_label.grid(row = 2, column = 3, columnspan = 1, padx = 2, pady = 2) - self.camera_period_entry.grid(row = 2, column = 4, columnspan = 1, padx = 2, pady = 2) - self.camera_period_units.grid(row = 2, column = 5, columnspan = 1, padx = 2, pady = 2) - - def external_trigger(self): - self.com_response.set(ac.send_command(self.ser_arduino,"e")) - self.exttr_tog = (self.exttr_tog + 1)%2 - if self.exttr_tog is 1: - self.external_trigger_button.configure(bg = 'green') - else: - self.external_trigger_button.configure(bg = 'magenta') - - def invert(self): - self.com_response.set(ac.send_command(self.ser_arduino,"i")) - self.inver_tog = (self.inver_tog + 1)%2 - if self.inver_tog is 1: - self.inverter_button.configure(bg = 'green') - else: - self.inverter_button.configure(bg = 'magenta') - - def simultaneous(self): - self.com_response.set(ac.send_command(self.ser_arduino,"k")) - self.simul_tog = (self.simul_tog + 1)%2 - if self.simul_tog is 1: - self.simultaneous_button.configure(bg = 'green') + # Functions are listed alphabetically for ease of searching + def arm(self): + self.com_response.set(ac.send_command(self.ser_arduino,"a")) + self.armed = (self.armed + 1) % 2 + if self.armed is 1: + self.arm_button.configure(bg='green') else: - self.simultaneous_button.configure(bg = 'magenta') - - def change_period(self, *args): - self.com_response.set(ac.send_command(self.ser_arduino,"c",self.camera_period.get())) + self.arm_button.configure(bg='magenta') def build_axes(self): # Axes variables and current position widget @@ -138,6 +74,44 @@ def build_axes(self): self.current_y.grid(row = pos_row + 1, column = pos_col + 1, sticky = 'W') self.current_z.grid(row = pos_row + 2, column = pos_col + 1, sticky = 'W') + def build_com_box(self): + # Communication Box + self.com_frame = tk.Frame(self.stage, bd = 2, relief = 'sunken') + self.com_frame_title = tk.Label(self.com_frame, text = 'Stage Communication') + self.cmd = tk.StringVar() + self.cmd.set('A') + self.command_line = tk.Entry(self.com_frame, textvariable = self.cmd) + self.response = tk.StringVar() + self.response.set('NA') + self.command_response = tk.Label(self.com_frame, textvariable = self.response) + self.cmd_button = tk.Button(self.com_frame, text = "Send", command = self.send_asi_command) + self.com_frame_title.grid(row = 0, column = 0 , columnspan = 2) + self.command_line.grid(row = 1) + self.command_response.grid(row = 2) + self.cmd_button.grid(row = 1, column = 1) + + def build_dual_camera(self): + self.dual_camera_frame =tk.Frame(self.root, bd =2 , relief = 'sunken') + self.external_trigger_button = tk.Button(self.dual_camera_frame, text = 'Ext. Trigger', bg = 'magenta', command = self.external_trigger) + self.inverter_button = tk.Button(self.dual_camera_frame, text = 'Inverter', bg = 'magenta', command = self.invert) + self.simultaneous_button = tk.Button(self.dual_camera_frame, text = 'Simultaneous', bg = 'magenta', command = self.simultaneous) + self.simul_tog = 0 + self.inver_tog = 0 + self.exttr_tog = 0 + self.camera_period_label = tk.Label(self.dual_camera_frame, text = 'Camera period') + self.camera_period_units = tk.Label(self.dual_camera_frame, text = 'ms') + self.camera_period = tk.StringVar() + self.camera_period.set('100') + self.camera_period.trace_add("write", self.change_period) + self.camera_period_entry = tk.Entry(self.dual_camera_frame, textvariable = self.camera_period) + #Organization + self.external_trigger_button.grid(row = 1, column = 0, columnspan = 3, padx = 2, pady = 2) + self.inverter_button.grid(row = 1, column = 3, columnspan = 3, padx = 2, pady = 2) + self.simultaneous_button.grid(row = 2, column = 0, columnspan = 3, padx = 2, pady = 2) + self.camera_period_label.grid(row = 2, column = 3, columnspan = 1, padx = 2, pady = 2) + self.camera_period_entry.grid(row = 2, column = 4, columnspan = 1, padx = 2, pady = 2) + self.camera_period_units.grid(row = 2, column = 5, columnspan = 1, padx = 2, pady = 2) + def build_focus(self): # Focus Adjustment widget self.focus_frame = tk.Frame(self.stage, bd = 2, relief = 'groove') @@ -184,22 +158,6 @@ def build_stage_marks(self): self.up_mark.grid (row = 0, column = 0) self.load_last_marks.grid(row = 0, column = 2) - def build_com_box(self): - # Communication Box - self.com_frame = tk.Frame(self.stage, bd = 2, relief = 'sunken') - self.com_frame_title = tk.Label(self.com_frame, text = 'Stage Communication') - self.cmd = tk.StringVar() - self.cmd.set('A') - self.command_line = tk.Entry(self.com_frame, textvariable = self.cmd) - self.response = tk.StringVar() - self.response.set('NA') - self.command_response = tk.Label(self.com_frame, textvariable = self.response) - self.cmd_button = tk.Button(self.com_frame, text = "Send", command = self.send_asi_command) - self.com_frame_title.grid(row = 0, column = 0 , columnspan = 2) - self.command_line.grid(row = 1) - self.command_response.grid(row = 2) - self.cmd_button.grid(row = 1, column = 1) - def build_storm_wave(self): self.storm_wave_frame = tk.Frame(self.stage, bd = 2, relief = 'sunken') self.wave_title = tk.Label(self.storm_wave_frame, text = 'Storm Wave') @@ -226,20 +184,7 @@ def build_storm_wave(self): self.wave_range_label.grid(row=2, column = 2) self.wave_button.grid(row = 3, column = 1) self.uv_laser_button.grid(row=3, column = 0) - - def setup_arduino(self, ser): - flag = 1 - print('Connecting to Arduino... ', end='') - while flag is 1: - try: - self.ser_arduino = serial.Serial(ser, 9600) - flag = 0 - except: - count = 1 - print('Complete\n') - self.arduino = tk.Frame(self.root, bd =2, relief = 'groove') - self.camera_frame_setup() - + def camera_frame_setup(self): w = 5 # Define Com Response @@ -311,95 +256,24 @@ def camera_frame_setup(self): self.reset.grid(row = endrow, column = 0,columnspan = 2) self.arm_button.grid(row = endrow +1, column = 2, columnspan = 2) self.toggle_switch.grid(row = endrow + 1, column = 0,columnspan = 2) + + def change_frequency(self, *args): + self.com_response.set(ac.send_command(self.ser_arduino,"f",self.frequency.get())) - def check_camera(self): - if(self.ser_arduino.in_waiting > 0): - string = self.ser_arduino.readline() - self.camera.set(string[0:-1]) - self.arduino.after(5,self.check_camera) - - def stimulate(self): - self.com_response.set(ac.send_command(self.ser_arduino,"S")) - - def switcher(self): - self.com_response.set(ac.send_command(self.ser_arduino,"w")) - self.switch = (self.switch + 1) % 2 - if self.switch is 1: - self.toggle_switch.configure(bg='green') - else: - self.toggle_switch.configure(bg='magenta') - - def arm(self): - self.com_response.set(ac.send_command(self.ser_arduino,"a")) - self.armed = (self.armed + 1) % 2 - if self.armed is 1: - self.arm_button.configure(bg='green') - else: - self.arm_button.configure(bg='magenta') - - def reset_frame(self): - self.com_response.set(ac.send_command(self.ser_arduino,"r")) - self.camera.set("0") - - # Text change Callback functions - def wave(self): - dz = float(self.wave_dz.get()) - um = float(self.wave_range.get())*1000 - steps = int(um/dz) - self.wave_state = (self.wave_state + 1) % 2 - if self.wave_state is 1: - pyasi.send_command(self.ser_s,'ZS X=' + str(dz/100) + ' Y=' + str(steps) + '\r') - pyasi.send_command(self.ser_s,'TTL X=4\r') - self.wave_button.configure(text = 'Turn Wave Off', bg = 'green') - else: - pyasi.send_command(self.ser_s,'TTL X=0\r') - self.wave_button.configure(text = 'Turn Wave On', bg = 'magenta') - - def uv_laser(self): - ac.send_command(self.ser_arduino, '4') - self.uv_state = (self.uv_state + 1) % 2 - if self.uv_state is 1: - self.uv_laser_button.config(text = 'Turn 405 Off', bg = 'green') - else: - self.uv_laser_button.config(text = 'Turn 405 On', bg = 'magenta') - + def change_period(self, *args): + self.com_response.set(ac.send_command(self.ser_arduino,"c",self.camera_period.get())) + def change_stim(self, *args): self.com_response.set(ac.send_command(self.ser_arduino,"s",self.stimset.get())) def change_stim_number(self, *args): self.com_response.set(ac.send_command(self.ser_arduino,"n",self.stimN.get())) - - def send_asi_command(self): - self.response.set(pyasi.send_command(self.ser_s,self.cmd.get() + '\r')) - - def change_frequency(self, *args): - self.com_response.set(ac.send_command(self.ser_arduino,"f",self.frequency.get())) - - def shut_down(self): - # Close serial connections and destroy GUI - self.ser_arduino.close() - self.ser_s.close() - self.root.destroy() - - def load_marks(self): - f = open('positions.csv', 'r') - reader = csv.reader(f) - self.marks = list(reader) - f.close() - print(self.marks) - self.mark_num = len(self.marks) - self.mark_text.set('Out of {} marks'.format(self.mark_num)) - - def up_focus(self): - pyasi.send_command(self.ser_s,'r z={}\r'.format(self.focus_amount.get())) - def dwn_focus(self): - pyasi.send_command(self.ser_s,'r z=-{}\r'.format(self.focus_amount.get())) - - def go_to_mark(self): - ind = int(self.last_pos.get()) - string = 'M X = {} Y = {} Z = {}\r'.format(self.marks[ind][0],self.marks[ind][1],self.marks[ind][2]) - pyasi.send_command(self.ser_s, string) + def check_camera(self): + if(self.ser_arduino.in_waiting > 0): + string = self.ser_arduino.readline() + self.camera.set(string[0:-1]) + self.arduino.after(5,self.check_camera) def clear_mark(self): ind = int(self.last_pos.get()) @@ -409,6 +283,25 @@ def clear_mark(self): self.mark_text.set('Out of {} marks'.format(self.mark_num)) self.write_marks() + def dwn_focus(self): + pyasi.send_command(self.ser_s,'r z=-{}\r'.format(self.focus_amount.get())) + + def external_trigger(self): + self.com_response.set(ac.send_command(self.ser_arduino,"e")) + self.exttr_tog = (self.exttr_tog + 1)%2 + if self.exttr_tog is 1: + self.external_trigger_button.configure(bg = 'green') + else: + self.external_trigger_button.configure(bg = 'magenta') + + def invert(self): + self.com_response.set(ac.send_command(self.ser_arduino,"i")) + self.inver_tog = (self.inver_tog + 1)%2 + if self.inver_tog is 1: + self.inverter_button.configure(bg = 'green') + else: + self.inverter_button.configure(bg = 'magenta') + def get_position(self): [x,y,z] = pyasi.get_positions(self.ser_s) self.x.set(x) @@ -416,6 +309,20 @@ def get_position(self): self.z.set(z) self.stage.after(20, self.get_position) + def go_to_mark(self): + ind = int(self.last_pos.get()) + string = 'M X = {} Y = {} Z = {}\r'.format(self.marks[ind][0],self.marks[ind][1],self.marks[ind][2]) + pyasi.send_command(self.ser_s, string) + + def load_marks(self): + f = open('positions.csv', 'r') + reader = csv.reader(f) + self.marks = list(reader) + f.close() + print(self.marks) + self.mark_num = len(self.marks) + self.mark_text.set('Out of {} marks'.format(self.mark_num)) + def new_mark_position(self): self.marks.append([self.x.get(),self.y.get(),self.z.get()]) self.mark_num = self.mark_num + 1 @@ -423,10 +330,103 @@ def new_mark_position(self): self.mark_text.set('Out of {} marks'.format(self.mark_num)) self.write_marks() + def reset_frame(self): + self.com_response.set(ac.send_command(self.ser_arduino,"r")) + self.camera.set("0") + + def send_asi_command(self): + self.response.set(pyasi.send_command(self.ser_s,self.cmd.get() + '\r')) + + def setup_arduino(self, ser): + flag = 1 + print('Connecting to Arduino... ', end='') + while flag is 1: + try: + self.ser_arduino = serial.Serial(ser, 9600) + flag = 0 + except: + count = 1 + print('Complete\n') + self.arduino = tk.Frame(self.root, bd =2, relief = 'groove') + self.camera_frame_setup() + + def setup_stage(self, ser): + # Setup widgets and positions related to the 'stage' portion of the gui + flag = 1 + print('Opening Stage communication... ', end ='') + + while flag is 1: + try: + self.ser_s = serial.Serial(ser, 9600) + flag = 0 + except: + count = 1 + print('complete\n') + self.ser_s.write(b'vb z=3\r') + #self.ser_s.readline() + self.stage = tk.Frame(self.root, bd = 2, relief = 'sunken') # Define frame for + self.build_axes() + self.build_focus() + self.build_stage_marks() + self.get_position() + # Widget Positioning + self.axes_frame.grid(row = 0, column = 0, padx = 2, pady = 2) + self.focus_frame.grid(row = 0, column = 1, padx = 2, pady = 2) + self.stage_mark_frame.grid(row = 1, column = 0, columnspan = 2, padx = 2, pady = 2) + + def shut_down(self): + # Close serial connections and destroy GUI + self.ser_arduino.close() + self.ser_s.close() + self.root.destroy() + + def simultaneous(self): + self.com_response.set(ac.send_command(self.ser_arduino,"k")) + self.simul_tog = (self.simul_tog + 1)%2 + if self.simul_tog is 1: + self.simultaneous_button.configure(bg = 'green') + else: + self.simultaneous_button.configure(bg = 'magenta') + + def stimulate(self): + self.com_response.set(ac.send_command(self.ser_arduino,"S")) + + def switcher(self): + self.com_response.set(ac.send_command(self.ser_arduino,"w")) + self.switch = (self.switch + 1) % 2 + if self.switch is 1: + self.toggle_switch.configure(bg='green') + else: + self.toggle_switch.configure(bg='magenta') + def update_mark(self): ind = int(self.last_pos.get()) self.marks[ind] = [self.x.get(),self.y.get(),self.z.get()] + def up_focus(self): + pyasi.send_command(self.ser_s,'r z={}\r'.format(self.focus_amount.get())) + + def uv_laser(self): + ac.send_command(self.ser_arduino, '4') + self.uv_state = (self.uv_state + 1) % 2 + if self.uv_state is 1: + self.uv_laser_button.config(text = 'Turn 405 Off', bg = 'green') + else: + self.uv_laser_button.config(text = 'Turn 405 On', bg = 'magenta') + + def wave(self): + dz = float(self.wave_dz.get()) + um = float(self.wave_range.get())*1000 + steps = int(um/dz) + self.wave_state = (self.wave_state + 1) % 2 + if self.wave_state is 1: + pyasi.send_command(self.ser_s,'ZS X=' + str(dz/100) + ' Y=' + str(steps) + '\r') + pyasi.send_command(self.ser_s,'TTL X=4\r') + self.wave_button.configure(text = 'Turn Wave Off', bg = 'green') + else: + pyasi.send_command(self.ser_s,'TTL X=0\r') + self.wave_button.configure(text = 'Turn Wave On', bg = 'magenta') + def write_marks(self): f = open('positions.csv', 'w+') for i in range(len(self.marks)):