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 的連線按 ✕ 也能直接移除,不會卡在清單裡。

Pi 5 Mecanum Robot Car: Web Control, Gyro Straight-Line Hold, Distance & Route Maps, Obstacle Avoidance | Pi 5 麥克納姆輪自走車:網頁遙控、陀螺儀走直線、距離圖與路線圖、自動避障實車調校

這台麥克納姆輪車之前是 Arduino UNO/Mega2560+ESP32-CAM 的取物機器人。這次把 Arduino 拿掉,改成 Raspberry Pi 5 直接用 GPIO 驅動兩片 L298N,加上 Logitech C310 攝影機、HC-SR04 超聲波(裝在 MG90S 伺服上可以轉頭)、MPU6050 陀螺儀,做成一台用手機網頁遙控、會自己避障的自走車。這篇記錄硬體接法、網頁介面,以及實車調校時一個一個踩到的坑。

硬體與接線

零件用途接到 Pi 5
L298N ×2四顆 TT 馬達(每片管一邊兩顆)EN 用 GPIO12/13/18/19(PWM 調速,板上 ENA/ENB 跳帽要拔),IN 用 8 支 GPIO
HC-SR04前方距離Trig GPIO17;Echo 是 5V,經 1kΩ/2kΩ 分壓才接 GPIO27
MG90S超聲波轉頭(±80°)GPIO22,電源吃 L298N 的 5V(不吃 Pi 的 5V)
MPU6050(GY-521)陀螺儀:車頭方向、撞擊偵測I2C:SDA 3 腳、SCL 5 腳、VCC 3.3V
Logitech C310影像+YOLO 物件偵測USB(640×480 YUYV,MJPG 會一直噴壞 JPEG)
18650 ×3 串聯馬達電源(12.6V 滿)→ 保護板 → 開關 → 兩片 L298N,GND 跟 Pi 共地
行動電源Pi 5 電源USB-C,跟馬達電源分開




三顆 18650 滿電 12.6V,扣掉 L298N 約 2V 壓降,馬達還是吃到 9~10V,而 TT 馬達額定 3~6V,所以程式把 PWM 上限壓在 60%。Pi 5 用行動電源供電,網頁上會顯示 Pi 的 5V 電壓;手邊這顆只有 4.75~4.89V,常跳「曾電壓不足/曾降頻」,之後要換 PD 的行動電源。

網頁操作

程式是 Python(aiohttp+lgpio+OpenCV+onnxruntime),開機自動跑成 systemd 服務,手機連 http://pi5-2:8080/:左邊搖桿前後+左右平移,右邊橢圓搖桿原地旋轉,影像上疊距離,YOLO(yolo26n,CPU 每張約 32 ms、限每秒 10 次)把看到的東西框出來。網頁每 0.1 秒送一次搖桿,超過 0.5 秒沒收到就停車(斷線、手機鎖螢幕)。


實車調校一:輪子方向與超聲波

  • 輪子方向:網頁有「單輪測試」,每顆按「正轉」都應該讓車往前推。實車 RL(左後)和 FR(右前)是反的,不用改線,在 config.yaml 把那兩顆的 invert 改成 true。
  • 超聲波第一次完全沒回音:Pi 送了 10 次 Trig,GPIO27 一次都沒變高——是接線問題(實體腳號和 GPIO 編號很容易搞混,第 13 腳是 GPIO27,GPIO13 是第 33 腳),重接後馬上量到 40 cm。
  • 轉頭後距離不會變:原本程式只在伺服朝正前方時才量,轉到 -10° 就凍結在最後一個值。改成任何角度都量,網頁標出方向(例如「63 cm 右 10°」);「太近不准往前」只看 ±15° 內的讀值。

實車調校二:陀螺儀讓車走直線

TT 馬達左右快慢不一樣,速度 50% 直走 3 秒,車頭就往左偏了 10°。加上 MPU6050 之後,搖桿沒有旋轉時程式會鎖住起步那一刻的車頭方向,偏了就讓兩邊輪子一快一慢拉回來(PD 控制),另外再學一個「這台車直走本來就要往右補多少」的固定量(積分,前/後/左/右分開學)。

版本3 秒直走的車頭偏移
沒修正10°
kp 0.037°
kp 0.1、ki 0.05、上限 0.5最多 2°,之後自己拉回,停下時 1.3°;實際走 115 cm,眼睛看是直的

兩個坑:

  • 兩個網頁互相蓋掉:我從遠端送「前進」做測試時,使用者手機的網頁還開著、每 0.1 秒送一次「搖桿放著=0」,車子其實是走走停停,第一次量到的「3 秒 80 cm」是錯的(真的是 115 cm)。改成每個網頁的搖桿分開記,有人在推就用最新推的那個,全部放開才停。
  • 積分飽和:自動模式卡在櫃子前推不動時,修正量一路累積到上限 -0.5,右輪只剩 14% 出力,車子一直往右繞。改成偏差小於 10° 才學、修正量上限 0.2、偏超過 20°(被撞歪、手轉、卡住)就改用現在的方向當目標。

距離圖與路線圖

影像下面多了兩張圖:

  • 距離圖(車身座標,車頭朝上):超聲波每 5° 一格、15 秒內的讀值畫成綠點連成輪廓;按「掃描一圈」伺服從右 80° 轉到左 80°,每 10° 量一次。黃色扇形是攝影機視角,YOLO 認得的東西畫成黃點並估距離。
  • 路線圖(俯視,出發時車頭朝上):沒有編碼器,位置是「送給四輪的速度 → 麥克納姆反運算 → 乘實測 77 cm/s(全速)」推算,方向用陀螺儀;超聲波打到的點換成世界座標畫成紅點,跑久了房間的輪廓就出來了。

攝影機估距離用「地面法」:鏡頭離地 8 cm,東西放在地上時,它的底邊在畫面越下面就越近,距離=鏡頭高度 ÷ tan(底邊在水平線下的角度);底邊碰到畫面下緣(看不到落地點)時,改用人、椅子這類已知高度的東西用框的高度估。一開始櫃子被估成 28 cm,因為鏡頭被夾子夾得往上仰——用一個放在 100 cm 的箱子校正:箱子底邊在畫面第 350 列、遠處地面的水平線在第 290 列左右,算出鏡頭往上仰約 6°,校正後估成 87 cm(從車頭算),跟超聲波的 86 cm 對得上。


自動避障:一路改了好幾版

最初的邏輯很簡單:前方 25 cm 內有東西就停、伺服左右各看 60°、往比較空的一邊轉。實車跑起來的問題和改法:

實車問題原因改法
斜面的路障偵測不到聲波被斜面彈走,收不到回音,原本當成「前方沒東西」前進時伺服在 0/左 20°/0/右 20° 輪流量,取擋在車寬內最近的;±25° 都沒回音超過 1 秒就停下來看;沒回音或接近時半速
撞到東西還一直頂沒有感測MPU6050 的加速度:水平加速度突然超過 0.9 g 當撞擊,退一點再找路
一直誤判撞到(前方還有 124 cm)起步、急停的加速度也超過門檻穩定前進 0.8 秒之後才算撞擊
跑不出房間只看左右兩個角度、固定轉一個角度;轉完還用轉之前的前方距離看 5 個角度(右 80、右 40、正前、左 40、左 80),往最空的方向轉、每次最多 30°;轉完清掉舊讀值
左右來回換、轉不出去每次重新選邊記住閃避方向:沒走出 50 cm 又被擋就繼續往同一邊;那邊累積轉 120° 還不行就記住、改另一邊;兩邊都不行就後退重來
頂著抽屜櫃推 45 秒超聲波裝得低,從櫃子下面看出去一直量到 90 cm卡住偵測:輪子推算走了 25 cm 以上,正前方距離卻變不到 1/4 → 當成卡住,後退換方向
太快自動模式不吃網頁的「速度上限」自動前進、轉彎、後退都乘上速度上限;轉彎改用陀螺儀轉到角度就停

最嚴重的坑:重開服務時暴衝

有一次車子突然全速衝進躺椅腳靠底下。查了才發現兩件事疊在一起:

  1. lgpio 的 tx_pwm(…, 0) 不會把腳位拉低:它只是停掉 PWM,腳位停在最後的電位。用 pinctrl get 一看,四支 L298N 的 EN 一直都是 high。
  2. 我用 SIGKILL 重開服務(程式收到 SIGTERM 不會自己結束,之前都用強制結束),當時車子正在自動模式轉動:方向腳停在「轉」、EN 又是 high,新程式起來前那 2~3 秒就是 100% 全速。

修法:停車時一定 gpio_write(EN, 0);systemd 服務加 ExecStartPre/ExecStopPost 用 pinctrl set … op dl 把 12 支馬達腳全部拉低、TimeoutStopSec=3;收到關閉訊號第一件事先停車。之後就算程式當掉或被砍,馬達也不會停在轉動狀態。接馬達的專案,「程式死掉時腳位會停在哪」一定要先想好。

還沒解決的

  • 超聲波看不到比它高或低的東西(躺椅腳靠、櫃子下緣、門檻),打算車頂加一顆 VL53L1X 雷射測距,跟 MPU6050 共用 I2C。
  • Pi 5 的行動電源電壓偏低(4.75~4.89V),要換 PD 5V 3A。
  • 路線圖的平移效率(假設直走的 80%)還沒實測;跑久了會飄。