技術乾貨 | 7個Python實用腳本,帶你輕鬆玩轉CAN通訊儀!

Kvaser CANlib是由 Kvaser精心開發的一個跨平臺通信庫,為用戶免費提供了與 CAN 匯流排交互的介面,您可👉點擊此處瞭解。Python 是一種廣泛使用的高級編程語言。在實際應用中,Python 程式通常使用 Kvaser CANlib 來與 Kvaser CAN 通訊儀交互。因此,學會使用Python和Kvaser CANlib對於開發和執行CAN匯流排通信應用程式十分重要。

本篇文章由Kvaser軟體開發資深人員Anton Carlsson與現場應用工程師L-G Fredriksson共同撰寫,旨在為使用CANlib和Python CANlib包/封裝的Kvaser CAN通訊儀的用戶提供詳盡的設置和使用指南。文章內容涉及CAN的典型應用場景,並詳細介紹了使用CANlib和Python進行Kvaser CAN通訊儀設置的多種命令和功能,包括:匯流排模式設置、參數配置以及LED測試等等。通過本文,您將更全面地瞭解CAN、CANlib和Kvaser CAN通訊儀。

《分步教程|如何使用CANlib設置Python》中,我們已經詳細闡述了:所需硬體和如何安裝軟體、快速入門與關鍵命令、發送CAN報文、故障排除及資訊獲取等初始設置內容。

在此次指南中,我們會使用到至少三個CAN通道。在本指南中,將使用👉Kvaser U100P以及👉Kvaser USBcan Pro 2xHS v2進行演示。

*腳本中出現的”Kvaser Leaf Pro HS v2″需改為您所使用的產品名稱。

當使用匯流排上的CAN通道(已通過busOn連接到匯流排上的通道)通過CANlib接收報文時,有兩種可能的模式可供選擇,分別為正常模式和靜默模式。要設置匯流排驅動程式模式,請使用“Channel.setBusOutputControl”。

正常模式是Kvaser通訊儀的默認模式,可使用setBusOutputControl手動設置為“canlib.canlib.Driver.NORMAL”。正常模式意味著驅動程式是標準的推拉模式,它既可以在匯流排上發送(推)資訊,也可以接收(拉)資訊。

某些控制器支持靜音模式,可使用 setBusOutputControl 將其設置為 “canlib.canlib.driver.SILENT”。在靜默模式下,驅動程式將被設置為僅接收。這意味著控制器不會在匯流排上傳輸任何內容,甚至連 ack(確認)位也不會傳輸。這在監聽 CAN 匯流排而又不想以任何方式干擾時非常有用。調用 .write 時仍可使用靜默通道,但報文不會正常發送。相反,報文將進入“發送佇列”而不會被發送。當發送佇列中的報文過多時,就會出現發送緩衝區溢出錯誤。

請注意,並不是所有設備都支持靜默模式。但是,當我們嘗試設置不支持靜默模式的設備時,將不會收到類似“設備未更改其模式”的任何指示。相反,該設備將發送報文並像正常模式下的設備一樣運行。如果我們在不更改其通道的情況下切換設備,這可能會造成問題。因此,在將通道設置為靜默模式之前,我們要確保通道/設備支持靜默模式。

*有兩種方法可以查詢設備是否支持靜默模式:一是從Kvaser網站獲取用戶指南,進入技術參數並在表格中確認。二是使用channel_data,要獲取通道的功能,請使用channel_data.channel_cap。然後創建一個if語句,查看channel_data.channel_cap中是否包含ChannelCap.SILENT_MODE(靜默模式)。

發送報文
CAN錯誤報文

該報文(幀)由通道ch_a發送,但在報文發送過程中,它變成了錯誤報文(錯誤幀)。這意味著沒有其他通道收到該報文,因此未添加確認位。這表明,儘管通道ch_b讀取了報文,但它沒有添加確認位,這證明了靜默通道不會干擾匯流排上發送的任何資訊流。

第二個測試是使用靜默通道發送報文並觀察CAN通訊儀。這次我們將不編寫腳本,而是使用python解釋器。要啟動python解釋器併發送報文,請在powershell中鍵入以下內容:

發送報文

這不會導致python解釋器中的任何錯誤,但如果我們查看Kvaser CAN通訊儀,通道LED將閃爍為紅色,表示出現錯誤(請參閱下圖,哪個led閃爍取決於哪個通道遇到錯誤)。當我們查看完閃爍的指示燈,請按以下步驟關閉匯流排:

關閉匯流排
Kvaser CAN通訊儀

連接到電腦的Kvaser CAN通訊儀(由PWR的綠燈指示)在其第二通道上接收到錯誤(由CAN 2上的紅燈閃爍指示)。

為了在解釋器中接收到錯誤,我們需要同時發送更多的報文。為此,我們將使用for迴圈來包圍write()命令(仍然在powershell內使用Python解釋器):

Python解釋器

請記住,完成後要關閉匯流排和通道。

這張圖片的 alt 屬性值為空,它的檔案名稱為 640-1.webp

請注意,為了能夠使用靜默通道,至少有兩個通道可以正常發送和接收報文。在本示例中,我們將添加一個Kvaser U100P,其他至少有一個通道CAN通訊儀就可以。要查看是否有兩個以上的通道可用,請再次運行腳本check_ch,本示例的結果如下:

運行腳本check_ch

與上次運行check_ch時相比,虛擬通道已從2和3降至3和4。CAN通道2已被新添加的Kvaser U100P通訊儀佔用。

下一步是使用兩個正常通道發送報文並使用第三個靜默通道進行監聽。再次回到CAN報文示例並添加代碼,此腳本將被命名為silent_listen:

silent_listen:

在powershell中運行該腳本結果如下:

我们现在可以看到,静默通道ch_c可以读取报文,ch_b也读取了报文,报文不再是错误信息。在此示例中,静默通道并不是必须的,但让我们了解了如何使用它。

有多種方法可以設置匯流排上的參數。在本教程中,我們將只關注使用預定義匯流排參數來設置、檢查和更改通道的CAN比特率,有關所有預定義參數的列表,請轉到 pycanlib.readthedocs canlib.canlib.Bitrate。

要設置比特率,請使用setBusParams()和canlib.Bitrate.BITRATE_xK作為輸入,其中x是所需的比特率。在設置比特率之前,我們將在之前使用getBusParams()來獲取標準參數,然後再使用getBusParams()查看參數是否已更改。

請注意,發送和接收通道都必須使用相同的比特率。否則,我們將收到錯誤報文,紅燈將開始閃爍。在以下示例腳本中,我們將使用發送報文示例,添加setBusParams函數並調用它change_bitrate。

報文示例

在虛擬環境中啟動此腳本將出現以下結果:

我們現在可以清楚地看到,兩個通道在更改之前具有相同的預設參數,然後在更改之後仍然具有相同的參數。通常情況下,比特率不會更改,作為快捷方式,可以在調用openChannel時設置比特率,如下所示:

所有Kvaser通訊儀都有LED,用於指示通訊儀是正常工作還是出現錯誤。我們可以使用flashLeds和不同的操作和LED來測試這些LED。操作包括打開和關閉所有LED。有關可用操作的完整列表,請前往pycanlib.readthedocs canlib.canlic.LEDAction。

請注意,並非所有操作都適用於所有Kvaser通訊儀,因為這些通訊儀具有不同數量的LED和通道。我們將使用Kvaser USBcan pro 2xHS v2來測試flashLeds,使用python解釋器運行以下命令(在執行flashLed命令時,請確保同時查看CAN通訊儀的LED):

代碼

在上面的代码中,我们执行了操作0和1。操作0是打开所有LED,而操作1是关闭所有LED。LED“闪烁”多长时间取决于第二个整数。在本例中,10000,表示10000毫秒,即10秒。这让我们有足够的时间清楚地看到LED是否正常工作。

接下来,我们将一次打开一个LED。这样,我们就可以看到,每个LED的“孔”都有两个不同颜色的LED。在下图中,我们可以看到不同的LED(白色的)在盖子内的电路板上是什么样子的。

LED

在Kvaser CAN通訊儀的內部,我們可以看到該特定通訊儀上的六個LED,該通訊儀有兩個通道(每個通道有兩個LED對和兩個PWR LED)。每個LED的指定編號如上圖所示。

在本例中,我們將打開LED 2和3,這是CAN 1的兩個LED,這兩個LED是LED 2和3,顏色分別為紅色和黃色。在Python解釋器中使用以下代碼:

代碼

如果我們使用PWR的LED,顏色將是綠色和黃色(分別為LED_0_ON和LED_1_ON)。

在canlib中有一個名為“Device”的類別,可以用來查找和跟蹤物理設備。Device類別表示一個物理設備,無論它當前是否連接,以及連接在哪個通道上。

如果設備已連接,請使用Device.find來查找設備並獲取設備對象。要搜索設備,可以使用EAN和序列號,打開虛擬環境,啟動python解釋器,並運行以下命令:

命令

Device.find將搜索並返回與輸入參數匹配的第一個設備。在前面的示例中,我們搜索了EAN為73-30130-00752-9和序列號為13406的第一個設備。

如果想要的設備當前未連接,可以使用其EAN和序列號(唯一標識特定設備所需的最小資訊)創建設備對象。對於EAN編號,只需要最後六個數字,因為前七個是默認的,在所有通訊儀上都是相同的。要創建設備,請在python解釋器中運行以下代碼:

代碼

創建新設備並通過USB連接到電腦後,我們可以使用probe_info獲取其(或任何其他設備)資訊:

這張圖片的 alt 屬性值為空,它的檔案名稱為 640-5.webp

Device.find還可以用於打開特定連接通訊儀上的通道,而不管它被分配在哪個CANlib通道號上。為此,請調用Device.find然後open_channel。這將自動打開通訊儀上的第一個本地通道:

現在,可以像使用canlib.openChannel(channel=x)打開的任何其他通道一樣使用Ch。

打開通道時,我們可以同時指定通訊儀上要使用的通道。這是通過chan_no_on_card完成的,它指定了通訊儀上的本地通道。確保chan_no_on_card整數小於通訊儀上CAN的數量(如果有兩個通道,則整數應為0或1)。

最後一步是在打開通道的同時設置比特率。

Probe_info可以在设备对象上用于获取有关连接通讯仪的信息。Probe_info使用ChannelData函数,我们可以直接使用ChannelData函数,就像在check_ch脚本中所做的那样。除了ChannelData,我们还可以使用另外两种方法来获取有关设备或通讯仪的信息。

我们获取通道数据的第一种方法是使用canlib.ChannelData(x),其中x是我们想要获取数据的通道。要运行此命令,我们需要在启动ChannelData之前启动虚拟环境和python解释器。在此示例中,我们将从通道0获取数据:

在數據對象創建並命名為dat之後,我們可以使用它從channeldata中獲得任何我們想要的資訊。有關可用數據的完整列表,請轉到pycanlib readthedocs canlib.canlib.ChannelData。

使用canlib.ChannelData需要我們知道通訊儀連接到哪個通道,這有些麻煩,因為在刪除和插入通訊儀時,它們很可能會更改通道號。因此,如果不知道通道,就無法使用ChannelData。

另外,還有兩種方法可以獲取數據對象。一種方法是查找或創建名為dev的設備,並使用dev.channel_dev(),另一種方法是打開一個通道並使用ch.channel_data()。這兩種方法都使用Python解釋器:

在這兩種選項中,dev.channel始終是正確的,也是最容易使用的。通過openChannel獲取dat的結果與之前使用的check_ch.py腳本相同。

一旦我們導入了canlib.canlib,它會枚舉連接的Kvaser CAN設備,我們可以調用getNumberOfChannels來獲取系統中枚舉通道的數量。如果我們在運行程式時同時連接和斷開通訊儀,可能會出現問題。在程式內部,我們在引用CAN通道和通訊儀時使用通道。但如果我們在程式運行時添加或刪除任何通訊儀,這些更改不會影響程式。或者,在引用某個通道時使用了錯誤的通訊儀。請注意,只有在代碼運行期間不斷連接和斷開設備時,才需要執行以下操作。

為了解決這個問題,我們將手動枚舉可用的CAN通道。該函數是canlib.enumerate_hardware,用於根據當前連接的所有設備創建一組全新的CANlib通道編號。當前打開的通道句柄仍然有效可用。但是,使用此函數時,我們需要停止根據CANlib通道號引用設備,而改為使用通道類。因為每次調用enumerate_hardware時,通道號都會更改。相反,要檢索有關特定通道的資訊,請使用Channel.channel_data。

如果我们在程序运行时连接设备,程序将无法识别是否连接了新设备。我们可以通过在虚拟环境和Python解释器内使用canlib.getNumberOfChannels来看到这一点(在此示例中,我们连接了一个USBcan并将连接一个Kvaser U100P):

接下來連接Kvaser U100P並再次運行getNumberOfChannels:

如果我們手動運行enumerate_hardware,然後運行getNumberOfChannels,我們會得到:

現在我們可以看到,不需要重新啟動程式,新通道已被識別並可以使用。

如果我們刪除一個設備,將會遇到一些問題。首先,與連接設備時一樣,在重新枚舉連接的設備(枚舉已運行)之前,程式不會識別已使用getNumberOfChannels刪除的設備:

如果在删除设备之前已打开到设备的通道,则程序仍然会尝试使用程序运行的命令与设备进行交互。运行这些命令中的大多数都会导致错误,但也有一些命令仍然有效。为了显示这一点,我们现在将尝试使用打开通道后删除的通讯仪进行写入和读取。在运行读和写命令之前,需要在Python解释器中运行设置代码:

如果現在斷開CAN通訊儀並嘗試用其中一個已刪除的通道寫入幀,我們將得到硬體錯誤異常:

要嘗試使用已刪除的通道讀取報文,我們需要在刪除通訊儀並運行讀取代碼之前再次運行設置代碼。

當您插入新設備時,如果已經啟動了程式,該設備將不會顯示。

不必重新啟動,使用enumerate。

請注意Canlib通道號“跳過”,但ch仍然有效。

當我們使用多個通訊儀和多個通道時,記住每個通道對應的是什麼可能會變得困難。為了解決這個問題,我們可以為通道重命名並賦予它們自定義名稱。要給通道自定義名稱,我們需要使用Kvaser設備指南。在Kvaser設備指南中,右鍵單擊要應用自定義名稱的通道,然後單擊“Edit Channel Name(編輯通道名稱)”。這時一個窗口會彈出,您可以在其中輸入通道名稱,然後單擊“ok”按鈕以應用名稱。要刪除名稱,只需再次打開更改通道名稱窗口並刪除插入的名稱。請注意,更改將影響所有使用通道名稱來識別設備的程式。設備也將重新啟動以設置名稱。

下一步是獲取自定義名稱並通過Python使用它。要獲取名稱,請使用canlib.getChannelData().custom_name。現在,我們將創建一個名為get_cus_name.py的腳本,以獲取所有連接設備的自定義名稱。在腳本中寫入以下代碼:

如果安裝了Kvaser USBcan,並且通道0具有自定義名稱“Green”,通道1具有自定義名稱“Red”,則將產生以下結果:

我们还可以使用自定义名称来打开特定的通道。要执行此操作,请编写以下名为open_channel_by_name的脚本,其中将包括同名函数以及用于确保其正常工作的测试。在此测试中,我们有一个具有自定义名称“USBone”的Kvaser USBcan,以及一个具有自定义名称“My Kvaser U100P“(根据所用产品更改名称)。在脚本中写入以下代码:

代碼

如果您想瞭解CAN匯流排相關解決方案或有任何問題,歡迎通過文末卡片電話聯繫我們。

本篇文章轉載合作夥伴Kvaser文章