2025年12月18日 星期四

針對固定USB裝置上帶出的Com port位置下指令

使用了兩個同樣規格同類型之USB Serial Part裝置,在每次電腦重新啟動,可能因為啟動或讀取的順序關係,會造成與原先所使用的Com Port不同,有時電腦重新啟動即可復原,但如何使每次開機都可以固定在所設定的Com Port上呢?

可以利用

在裝置管理員上在COM Port的裝置上按滑鼠右鍵出現的內容上 位置的資料
利用這個資料只要不去換USB的PORT位置就可針對這個裝置下指令!



延伸閱讀

2025年12月17日 星期三

nRF52 PCA10040 DK 量產 nrf52840 產品

The nRF52 Development Kit (PCA10040) hardware provides support for the Nordic Semiconductor nRF52832 ARM Cortex-M4F CPU and the following devices:
ADC
CLOCK
FLASH
GPIO
I2C
MPU
NVIC
PWM
RADIO (Bluetooth Low Energy)
RTC
Segger RTT (RTT Console)
SPI
UART
WDT

利用 這個J-Link Prog Connector

PIN #
Signal Name
1    VDD
2    IMCU_TMSS
3    GND
4    IMCU_TCKS
5    V5V
6    IMCU_TDOS
7    Cut off
8    IMCU_TDIS
9    Cut off
10    IMCU_RESET

來做燒錄nrf52840 DUT的FW.
介面設計是同時燒錄四組DUT並且去偵測帶出的com port!
Demo Vedio:





延伸閱讀

2025年11月28日 星期五

Microchip PAC1934 - ADM00805 與 Arduino 通訊

ADM00805評估板
ADM00805具有USB連接器,用於連接到電腦進行裝置通訊。給PAC1934裝置供電有兩種方式:
一是透過USB連接器直接由VBUS供電,
二是透過VDD的外部連接供電。
利用板上MCP2221 USB轉I2C橋接器,可透過USB提供I2C通訊。
另外還有一個連接器,透過此連接器可以將VDD_IO、接地、SDA和SCL連接到PC主機板或Linux系統等外部源,可直接實現I2C通訊。有關使用直接I2C連接的重要詳細信息
Microchip_PAC193x Arduino_Library
The PAC1934 is a four channel power/energy monitor with current sensor amplifier and bus voltage monitors that feed high resolution ADCs.  Digital circuitry performs power calculations and energy accumulation.  The PAC1934 enables energy monitoring with integration periods from 1 ms to up to 36 hours.  Bus voltage, sense resistor voltage, and accumulated proportional power are stored in registers for retrieval by the system master or embedded controller. This library supports all the 4 channels on the PAC1934.  Source: http://ww1.microchip.com/downloads/en/DeviceDoc/PAC193x_Arduino_Library_v1_0_0.zip

透過Arduino的I2C與ADM00805連接去量測電壓與電流

將上述連結的Arduino Library 的Microchip_PAC193x sample upload 到Mega2560板子上就可以看到輸出了!!








延伸閱讀

2025年8月5日 星期二

PeakCAN 與 ECU Simulator 通訊利用OpenAI 來找尋DTC 的解釋

📺 影片版(約 6 分鐘):想先看實際操作的話可以直接看這支影片,完整步驟、設定與程式碼在下方文字版。
YouTube:https://youtu.be/ogyptBIosK4(winson-DIY 頻道)
在這一篇文章中PeakCAN Bus 與 ECU Simulator 通訊 擷取 DTC Data
得到DTC錯誤代碼但是有太多的錯誤代碼, 本來想說在本機建立一個database來搜尋, 靈機一動想說現在萬物都OpenAI, 於是就在得到DTC時把OpenAI API的功能寫進去來尋找 DTC的意義!
錯誤碼=>所有常見的 OBD2 錯誤代碼:解讀 P、B、C、U 程式碼
在Microsoft Visual Studio中利用NuGet 安裝OpenAI

using OpenAI;
using OpenAI.Chat;

private async void button3_Click(object sender, EventArgs e)
{
    //string dtcCode = txtDTC.Text.Trim();
    string dtcCode = "P0218".Trim();

    if (string.IsNullOrEmpty(dtcCode))
    {
        MessageBox.Show("請輸入 DTC 代碼,例如 P0202");
        return;
    }

    button3.Enabled = false;
    //txtResult.Text = "查詢中,請稍候...";
    CommonData.WriteMessage("查詢中,請稍候...", "", Color.Blue, Color.Red);

    string myApiKey = "your key";

    ChatClient client = new(
        model: "gpt-4.1",  //gpt-4
        apiKey: myApiKey
    );

    try
    {
        var prompt = $"請解釋 OBD2 故障碼 {dtcCode} 的意思,用繁體中文回答";
        
        ChatCompletion completion = await client.CompleteChatAsync(prompt);   
        CommonData.WriteMessage("查詢結果...", completion.Content[0].Text.ToString(), Color.Blue, Color.Red);
    }
    catch (Exception ex)
    {
        //txtResult.Text = "錯誤:" + ex.Message;
    }
    finally
    {
        button3.Enabled = true;
    }
}


還真的可以用!真是方便!!



補充(2026/10 更新):AI 解釋 DTC 會不會講錯?實測與改良做法
這篇是去年 8 月第一次把 OpenAI 接進 PeakCAN 程式時寫的,當時覺得「還真的可以用」。後來想把它改成不用付費、可以離線的版本,就在 GX10 本機用 Ollama 跑同一句提示詞,結果發現一個很重要的問題:AI 會很有自信地講錯故障碼的意思。這段補充整理實測結果,以及比較可靠的改良做法。

補充一、整個流程回顧
PeakCAN(PCAN-USB)──CAN 500 kbit/s──▶ ECU Simulator
  1. 送 Mode 03 讀取 DTC:ID 0x7DF,資料 01 03 00 00 00 00 00 00
  2. 收到 First Frame:ID 0x7E8,10 10 43 02 01 68 03 03
  3. 回 Flow Control:ID 0x7E0,30 00 00 00 00 00 00 00
  4. 解碼:01 68 → P0168、03 03 → P0303
  5. 把故障碼送給 AI,取得中文解釋,顯示在下方訊息區
第 1~4 步的細節在前一篇:PeakCAN 與 ECU Simulator 通訊 擷取 DTC Data。這篇補充的重點在第 5 步。

補充二、實測:本機模型會把故障碼講錯
用跟文章 C# 程式完全相同的提示詞「請解釋 OBD2 故障碼 {代碼} 的意思,用繁體中文回答」,在 GX10 上用 Ollama 問兩個本機模型,結果如下:
故障碼SAE 標準定義gemma4:12b 的回答qwen3.6:35b 的回答
P0168Fuel Temperature Too High(燃油溫度過高)❌ 燃燒過稀 Bank 1(這其實是 P0171)❌ 第三列氧感測器電路異常
P0303Cylinder 3 Misfire Detected(第 3 缸失火)✔ 正確✔ 正確
P0218Transmission Fluid Over Temperature Condition(變速箱油溫過高)❌ 冷卻液溫度感測器電路❌ 怠速時冷卻液溫度偏高

三個故障碼錯了兩個,而且錯的答案寫得非常完整,有原因、有症狀、有維修建議,看起來就像真的一樣。如果沒有對照標準定義,很容易就相信了。

文章截圖裡雲端的 gpt-4.1 這三個都答對了(P0218 變速箱溫度過高、P0168 燃油溫度過高、P0303 第 3 缸失火),大模型對常見的 P 碼確實比較準。但「這次答對」不代表每次都對,尤其是車廠自訂的 P1xxx、U 碼這類比較冷門的故障碼,大模型一樣可能亂講。

補充三、改良做法:先查表,AI 只負責解釋
一開始「本來想在本機建一個 database 來搜尋」的想法其實是對的,只是不用二選一,兩個一起用:
  1. 標準定義從本地 DTC 表查:SAE J2012 的通用碼(P0xxx、C0xxx、B0xxx、U0xxx)定義是固定的,存成一個 CSV 或字典就好
  2. 把查到的定義放進提示詞,請 AI「只根據這個定義」用中文說明代表什麼、常見原因
  3. 表裡查不到的碼不送 AI,直接顯示「未知代碼,請查原廠手冊」,不讓 AI 自己猜
同樣用 gemma4:12b,改成這種提示詞後再測一次:
提示詞:OBD2 故障碼 P0168 的 SAE 標準定義是「Fuel Temperature Too High」。
        請只根據這個定義,用繁體中文、三句話以內說明它代表什麼,
        以及最常見的兩個原因。不要更改定義。

P0168 → 引擎偵測到燃油溫度過高。最常見的兩個原因是燃油溫度傳感器故障或燃料相關系統過熱。      ✔
P0303 → 引擎偵測到第三缸發生失火……最常見的兩個原因是火星塞或點火線圈損壞。                    ✔
P0218 → 變速箱油溫過高……最常見的兩個原因是變速箱油量不足,以及內部磨損導致摩擦過熱。          ✔
P1234 → 本地表查不到,不送 AI                                                                  ✔
三個全部正確,連小模型也不會再講錯。另外,要求「三句話以內」也讓回答從 1,400~1,900 個 token 降到幾十個字,訊息區比較好讀,用雲端 API 時費用也跟著降下來。

補充四、C# 程式改良版
原本的程式有幾個地方可以改:
  • 故障碼寫死成 "P0218",實際要用解碼出來的結果;而且 ECU 一次可能回好幾個碼(畫面上的 P0168P0303),要拆開逐一查
  • API 金鑰直接寫在程式裡,改成讀環境變數,程式碼才不會不小心把金鑰一起分享出去
  • catch 區塊是空的,出錯時畫面上什麼都不會顯示,至少要把錯誤訊息印出來
1. 從 CAN 資料解碼 DTC(每 2 bytes 一個碼,高 2 bits 決定 P/C/B/U):
static List<string> DecodeDtcs(byte[] data, int count)
{
    char[] type = { 'P', 'C', 'B', 'U' };
    var list = new List<string>();
    for (int i = 0; i < count; i++)
    {
        byte b1 = data[i * 2], b2 = data[i * 2 + 1];
        if (b1 == 0 && b2 == 0) continue;           // 00 00 是填充,不是故障碼
        list.Add($"{type[b1 >> 6]}{(b1 >> 4) & 0x3}{b1 & 0xF:X}{b2:X2}");
    }
    return list;                                   // 01 68 03 03 → P0168, P0303
}
2. 先查表、再問 AI:
static readonly Dictionary<string, string> DtcTable = new()
{
    ["P0168"] = "Fuel Temperature Too High",
    ["P0303"] = "Cylinder 3 Misfire Detected",
    ["P0218"] = "Transmission Fluid Over Temperature Condition",
    // ……其餘從 CSV 載入
};

async Task<string> ExplainDtcAsync(ChatClient client, string code)
{
    if (!DtcTable.TryGetValue(code, out var name))
        return $"{code}:本地表查不到,請查原廠維修手冊";

    string prompt = $"OBD2 故障碼 {code} 的 SAE 標準定義是「{name}」。" +
                    "請只根據這個定義,用繁體中文、三句話以內說明它代表什麼," +
                    "以及最常見的兩個原因。不要更改定義。";
    ChatCompletion c = await client.CompleteChatAsync(prompt);
    return $"{code}({name}):{c.Content[0].Text}";
}
3. 雲端或本機二選一:OpenAI 的 NuGet 套件也能連 Ollama,因為 Ollama 提供相容 OpenAI 的 API,只要換掉 Endpoint:
using System.ClientModel;
using OpenAI;
using OpenAI.Chat;

// 雲端 OpenAI:金鑰從環境變數讀
ChatClient cloud = new("gpt-4.1-mini",
    Environment.GetEnvironmentVariable("OPENAI_API_KEY"));

// 本機 Ollama(GX10):金鑰隨便填,不會檢查
ChatClient local = new("gemma4:12b",
    new ApiKeyCredential("ollama"),
    new OpenAIClientOptions { Endpoint = new Uri("http://GX10的IP:11434/v1") });
注意:Ollama 預設只聽 127.0.0.1,Windows 測試機要連 GX10 的話,要在 GX10 設 OLLAMA_HOST=0.0.0.0,而且建議走 Tailscale,不要把 11434 埠直接開到公司或家裡的整個網段。

補充五、雲端 OpenAI 與本機 Ollama 怎麼選
雲端 OpenAI(gpt-4.1 / mini)本機 Ollama(GX10)
費用按 token 計費免費
網路要能連外網產線、實驗室內網也能用
速度通常幾秒這次實測 gemma4:12b 一個碼約 20~70 秒
不查表直接問常見碼大多正確實測 3 個錯 2 個,不建議
先查表再問正確實測 3 個全對

結論:不管用雲端還是本機,都建議「先查表、AI 只負責解釋」。這樣小模型就夠用,也不用擔心 AI 編出一個看起來很專業、其實是錯的答案。

延伸閱讀