2026年11月10日 星期二

CAN Bus on the ATS Console: PCAN FD, Error Frames, Scripts and UWB Ranging with NXP NCJ29D6 | ATS 操作台的 CAN 介面:PCAN FD、錯誤框處理、腳本與 NXP NCJ29D6 UWB 測距

ATS 網頁操作台除了 UART、GPIB、Ethernet,還有一個 CAN 分頁:插 PCAN(PEAK)、Kvaser 或 CANable 都能用,支援 CAN FD,可以手動送框、依 ID 彙整、寫腳本。這篇整理 CAN 介面的用法和實機踩到的坑,後半段是這次的重點:把 NXP NCJ29D6 UWB 模組的測距(ranging) 整合進 ATS。原廠的測試工具是加密的 exe,這次照它的 CAN 收發方式,在 ATS 裡用腳本就能讓兩片模組開始測距,即時看到距離、AoA,還有一個相對位置圖。

說明:本文截圖是在開發機上用模擬模式拍的(virtual CAN 上有一顆假的 ECU 和一片假的 NCJ29D6,回應格式照原廠 log),數值只是示意;實機結果是 11/06 在筆電上用兩支 PCAN-USB FD 對測的紀錄。

一、連線:掃描轉接器、鮑率、CAN FD

切到 CAN 分頁會自動掃描插著的轉接器(python-can 的 detect),下拉選單列出全部,正在使用的會反灰。選鮑率,要 CAN FD 就再選資料段速率(1M/2M/5M),別名可以取「UWB 模組」「車身 CAN」方便分辨。開了 FD 的連線名稱會帶「500k/2M FD」,跟不開 FD 視為不同裝置,log 檔也分開。

第一個坑在 PCAN 的 FD 模式:python-can 的 pcan 介面開 FD 時不吃 bitrate/data_bitrate,直接傳會得到「A parameter contains an invalid value」。要給完整的位元時序,ATS 用 80 MHz 時脈、取樣點 80% 算出來,跟 PCAN-View 的 SAE J2284-4 預設(500k/2M)一致:

# ats/ifaces.py CanBus
if c["interface"] == "pcan":
    # PCAN 的 FD 模式不吃 bitrate/data_bitrate,要完整位元時序
    kw = {"interface": "pcan", "channel": c["channel"], "timing": can.BitTimingFd.from_sample_point(
        f_clock=80_000_000, nom_bitrate=kw["bitrate"], nom_sample_point=80.0,
        data_bitrate=kw["data_bitrate"], data_sample_point=80.0)}

二、收發:手動送框、快捷、依 ID 彙整

下方輸入 ID(hex)和資料,勾 EXT(29 bit)或 FD 就能送;可以每 N ms 重複送,常用的框存成快捷(「ID#資料」格式),點一下就送。收發紀錄 → 是送出、← 是收到,FD 框會標 FD 和長度。下圖是模擬 ECU:0x100 每秒心跳,送 OBD 請求 7E0 會從 7E8 回應。

匯流排上框很多的時候,勾「依 ID 彙整」改成每個 ID 一行,顯示方向、DLC、最新資料、次數和實際週期,一眼看出哪個 ID 有沒有在送、週期對不對:

所有收發都記到 CSV(utf-8 BOM,Excel 直接開):一份總表,另外每個連線一份 logs/can/<別名+名稱>_<時間>.csv。

三、錯誤框:只顯示一次、看懂原因、2 秒自動中斷

實機遇到的狀況:接上 DUT 還沒送任何框,畫面就被錯誤框洗版,每秒約 7700 個。一開始以為是沒有 ACK,後來把 PCAN 的錯誤框解開才知道是「接收時填充錯誤、REC 127」:對方送的是 CAN FD,我們這邊沒開 FD。PCAN 錯誤框的格式是 ID=錯誤種類(1 位元/2 格式/4 填充/8 其他),data[0] 0=送出時、1=接收時,data[2]/[3] 是接收/送出錯誤計數:

ERR_KIND = {1: "位元錯誤", 2: "格式錯誤", 4: "填充錯誤", 8: "其他錯誤"}
# 例:ID 4 [4] 01 00 7f 00 → 接收時填充錯誤、REC 127
#   → 提示「鮑率不同或對方送 CAN FD(沒開 FD 時建議 500k/2M)」
# 送出端的錯誤才提示 ACK(沒接東西、只有自己一個節點)

現在的處理方式:同一波錯誤框只顯示第一個,附一行中文原因和建議;之後每秒(10 秒後每 10 秒)一行「已 N 個」。錯誤持續超過 2 秒就自動中斷這個連線,視窗留著標「已中斷」看原因,改好設定再連。另外,沒接東西時送框會因為沒有 ACK 讓控制器無限重送,PCAN 實機證實 bus.reset() 停不了,所以「剛送過框又一直錯」時會把通道關掉重開。

四、CAN 腳本

腳本一行一個框,格式跟快捷一樣是 ID#資料,前面可以加 FD、EXT;@wait 2 等 2 秒,# 開頭 是註解。CAN 沒有「查詢」,所以另外加了等回應的語法:

語法意思
7E0#02 01 0D 00 00 00 00 00送一個框
@expect 011#41 03 XX XX 00 3s等收到開頭符合的框(ID 寫 * 不限、XX 不比對),沒等到腳本就停
UCI 012#20 02 00 00送一則 UCI 訊息,一律 FD,超過 64 bytes 自動分段(下面說明)
@uci */@uci off把收到的框當 UCI 解讀(每則翻成一行中文);off 關掉並印統計
@to COM11 dio17_on => ok> 3s送到另一個開著的連線(例如 UART 控制板讓 relay 上電),可等回應

@expect 從「上一個送出的框之後」收到的開始找,而且依序消耗:同一個回應不會被兩行 @expect 用到,所以「先等 RSP、再等 NTF」這種順序可以照寫。每個 CAN 裝置各自存一份腳本(macros\can\<介面>_<通道>.yaml)。

五、UWB 測距:NXP NCJ29D6 的 UCI over CAN

NCJ29D6 是 NXP 的車用 UWB 晶片,公司的模組透過 CAN FD 跟 PC 溝通,原廠有一支 Ranging Test Tool(Python 包成 exe、Pyarmor 加密)。從它的 log、PCAN-View 的紀錄,以及另一版沒加密的原始碼,把收發方式整理出來:

項目內容
匯流排CAN FD+BRS,500k/2M(80 MHz,取樣點約 80%)
PC → 模組ID 依板子不同(原廠 Setting.ini:0x12/0x10/0x06),ATS 預設 012
模組 → PC實機是 0x011(原廠收的時候不分 ID,所以腳本的 @expect 用 *)
資料就是原始 UCI 訊息:標頭 4 bytes [MT|PBF|GID][OID][長度高][長度低];MT 1=指令 0x2X、2=回應 0x4X、3=通知 0x6X;回應後面補 00 到 FD 長度
長訊息超過 64 bytes 用 UCI 的 PBF 分段:每段 payload 最多 60、各自帶標頭,中間段 byte0 加 0x10,送的時候段間隔 20 ms

腳本的 UCI ID#訊息 會自動切段;收的方向開 @uci 時自動接回完整訊息再解讀。切段的程式照原廠 transmit_uci_message 的做法:

# ats/uci.py
def fragments(msg, size=64):
    """完整 UCI 訊息 → 一個個 CAN FD 框的資料(每段 payload 最多 60,標頭 byte2/3 是這段長度)"""
    msg = bytes(msg)
    if len(msg) <= size:
        return [msg]
    body, room, out = msg[4:], size - 4, []
    for k in range(0, len(body), room):
        seg = body[k:k + room]
        last = k + room >= len(body)
        out.append(bytes([msg[0] & 0xEF if last else msg[0] | 0x10, msg[1], len(seg) >> 8, len(seg) & 0xFF]) + seg)
    return out

內建四個腳本

這些腳本寫在 instruments/NCJ29D6/commands.yaml,標了 iface: can,所以會成為所有 CAN 連線的預設腳本:

  • 讀版本:CORE_GET_DEVICE_INFO(回應 200 多 bytes、分 4 段,接回來後顯示韌體/MAC 版本)+ DEVICE_GET_REBOOT_REASON。
  • FiRa Responder 開始測距:重設 → 低功耗關 → 天線延遲(0x2A)/天線間距 17 mm → SESSION_INIT(session ID 0xCEFAFECA)→ 共同參數(DS-TWR、channel 9、間隔 1000 ms)→ responder 參數(自己 MAC DDCC、對方 BBAA)→ START。
  • FiRa Initiator 開始測距:一樣的流程,改成 controller/initiator、自己 BBAA、對方 DDCC。
  • 停止測距:原廠結束時只送 CORE_DEVICE_RESET,沒有 SESSION_STOP;ATS 照做,並關掉 UCI 解讀、印出統計。

每一步都用 @expect 確認回應狀態 00(OK),SESSION_INIT 還會確認 handle 是 00 00 01 00(原廠後面的指令是固定照這個值寫的)。腳本開頭先 reset 是原廠沒有的,免得上一次的 session 還在,SESSION_INIT 回 SESSION_DUPLICATE。

解讀 RANGE_DATA_NTF:距離與兩個 AoA

開始測距後,模組每秒送一筆 RANGE_DATA_NTF(68 bytes,分兩個 FD 框)。開了 @uci,ATS 會把它組回來翻成一行:距離(cm)、自己量的 AoA,以及對方量的 AoA:

# ats/uci.py Decoder.range_data():每筆 TWR 量測 31 bytes(短 MAC)
mac, st, d = m[1::-1].hex().upper(), m[2], int.from_bytes(m[4:6], "little")      # MAC、狀態、距離 cm
if st == 0 and d != 0xFFFF:
    a = int.from_bytes(m[9:11], "little", signed=True) / 128                      # 自己量的 AoA(度)
    if len(m) >= 18 and m[17]:                                                    # FOM 不是 0 才有
        b = int.from_bytes(m[15:17], "little", signed=True) / 128                 # 對方量的 AoA

這個「對方量的 AoA」是實機對測才發現的:Initiator 收到的 RANGE_DATA 裡,每筆第 15~16 byte 還帶著 Responder 量到的角度,Responder 那邊這個欄位則全是 0。所以 ATS 對 Initiator 顯示「自己量/對方量」兩個 AoA,統計也分開算。

實機對測結果

11/06 在筆電上插兩支 PCAN-USB FD,各接一片模組,一邊跑 Responder、一邊跑 Initiator:CAN ID 用預設 012 就通,模組從 0x011 回。

項目結果
距離約 106 cm
Responder 自己量的 AoA-1.33°
Initiator 收到的「Responder 量的 AoA」-0.88°(跟上一列是同一個角度,兩邊差 0.45°)
Initiator 自己量的 AoA-17.73°(擺放角度造成,確認過不用處理)

停止腳本送 CORE_DEVICE_RESET 後 @uci off,會印出這次的統計:筆數、距離平均/最小/最大/差,兩個 AoA 各自的平均和範圍:


UWB 相對位置圖

只看數字不直觀,所以 CAN 視窗工具列多了「UWB 圖」,開一個彈出視窗:Responder 固定在下方朝上,Initiator 依「距離+Responder 量的 AoA」定位,箭頭是 Initiator 的正前方(由 Initiator 自己量的 AoA 推回來),還有軌跡、平滑(1/3/5/10 筆平均)、右側的距離與兩個 AoA 統計,下方是 2 分鐘曲線,滑鼠移上去看每一點的數值。伺服器解到 RANGE_DATA_NTF 時另外廣播一個 uwb 事件給這個頁面,不進收發紀錄。

還沒確認的

  • AoA 的正負方向(左正還是右正)實機還沒確認,UWB 圖先留了「左右反轉」開關。
  • PCAN-View 有設 SSP Offset 32,python-can 沒有這個參數;如果資料段不穩,先查這裡。
  • 每片板子 PC → 模組的 CAN ID 可能不同,不是 012 時要把腳本裡的 UCI 012# 改掉。

2026年11月9日 星期一

Driving an Anritsu MT8870A from the ATS Console: VSG Packets and VSA Measurements over GPIB | 用 ATS 操作台控制 Anritsu MT8870A:GPIB 送封包與量測

公司有一台 Anritsu MT8870A Universal Wireless Test Set,機箱裡插了兩片 MU887001A TRX 測試模組(Slot 1、Slot 4),可以量 WLAN、藍牙、GPS 等無線訊號。原本要用原廠的 CombiView 操作,這次把它接進自己寫的 ATS 網頁操作台,用 GPIB 控制:一片當訊號產生器(VSG)送出 802.11b 封包,另一片當分析儀(VSA)量功率、EVM 和頻率誤差,結果直接畫成曲線。這篇記錄怎麼接、怎麼操作,還有實測時踩到的坑。

先搞清楚:每一片模組都是一台獨立的儀器

MT8870A 的機箱只是電源和外殼,真正做事的是裡面的 TRX 模組。每一片模組有自己的 IP、自己的 GPIB 位址,要分開連線、分開下指令。機箱背面有 GPIB 1~4 四個接頭(選配),問 *IDN? 會回模組的型號和序號:

*IDN?    →  ANRITSU,MU887001A,6272359750,04.01.00   (模組)
*IDN? 1  →  ANRITSU,MT8870A,…                       (機箱)

兩片模組出廠的 GPIB 位址都是 1。串在同一條 GPIB 線上時,問一句會兩片同時回答,第一次回的序號會變來變去,接著就整個逾時。用下面這條指令一次設定四個 Slot 的位址,送給任一片都可以,設完重啟網路才會生效(大約 80 秒):

SYST:LANG SCPI
:SYST:COMM:GPIB:ADDR:ALL 1,1,1,2    ← Slot 1=1、Slot 4=2
:SYST:COMM:NET:REST

之後 PC 上就有兩台儀器:GPIB0::1::INSTR(Slot 1)和 GPIB0::2::INSTR(Slot 4)。開機時按住面板的 IP Reset,位址會還原成全部 1。

在 ATS 連線:自動辨識、自動標 Slot

  1. 左邊「新增連線」選 GPIB 分頁,按重新掃描,選 GPIB0::1::INSTR 按連線,另一片同樣做一次。
  2. ATS 連上後自動問 *IDN?,型號對上 MT8870A 指令集,類型顯示「頻譜」,工具列多出「RF 輸出」「腳本」「指令集」。
  3. 接著再問 :SYST:INF:SLOT?,連線名稱後面自動加上 Slot 1/Slot 4。兩片模組型號一樣,沒有這個很容易搞混哪一片在發射。
  4. 別名可以自己取,例如 VSG、VSA。

每片模組連上後,記得先切 SCPI 模式並選應用程式,不然其他指令都會回 -113 Undefined header:

SYST:LANG SCPI
INST SRW        ← Short Range Wireless:WLAN/藍牙

VSG:用「腳本」一鍵送出 11b 封包

讓模組播放標準封包波形要十幾條指令,還要等波形載入(第一次大約 40 秒)。ATS 加了「腳本」功能,把一串指令包成一個名字,選了按執行,伺服器就照順序送完,執行中按鈕會顯示目前第幾行,也可以按停止中斷。

MT8870A 預設有 8 個腳本:VSG 送 11b/11g/11n MCS7/藍牙 DH1 封包、VSG 停止發送、VSA 從 Port 1 收、VSA 從 Port 3 收、VSA 11b 量一次。按「編輯」可以直接改內容,例如把頻率改成別的頻道,存在 ATS 資料夾的 macros\,更新程式也不會被蓋掉。

「VSG:11b 11 Mbps 封包」腳本的內容:

SYST:LANG SCPI
INST SRW
ROUT:PORT:CONN:DIR PORT1,PORT1          ← 輸入埠,輸出埠(一定兩個一起給)
SOUR:GPRF:GEN:MODE NORMAL
SOUR:GPRF:GEN:ARB:FILE:LOAD 'MV887030A_b_11_1024L'
@until SOUR:GPRF:GEN:ARB:FILE:LOAD? 'MV887030A_b_11_1024L' == 0 90
SOUR:GPRF:GEN:RFS:FREQ 2412MHz
SOUR:GPRF:GEN:RFS:LEV -10               ← Port 1/2 最大 -10 dBm,Port 3/4 最大 0 dBm
SOUR:GPRF:GEN:ARB:WAV:PATT:SEL 'MV887030A_b_11_1024L',1
SOUR:GPRF:GEN:BBM ARB
SOUR:GPRF:GEN:STAT 1

工具列的「RF 輸出」按鈕對應 SOUR:GPRF:GEN:STAT 1/0/?:紅色=正在發射,按一下停止;開啟前會跳確認框。不管是按鈕、腳本還是手動送指令開關,ATS 都會再問一次狀態,按鈕跟實際一致。

VSA:量測項目畫成曲線

VSA 那格勾「曲線」,量測項目選 11b 平均功率、峰值功率、EVM、頻率誤差(可以複選),按開始量測。開始時先送一次設定(segment、觸發、濾波器、頻率、自動調準位),之後每一輪送一次「擷取+讀結果」。

MT8870A 的結果是一長串逗號分隔的數字,所以指令集的量測項目多了 field(取第幾欄)和 timeout。例如功率:

:INIT:SRW;*WAI;:FETC:SRW:SUMM:WLAN:POW? 1,1
→ 1,0,1,1,1,-9.25,-10.97,1.70,1,0,-10.97,-10.97,6,7
            第 6 欄峰值 ↑   ↑ 第 7 欄平均(dBm)

:INIT:SRW;*WAI;:FETC:SRW:SUMM:WLAN:DSSS:EVM? 1,1
→ 第 5 欄 EVM(%)、第 10 欄頻率誤差(ppm)

量測項目不指定接收埠,照模組目前的設定收;開始量測前先執行腳本「VSA:從 Port 1 收」或「從 Port 3 收」。沒抓到封包時回 1,0,1,0(只有 4 欄),那一輪曲線就不畫點。

指令集面板

按「指令集」會列出整理好的 SCPI 指令:系統、埠與線損補償、擷取設定、量測項目、讀結果、訊號產生器、RX 封包序列、FM/音訊。點一條就填進輸入框,危險的指令(例如 *RST、改 GPIB 位址、開 RF 輸出)前面有 ⚠,送出前要確認。指令來源是原廠的 MU887000A 操作手冊和 Remote Command List Examples。

面板燈號怎麼看

  • Module Status 綠:模組正常;Remote 綠:正被遠端控制。
  • 燈 2 綠:RF 輸出開著;紅:波形檔載入失敗。
  • 燈 3 綠:正在量測;紅:上一次量測失敗(下一次成功才會熄,當 VSG 不量測時會一直紅著,不代表現在有問題)。
  • 各埠的 Input/Output 燈:訊號從這個埠進/出。ROUT:PORT:CONN:DIR PORT1,PORT1 會讓 Port 1 的 Input、Output 都亮。

實測踩到的坑

  • GPIB 位址衝突:兩片模組出廠都是位址 1,串同一條線會互相干擾,要先改位址(見上面)。
  • 觸發準位:原廠範例用 :CONF:SRW:TLEV -20(相對參考準位往下 20 dB)。訊號弱時(-47 dBm、雜訊底 -59)觸發點掉進雜訊,一直亂觸發、抓不到封包;改成 -10 就穩定。
  • 11b EVM 要設濾波器:沒送 :CONF:SRW:WLB:FTYP GAUSSIAN 時 EVM 是 3.8 %,設了是 0.7 %。
  • 線要真的接通:一開始兩片之間少了 36 dB、讀數亂跳、EVM 到 50 %,最後發現兩條線各自通到別處,只是靠漏出去的訊號互相收到,而且開路的線像天線一樣收到辦公室的 2.4 GHz 訊號。判斷方法很簡單:把 VSG 關掉,VSA 還收得到東西就不是你的訊號。
  • 沒有線也能先驗證:Port 1/2 可以同時送和收,同一片模組 ROUT:PORT:CONN:DIR PORT1,PORT1 開產生器、分析也從 Port 1 收,訊號在內部繞回來,實測 -10.16 dBm、EVM 0.7 %,可以快速確認模組本身正常。
  • 查詢後面帶參數:FETC:SRW:SUMM:WLAN:POW? 1,1、*IDN? 1 這種問號後面還有參數的查詢,ATS 原本當成寫入不讀回應,回應被下一條讀走;改成看最後一段指令的標頭。

小結

現在 MT8870A 在 ATS 裡跟電源、電錶、示波器一樣,連上就自動辨識,有指令集、輸出按鈕、腳本和量測曲線,兩片模組對打的讀數也正確(-10.98 dBm、EVM 0.6 %)。下一步是接真的 Wi-Fi/藍牙 DUT 從 Port 3 量,並核對藍牙、BLE 結果的欄位,再把這些步驟串成自動測試流程。

GW Instek PPT-3615 Triple-Output Supply on the ATS Console: Channel Select, Output Button and Multi-Trace Charts | 用 ATS 操作台控制固緯 PPT-3615 三通道電源

GW Instek(固緯)PPT-3615 是三通道可程式線性電源:CH1、CH2 各 0~36 V/1.5 A,CH3 0~6 V/3 A,只有 GPIB 介面。它跟 Tektronix PS2520G 是同一台機器(OEM),所以指令集參考 Tek 的程式手冊,但實際接上去才發現 GW 韌體有不少差異。這篇記錄怎麼在 ATS 網頁操作台上控制它,以及那些手冊上沒寫的地方。

說明:本文截圖是在開發機上用模擬儀器拍的(回應格式照實機),數值只是示意;指令差異都是公司實機測出來的。

連線與辨識:*IDN? 是用分號分隔的

一般 SCPI 儀器的 *IDN? 是用逗號分隔「廠牌,型號,序號,韌體」,PPT-3615 回的卻是:

GOOD WILL;PPT-3615;0870154;SCPI:93.0 FW:1.15

ATS 原本只切逗號,結果判成「通用裝置」,後來改成逗號、分號都能切,現在可以正確辨識成「電源」,工具列也會多出「輸出」按鈕。

輸出按鈕與選通道

實機測出來跟 Tek 手冊不一樣的地方:

  • 選通道要用 :CHAN 1(CHAN 和數字中間要空格),查目前通道用 :CHAN?。手冊上的 INST:NSEL、INST:SEL 全部回 -100;寫成 :CHAN1 會 -108。之後的 VOLT、CURR、MEAS 都是對目前選的通道。
  • 輸出開關要寫完整的 OUTP:STAT 1/OUTP:STAT 0,簡寫 OUTP ON 不認得、OUTP? 會直接逾時。一開始「開始量測一直讀到 0 V」就是因為輸出根本沒開,所以 ATS 才加了輸出按鈕。三個通道是一起開關的,開之前 ATS 會跳確認框提醒先檢查電壓、限流和 OVP。
  • 不認得的查詢不回應:不會回錯誤字串,VISA 等到逾時(2 秒),之後 SYST:ERR? 會多出 -100 和 -420。
  • 查詢結尾加不加分號都可以,例如 MEAS:VOLT?;,跟以前 C# 程式的寫法相容。
  • VOLT?/CURR? 回的是設定值(限制值),實際輸出要用 MEAS:VOLT?/MEAS:CURR?。

曲線:三個通道一起看

量測功能是可以複選的清單:CH1~CH3 的電壓、電流共 6 項,勾幾項就畫幾條線。

每一項都有自己的前置指令(:CHAN n),伺服器只在通道跟目前不同時才送,所以一輪會是 :CHAN 1 → MEAS:VOLT? → MEAS:CURR? → :CHAN 2 → MEAS:CURR? → :CHAN 3 → MEAS:CURR?。第一個單位(V)畫在左軸、第二個單位(A)畫在右軸,刻度用該線的顏色。

要注意:切通道會改到面板上目前選的通道,量測停止後面板會停在最後一個通道。

指令集

指令集共 6 類 40 條、18 個錯誤碼,另外整理了保護功能:OVP 動作會關輸出並報 -300(面板 Err -013),排除後送 OUTP:PROT:CLE;OCP 一到限流就關輸出(Err -012),要 CURR:PROT:STAT OFF 再 ON 才清得掉。

2026年11月7日 星期六

Tektronix TDS3054B over Ethernet on the ATS Console: Live Scope Screen and Measurement Trends | 用 ATS 操作台控制 Tektronix TDS3054B 示波器:網路連線、畫面與量測曲線

Tektronix TDS3054B 是四通道、500 MHz 的數位示波器(TDS3000B 系列)。公司這台背後的通訊模組槽是空的,所以沒有 GPIB、也沒有 RS-232,只有內建的 Ethernet。這篇記錄怎麼把它接進 ATS 網頁操作台:網頁上照示波器螢幕畫出波形,也可以把頻率、Vpp 這些量測值畫成隨時間變化的曲線,最後是幾個讓示波器卡死的踩坑。

說明:本文截圖是在開發機上用模擬儀器拍的(回應格式照實機,CH1 是 1 kHz 方波、CH2 是正弦),數值只是示意;連線方式和踩坑都是實機經驗。

連線:Ethernet,但要走 VISA(VXI-11)

TDS3000B 的網路是 VXI-11 協定,不是常見的 raw socket(TCP 5025),所以 ATS 的「Ethernet」分頁連不上它。要走「GPIB」分頁(其實是 VISA),位址選「手動輸入」,填:

TCPIP0::192.168.10.2::INSTR
(不通再試 TCPIP0::192.168.10.2::gpib0,1::INSTR)

示波器的 IP 在面板 UTILITY → System: I/O → Ethernet Network Settings 設定,建議用固定 IP。公司這台直接用網路線接在測試桌機的第二張網卡上。手動輸入的位址連線成功一次後,ATS 會記進 visa_addresses.txt,之後就會出現在下拉選單裡。

網路儀器的位址 ATS 掃描時不會去問 *IDN?,因為這台示波器一次只接受一個 VXI-11 連線,掃描時開連線會跟正在用的程式搶。另外,瀏覽器打 http://示波器IP/ 是原廠的 e*Scope 網頁,可以看螢幕截圖、下指令,不用裝任何東西。

示波器畫面:網頁上照螢幕畫波形

連上後辨識成「示波器」類型,勾「曲線」會多一個下拉選單「示波器畫面/量測值曲線」,預設是示波器畫面。按「開始量測」,伺服器每一輪:

  1. 讀時基、觸發來源/準位/斜率、執行狀態::HORizontal:MAIn:SCAle?;:TRIGger:A:EDGe:SOUrce?;…
  2. :SELect? 看哪些通道開著,:HORizontal:RECOrdlength? 拿點數(10000)。
  3. 每個開著的通道讀 SCAle/POSition/OFFSet,設 DATa:SOUrce CHx;ENCdg ASCIi;…,讀換算係數 WFMPre:XINcr?;XZEro?;YMUlt?;YZEro?;YOFf?,最後 CURVe? 拿波形。
  4. 換算成「格」(電壓 =(原始值 − YOFf)× YMUlt + YZEro,格數 =(電壓 − OFFSet)/ SCAle + POSition),網頁照 10×8 格的螢幕畫出來。

波形資料一次一萬點,所以不寫進收發紀錄,也不進 CSV;「匯出 CSV」會存目前這一張。示波器本身的設定(時基、垂直刻度、觸發)還是在面板上調,ATS 只負責讀。

量測值曲線:長時間觀察頻率、Vpp

切到「量測值曲線」,可以從 44 個量測項目(CH1~4 × 平均、Vpp、最大、最小、RMS、頻率、週期、上升/下降時間、正脈寬、正工作週期)複選:

用的是 MEASUrement:IMMed(不顯示在螢幕上的量測),每項先送 HEADer OFF、切來源和類型,再讀 MEASUrement:IMMed:VALue?,不會動到螢幕上的四格量測。幾個要注意的地方:

  • Tek 預設回應帶標頭(:MEASUREMENT:IMMED:VALUE 1.2E0),不先送 HEADer OFF 曲線會讀不到數字。
  • 量不到(沒觸發、訊號不到一個週期、超出畫面)回 9.9E37,ATS 不畫這種點。
  • 時基 40 ms/div 以上是 Roll 模式,波形還沒成形前頻率、上升時間可能一直量不到。
  • 錯誤不會自己回傳,要用 EVMsg? 或 ALLEv? 讀事件,ATS 會附上中文說明(指令集收錄 124 個事件碼)。

踩坑:沒讀完的波形讓示波器卡死

有一次 ATS 在讀 CURVe? 的途中被強制結束,波形沒讀完、留在示波器的輸出緩衝。下次 ATS 連上問 *IDN?,先讀到的是那一大串舊波形,辨識就錯了。更糟的是嘗試「連上就讀到逾時,把殘留清掉」時,TDS3054B 的 VXI-11 直接卡死:開得了連線但什麼都不回,只能關機重開。

現在的做法是:網路儀器開連線時先 Device Clear,再送 *OPC?,一直讀到回「1」為止,前面讀到的都丟掉。絕對不要在沒送查詢的情況下去讀。正常按「停止量測」不會有這個問題,伺服器會把讀到一半的 CURVe? 讀完。

另外兩個小地方:示波器一次只收一個連線,ATS 連著時其他程式(例如另一個 ATS 視窗)會開不了,ATS 會提示「可能有別的程式正連著它」;被強制中斷後示波器大約要 30 秒才會釋放連線。如果是儀器先關機,ATS 的連線按 ✕ 也能直接移除,不會卡在清單裡。