This commit is contained in:
2025-12-04 17:17:09 +08:00
parent c548a08c1e
commit c5dbb6a884
16 changed files with 884 additions and 14561 deletions

View File

@@ -1,58 +1,168 @@
"""
Andor SDK3 Camera Discovery and Connection Test
Direct SDK usage without pylablib dependency
"""
import ctypes
import os
import sys
# Type definitions
AT_H = ctypes.c_int
AT_64 = ctypes.c_longlong
AT_BOOL = ctypes.c_int
# Constants
AT_SUCCESS = 0
AT_HANDLE_SYSTEM = 1
# Load DLL
dll_dir = os.path.join(os.path.dirname(__file__), "libs")
old_path = os.environ.get("PATH", "")
os.environ["PATH"] = dll_dir + os.pathsep + old_path
# Load the Andor SDK3 library
try:
if hasattr(os, "add_dll_directory"):
with os.add_dll_directory(dll_dir):
lib = ctypes.windll.LoadLibrary("atcore.dll")
else:
lib = ctypes.windll.LoadLibrary(os.path.join(dll_dir, "atcore.dll"))
finally:
os.environ["PATH"] = old_path
# Try common installation paths
sdk_paths = [
r"C:\Program Files\Andor SOLIS\atcore.dll",
r"C:\Program Files\Andor SDK3\atcore.dll",
"atcore.dll" # Try system PATH
]
# Define functions
lib.AT_InitialiseLibrary.argtypes = []
lib = None
for path in sdk_paths:
if os.path.exists(path) or path == "atcore.dll":
try:
lib = ctypes.WinDLL(path)
print(f" Loaded SDK from: {path}")
break
except OSError:
continue
if lib is None:
raise OSError("Could not find atcore.dll. Please install Andor SDK3 or Andor SOLIS.")
except Exception as e:
print(f" Failed to load Andor SDK3 library: {e}")
sys.exit(1)
# Define function signatures
lib.AT_InitialiseLibrary.restype = ctypes.c_int
lib.AT_InitialiseLibrary.argtypes = []
lib.AT_GetInt.argtypes = [AT_H, ctypes.c_wchar_p, ctypes.POINTER(AT_64)]
lib.AT_GetInt.restype = ctypes.c_int
lib.AT_FinaliseLibrary.argtypes = []
lib.AT_FinaliseLibrary.restype = ctypes.c_int
lib.AT_FinaliseLibrary.argtypes = []
lib.AT_Open.restype = ctypes.c_int
lib.AT_Open.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_int)]
lib.AT_Close.restype = ctypes.c_int
lib.AT_Close.argtypes = [ctypes.c_int]
lib.AT_GetInt.restype = ctypes.c_int
lib.AT_GetInt.argtypes = [ctypes.c_int, ctypes.c_wchar_p, ctypes.POINTER(ctypes.c_longlong)]
lib.AT_GetString.restype = ctypes.c_int
lib.AT_GetString.argtypes = [ctypes.c_int, ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_int]
lib.AT_GetStringMaxLength.restype = ctypes.c_int
lib.AT_GetStringMaxLength.argtypes = [ctypes.c_int, ctypes.c_wchar_p, ctypes.POINTER(ctypes.c_int)]
# Error checking
def check_error(code, func_name):
error_names = {
0: "SUCCESS",
1: "NOT_INITIALISED",
2: "NOT_IMPLEMENTED",
12: "INVALID_HANDLE",
39: "DEVICE_NOT_FOUND"
}
if code != 0:
error = error_names.get(code, f"UNKNOWN({code})")
raise RuntimeError(f"{func_name} failed with error: {error}")
# Helper functions
def get_int_feature(handle, feature):
value = ctypes.c_longlong()
code = lib.AT_GetInt(handle, feature, ctypes.byref(value))
check_error(code, f"AT_GetInt({feature})")
return value.value
def get_string_feature(handle, feature):
max_len = ctypes.c_int()
code = lib.AT_GetStringMaxLength(handle, feature, ctypes.byref(max_len))
check_error(code, f"AT_GetStringMaxLength({feature})")
buffer = ctypes.create_unicode_buffer(max_len.value)
code = lib.AT_GetString(handle, feature, buffer, max_len.value)
check_error(code, f"AT_GetString({feature})")
return buffer.value
# Main test code
print("=" * 60)
print("Andor SDK3 Camera Discovery Test")
print("=" * 60)
# Initialize library
print("Initializing library...")
ret = lib.AT_InitialiseLibrary()
if ret != AT_SUCCESS:
print(f"ERROR: Initialize failed, code: {ret}")
exit(1)
print("Initialize OK")
print("\n[1] Initializing Andor SDK3 library...")
code = lib.AT_InitialiseLibrary()
check_error(code, "AT_InitialiseLibrary")
print(" Library initialized successfully")
# Get device count
device_count = AT_64(0)
ret = lib.AT_GetInt(AT_HANDLE_SYSTEM, "DeviceCount", ctypes.byref(device_count))
if ret != AT_SUCCESS:
print(f"ERROR: Get device count failed, code: {ret}")
else:
print(f"Device count: {device_count.value}")
try:
# Get number of cameras (using system handle = 1)
print("\n[2] Detecting cameras...")
num_cameras = get_int_feature(1, "DeviceCount")
print(f" Found {num_cameras} camera(s)")
# Finalize library
ret = lib.AT_FinaliseLibrary()
if ret != AT_SUCCESS:
print(f"ERROR: Finalize failed, code: {ret}")
else:
print("Finalize OK")
if num_cameras == 0:
print("\n<EFBFBD> No cameras detected. Please check:")
print(" - Camera is powered on")
print(" - USB/PCIe connection is secure")
print(" - Drivers are installed correctly")
else:
# Open first camera
print(f"\n[3] Opening camera index 0...")
handle = ctypes.c_int()
code = lib.AT_Open(0, ctypes.byref(handle))
check_error(code, "AT_Open")
print(f" Camera opened (handle: {handle.value})")
try:
# Get camera information
print("\n[4] Reading camera information...")
print("-" * 60)
camera_name = get_string_feature(handle.value, "CameraName")
print(f" Camera Name : {camera_name}")
camera_model = get_string_feature(handle.value, "CameraModel")
print(f" Camera Model : {camera_model}")
serial_number = get_string_feature(handle.value, "SerialNumber")
print(f" Serial Number : {serial_number}")
firmware_ver = get_string_feature(handle.value, "FirmwareVersion")
print(f" Firmware Ver : {firmware_ver}")
# Additional info
try:
sensor_width = get_int_feature(handle.value, "SensorWidth")
sensor_height = get_int_feature(handle.value, "SensorHeight")
print(f" Sensor Size : {sensor_width} x {sensor_height} pixels")
except:
pass
try:
sensor_temp = lib.AT_GetFloat(handle.value, "SensorTemperature")
# Note: would need to define AT_GetFloat properly for this
except:
pass
print("-" * 60)
print(" Camera information retrieved successfully")
finally:
# Close camera
print("\n[5] Closing camera...")
code = lib.AT_Close(handle.value)
check_error(code, "AT_Close")
print(" Camera closed")
finally:
# Finalize library
print("\n[6] Shutting down SDK library...")
code = lib.AT_FinaliseLibrary()
check_error(code, "AT_FinaliseLibrary")
print(" Library shutdown complete")
print("\n" + "=" * 60)
print("Test completed successfully!")
print("=" * 60)