文章目錄
- 說明
- 使用的庫
- openpyxl
- pyvisa
- 代碼說明
- 效果展示
- 參考
- 代碼
說明
本文介紹了 Keysight 34465A 的基本使用和 SCPI 指令設置,演示了使用 Python 的 PyVISA 庫控制兩臺 34465A 同時采集數據的完整流程,包括設置采樣參數、觸發測量、讀取數據、使用 OpenPyXL 保存到 Excel 并生成折線圖。整個過程采用模塊化代碼并加入詳細注釋,每一步都以教程形式說明,并增加了異常處理邏輯來提高健壯性。
使用的庫
openpyxl
- https://openpyxl.readthedocs.io/
- OpenPyXL 用于生成 Excel 文件和繪制圖表。
pyvisa
- https://pyvisa.readthedocs.io/en/latest/
- 在 Python 環境中,通過
pip install pyvisa pyvisa-py openpyxl
安裝依賴庫。PyVISA 用于與萬用表通訊,PyVISA-Py(或 NI-VISA)提供 VISA 后端。
代碼說明
- 生成Excel文件每次采集后直接保存;
- 使用Excel折線圖展示數據;
- 可設定采集參數(采集點數、采集時長、NPLC);
- 代碼包含異常處理(比如設備未連接、超時等);
效果展示
參考
- https://pyvisa.readthedocs.io/en/latest/
- https://docs.keysight.com/
- https://www.keysight.com/
- https://openpyxl.readthedocs.io/
- https://blog.csdn.net/Jzy140222010108/article/details/125111682
- https://blog.csdn.net/palzhj/article/details/129339224
- https://bloghome.com.cn/post/ru-he-li-yong-pyvisaku-yu-gpibjie-kou-de-ce-liang-she-bei-jin-xing-tong-xin-shi-xian-shu-ju-de-cai-ji-he-fa-song-kong-zhi-ming-ling-csdnwen-ku.html
代碼
import pyvisa
from time import sleep
from openpyxl import Workbook
from openpyxl.chart import LineChart, Reference
from datetime import datetime
import logging
# 查看詳細通信過程
#logging.basicConfig(level=logging.DEBUG) # 獲取當前時間并格式化
current_time = datetime.now().strftime("%Y%m%d-%H%M%S")# 配置日志格式和文件
logging.basicConfig(level=logging.DEBUG, # 設置日志級別format='%(asctime)s [%(levelname)s] %(message)s', # 含時間戳和日志級別handlers=[logging.FileHandler(f'DMMRecorder_{current_time}.log', encoding='utf-8'), # 輸出到文件logging.StreamHandler() # 同時輸出到控制臺]
)# 示例參數:采樣 1000 點,總時間 1秒
sample_points = 1000 # 采樣點數
total_time = 1.0 # 秒,總時間
DMM_NPLC = 0.001 # NPLC
DMM_IP_ADDR_1 = "10.0.1.83" # 萬用表1 IP 地址
DMM_IP_ADDR_2 = "10.0.1.86" # 萬用表2 IP 地址def setup_scpi(inst, dmm_nplc, sample_count, total_time):"""通過 SCPI 配置萬用表采樣參數"""inst.write(':CONF:VOLT:DC 10') # 直流量程 10Vinst.write(f':SENS:VOLT:DC:NPLC {dmm_nplc}') # NPLC=0.001inst.write(':VOLT:DC:RANG:AUTO OFF') # 關閉自動量程inst.write(':TRIG:SOUR INTERNAL') # 內部觸發inst.write(f':SAMP:COUN {sample_count}') # 采樣點數inst.write(f':SAMP:TIM {total_time/sample_count}') # 采樣間隔inst.write(':TRIG:COUN 1') # 單次觸發inst.write(':TRIG:DEL 0') # 無延時#inst.write(':INIT') # 初始化采集try:# 創建資源管理器rm = pyvisa.ResourceManager() # 列出所有可見的 VISA 資源 #devices = rm.list_resources() #logging.info("Available devices:", devices)# 打開第一個萬用表mtr1 = rm.open_resource(f'TCPIP0::{DMM_IP_ADDR_1}::hislip0::INSTR')# 打開第二個萬用表mtr2 = rm.open_resource(f'TCPIP0::{DMM_IP_ADDR_2}::hislip0::INSTR')
except Exception as e:logging.info("無法連接儀器,請檢查連接:", e)exit(1)logging.info(f'連接萬用表:{DMM_IP_ADDR_1} {DMM_IP_ADDR_2}')
logging.info(f'啟動參數:采樣點數 {sample_points},總時間 {total_time}s,NPLC {DMM_NPLC}')# 配置兩臺萬用表
setup_scpi(mtr1, DMM_NPLC, sample_points, total_time)
setup_scpi(mtr2, DMM_NPLC, sample_points, total_time)try:# 啟動采集mtr1.write(':INIT'); mtr2.write(':INIT')sleep(total_time + 3) # 等待采集完成# 讀取采集數據data1 = mtr1.query(':FETCh?') # 假設 FETCh? 返回 1000 個數據的逗號分隔字符串data2 = mtr2.query(':FETCh?')# 將字符串分割并轉換為浮點數列表voltages1 = [float(val) for val in data1.split(',')]voltages2 = [float(val) for val in data2.split(',')]
except pyvisa.VisaIOError as ve:logging.info("通訊錯誤:", ve)voltages1, voltages2 = [], []
except Exception as e:logging.info("測量失敗:", e)voltages1, voltages2 = [], []# 建立工作簿與工作表
wb = Workbook()
ws = wb.active
ws.title = "DMM_Data"# 寫入表頭
ws.append(["Time (s)", "Meter1 (V)", "Meter2 (V)"])# 寫入數據行:假設等間隔采樣
for i in range(len(voltages1)):t = i * (total_time / sample_points)ws.append([t, voltages1[i], voltages2[i]])# 創建折線圖
chart = LineChart()
chart.title = "Voltage vs Time"
chart.x_axis.title = "Time (s)"
chart.y_axis.title = "Voltage (V)"# Y 軸數據范圍:第2列和第3列(不包括表頭)
data = Reference(ws, min_col=2, min_row=2, max_col=3, max_row=len(voltages1)+1)
chart.add_data(data, titles_from_data=False)# X 軸類別:第1列(時間)
cats = Reference(ws, min_col=1, min_row=2, max_row=len(voltages1)+1)
chart.set_categories(cats)# 顯示所有數據點(關鍵步驟)
for series in chart.series:series.marker.symbol = "circle" # 點形狀:圓形series.marker.size = 3 # 點大小series.graphicalProperties.line.noFill = False # 顯示連接線# 將圖表插入到工作表,例如 E2 單元格開始
ws.add_chart(chart, "E2")# 保存 Excel 文件
file_name = "measurement_data_" + current_time + ".xlsx"
wb.save(file_name)
logging.info(f"數據已保存到 {file_name}")