Skip to content

Commit 9a3f6ea

Browse files
utility duplicacy removed
1 parent 46c4aeb commit 9a3f6ea

1 file changed

Lines changed: 5 additions & 171 deletions

File tree

pica/main.py

Lines changed: 5 additions & 171 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import multiprocessing
2525
from multiprocessing import Process
2626

27+
from pica.utils.GPIB_Instrument_Scanner_GUI import GPIB_Instrument_Scanner_GUI
28+
2729
try:
2830
from PIL import Image, ImageTk
2931
PIL_AVAILABLE = True
@@ -779,8 +781,9 @@ def run_gpib_test(self):
779781
"Dependency Missing",
780782
"The 'pyvisa' library is required.\n\nInstall via pip:\npip install pyvisa pyvisa-py")
781783
return
782-
# The GPIB scanner is now its own class
783-
GPIBScannerWindow(self.root, self)
784+
# The GPIB scanner is now its own class, create a new window for it
785+
scanner_window = Toplevel(self.root)
786+
GPIB_Instrument_Scanner_GUI(scanner_window)
784787

785788
def _pre_cache_markdown_files(self):
786789
"""
@@ -914,175 +917,6 @@ def _render_markdown_content(self, text_area, lines):
914917
text_area.insert('end', '\n')
915918

916919

917-
class GPIBScannerWindow(Toplevel):
918-
def __init__(self, parent, app_ref):
919-
super().__init__(parent)
920-
self.app = app_ref # Reference to the main app for styling and logging
921-
922-
self.title("GPIB/VISA Instrument Scanner")
923-
self.configure(bg=self.app.CLR_BG_DARK)
924-
self.transient(parent)
925-
926-
# --- Position the window to the top-right of the screen ---
927-
win_width, win_height = 500, 400
928-
self.update_idletasks()
929-
screen_width = self.winfo_screenwidth()
930-
x_pos = screen_width - win_width - 50
931-
y_pos = 50
932-
self.geometry(f"{win_width}x{win_height}+{x_pos}+{y_pos}")
933-
self.minsize(500, 350)
934-
935-
self.result_queue = queue.Queue()
936-
self.create_widgets()
937-
938-
self.app.log(
939-
"GPIB/VISA scanner window opened. Auto-scan will begin shortly.")
940-
self.after(100, self._process_gpib_queue) # Start the queue processor
941-
# Auto-start the scan after 1 second
942-
self.after(1000, self.start_scan)
943-
944-
def create_widgets(self):
945-
main_frame = ttk.Frame(self, padding=15)
946-
main_frame.pack(fill='both', expand=True)
947-
main_frame.rowconfigure(1, weight=1)
948-
main_frame.columnconfigure(0, weight=1)
949-
950-
controls_frame = ttk.Frame(main_frame)
951-
controls_frame.grid(row=0, column=0, sticky='ew', pady=(0, 15))
952-
controls_frame.columnconfigure((0, 1, 2), weight=1)
953-
954-
self.console_area = scrolledtext.ScrolledText(
955-
main_frame,
956-
state='disabled',
957-
bg=self.app.CLR_CONSOLE_BG,
958-
fg=self.app.CLR_TEXT,
959-
font=self.app.FONT_CONSOLE,
960-
wrap='word',
961-
bd=0)
962-
self.console_area.grid(row=1, column=0, sticky='nsew')
963-
964-
self.scan_button = ttk.Button(
965-
controls_frame,
966-
text="Scan Instruments",
967-
command=self.start_scan,
968-
style='Scan.TButton')
969-
self.scan_button.grid(row=0, column=0, padx=(0, 5), sticky='ew')
970-
guide_button = ttk.Button(
971-
controls_frame,
972-
text="Address Guide",
973-
command=self.show_address_guide,
974-
style='App.TButton')
975-
guide_button.grid(row=0, column=1, padx=5, sticky='ew')
976-
clear_button = ttk.Button(
977-
controls_frame,
978-
text="Clear Log",
979-
command=self.clear_log,
980-
style='App.TButton')
981-
clear_button.grid(row=0, column=2, padx=(5, 0), sticky='ew')
982-
983-
ttk.Button(
984-
main_frame,
985-
text="Close",
986-
style='App.TButton',
987-
command=self.destroy).grid(
988-
row=2, column=0,
989-
sticky='ew',
990-
pady=(
991-
15,
992-
0))
993-
self.log_to_scanner("Welcome to the GPIB/VISA Instrument Scanner.")
994-
self.log_to_scanner("Auto-scanning for instruments in 1 second...")
995-
996-
def log_to_scanner(self, message, add_timestamp=True):
997-
self.console_area.config(state='normal')
998-
if add_timestamp:
999-
timestamp = datetime.now().strftime("%H:%M:%S")
1000-
self.console_area.insert('end', f"[{timestamp}] {message}\n")
1001-
else:
1002-
self.console_area.insert('end', message)
1003-
self.console_area.see('end')
1004-
self.console_area.config(state='disabled')
1005-
1006-
def start_scan(self):
1007-
self.scan_button.config(state='disabled')
1008-
self.log_to_scanner("Starting scan...")
1009-
threading.Thread(target=self._gpib_scan_worker, daemon=True).start()
1010-
1011-
def clear_log(self):
1012-
self.console_area.config(state='normal')
1013-
self.console_area.delete(1.0, 'end')
1014-
self.console_area.config(state='disabled')
1015-
self.log_to_scanner("Log cleared.")
1016-
1017-
def show_address_guide(self):
1018-
guide_text = """
1019-
--- PICA Instrument Address Guide ---
1020-
Note: These are typical addresses. Use the scan results for exact values.
1021-
1022-
Temperature Controllers
1023-
• Lakeshore 340: GPIB0::12::INSTR
1024-
• Lakeshore 350: GPIB1::15::INSTR
1025-
1026-
Source-Measure Units (SMU) & Electrometers
1027-
• Keithley 2400: GPIB1::4::INSTR
1028-
• Keithley 6221: GPIB0::13::INSTR
1029-
• Keithley 6517B: GPIB1::27::INSTR
1030-
1031-
Nanovoltmeters, LCR Meters & Amplifiers
1032-
• Keithley 2182: GPIB0::7::INSTR
1033-
• Keysight E4980A: GPIB0::17::INSTR
1034-
• SRS SR830 Lock-in: GPIB0::8::INSTR
1035-
• Stanford PS365 HV: GPIB0::14::INSTR
1036-
1037-
---------------------------------------------
1038-
"""
1039-
self.log_to_scanner(guide_text, add_timestamp=False)
1040-
1041-
def _gpib_scan_worker(self):
1042-
try:
1043-
rm = pyvisa.ResourceManager()
1044-
resources = rm.list_resources()
1045-
if not resources:
1046-
self.result_queue.put(
1047-
"-> No instruments found. Check connections and retry.\n")
1048-
else:
1049-
self.result_queue.put(
1050-
f"-> Found {len(resources)} instrument(s). Querying...\n\n")
1051-
for address in resources:
1052-
try:
1053-
with rm.open_resource(address) as instrument:
1054-
instrument.timeout = 2000
1055-
idn = instrument.query('*IDN?').strip()
1056-
result = f"Address: {address}\n ID: {idn}\n\n"
1057-
self.result_queue.put(result)
1058-
except Exception as e:
1059-
result = f"Address: {address}\n Error: Could not get ID. {e}\n\n"
1060-
self.result_queue.put(result)
1061-
except pyvisa.errors.VisaIOError:
1062-
error_msg = (
1063-
"PICA could not find a VISA backend. Please install NI-VISA or run pip install pyvisa-py.\n"
1064-
"Refer to the 'Troubleshooting Installation' section in the documentation for more details.\n")
1065-
self.result_queue.put(error_msg)
1066-
except Exception as e:
1067-
error_msg = (
1068-
f"A critical VISA error occurred: {e}\n"
1069-
"Please ensure a VISA backend (e.g., NI-VISA) is installed correctly.\n")
1070-
self.result_queue.put(error_msg)
1071-
finally:
1072-
self.result_queue.put("SCAN_COMPLETE")
1073-
1074-
def _process_gpib_queue(self):
1075-
try:
1076-
message = self.result_queue.get_nowait()
1077-
if message == "SCAN_COMPLETE":
1078-
self.scan_button.config(state='normal')
1079-
self.log_to_scanner("Scan complete.")
1080-
else:
1081-
self.log_to_scanner(message, add_timestamp=False)
1082-
except queue.Empty:
1083-
pass
1084-
finally:
1085-
self.after(100, self._process_gpib_queue)
1086920

1087921

1088922
def main():

0 commit comments

Comments
 (0)