本文提供了關於如何使用 Python 通過乙太網路與 Schneider M221 和 Siemens S7-1200 PLC 進行通訊的詳細步驟。此外,我們還提供了一個打包的 Python PLC 客戶端函式庫,使您能夠輕鬆構建自己的 SCADA 控制程式,例如人機介面 (HMI)。系統概述如下所示:
# Created: 2024/06/29
# Version: v0.1.3
# Copyright: Copyright (c) 2024 LiuYuancheng
# License: MIT License
簡介
本文將引導初學者 OT 工程師完成四個基本步驟,以在 SCADA 網路中配置可程式邏輯控制器 (PLC),並使用 Python 腳本或我們的 Python 實體 PLC 通訊客戶端函式庫與 PLC 進行通訊。這四個步驟包括:
-
[步驟 1] 配置 PLC:學習如何使用 PLC 供應商的 IDE 設定 PLC 的 IP 位址,以啟用網路連線。請注意,本節不涵蓋電氣接線連接。
-
[步驟 2] 配置階梯邏輯:了解如何配置 PLC 的 I/O 和階梯邏輯圖,以連結接點、記憶體和線圈。
-
[步驟 3] 了解 PLC 通訊協定:簡要概述用於與 PLC 互動的通訊協定。本節為選修。
-
[步驟 4] 使用 Python 控制 PLC:說明如何建構 Python 程式來控制 PLC,包括展示如何使用 Python 實體 PLC 通訊客戶端 API 的程式碼範例。
M221 PLC 簡介
步驟 1:配置 Schneider M221 PLC
啟動 M221 PLC 並將其連接到網路。使用 SoMachine 編輯器搜尋並連接到 PLC 裝置。然後在MyController > ETH1
區段中為 PLC 配置固定 IP 位址並啟用 Modbus 通訊,如下所示:
圖 03:M221 PLC IP 配置頁面,版本 v1.3 (2024)
選取固定 IP 位址
並填寫 IP 資訊,勾選已啟用乙太網路/IP 協定
和已啟用 Modbus 伺服器
。然後,同一子網路中的程式可以透過 IP 位址連接到 PLC 並與 Modbus 伺服器通訊。
步驟 2:配置階梯邏輯
Rung 1: [ I0.x ] --> | M1x |
Rung 2: | M1x | --> | 您的階梯邏輯 | --> | M2x |
Rung 3: | M2x | --> ( Q0.x )
開啟 SoMachine 階梯配置頁面並新增階梯邏輯,如下所示:
圖 04:SoMachine 編輯階梯邏輯 rung,版本 v1.3 (2024)
然後,在調試頁面中,選取「PC to Controller (download)」(電腦到控制器(下載))以將階梯邏輯提交到 PLC,如下所示:
步驟 3:了解通訊協定
-
交易識別碼 (2 個位元組):交易的唯一識別碼。它通常由客戶端設定,並由伺服器回顯。
-
協定識別碼 (2 個位元組):對於 Modbus TCP,始終設定為 0。
-
長度 (2 個位元組):後續位元組的數量,包括單元識別碼、功能碼和資料。
-
單元識別碼 (1 個位元組):遠端伺服器 (PLC) 的位址。
-
功能碼 (1 個位元組):定義要執行的操作(例如,讀取保持暫存器)。
-
資料:這包括請求或回應的具體詳細資訊(例如,起始位址、暫存器數量)。
若要與 PLC 互動,您需要使用特定的 Modbus 功能碼:
-
'0f'
:用於寫入多個位元的記憶體位元存取功能碼。 -
'01'
:用於讀取內部多個位元的記憶體位元狀態擷取功能碼%M
。
若要使用更多功能,請參閱第 196 頁中的功能碼表。
Figure-06: M221 Modbus 功能碼表,版本 v1.3 (2024)
M221 Modbus-TCP 資料封包序列表如下所示:
Figure-07: M221 Modbus 封包位元組序列圖,版本 v1.3 (2024)
從記憶體讀取位元資料的 Modbus 訊息序列:
TID | PROTOCOL_ID | 長度 | UID | 功能碼 | 記憶體索引 | 位元數量 |
---|---|---|---|---|---|---|
2 個位元組 | 2 個位元組 | 2 個位元組 | 1 個位元組 | 1 個位元組 | 2 個位元組 | 2 個位元組 |
0000 |
0000 |
0006 |
01 |
01 |
<0032> |
<0008> |
將位元組資料寫入記憶體的 Modbus 訊息序列:
TID | PROTOCOL_ID | 長度 | UID | 功能碼 | 記憶體索引 | 位元索引 | 位元組索引 | 值位元組 | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2 個位元組 | 2 個位元組 | 2 個位元組 | 1 個位元組 |
要將記憶體標籤
步驟 4:使用 Python 與 PLC 通訊4.1 初始化連線 要與 PLC 通訊,首先初始化一個 TCP 用戶端,該用戶端連線到 PLC 在連接埠 502 上的 IP 位址,如下所示: self.plcAgent = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 4.2 將訊息傳送到 PLC 要將訊息傳送到 PLC,請將十六進位字串轉換為位元組: bdata = bytes.fromhex(modbusMsg) 4.3 讀取 PLC 記憶體資料 根據步驟 3,建立記憶體讀取 Modbus 訊息,並呼叫傳送函式以從 PLC 讀取記憶體位元組。 def readMem(self, memAddrTag, bitNum=8): 輸入:
4.4 寫入 PLC 記憶體資料 與資料讀取相同,根據步驟 3 中的位元組序列建立 modbus 訊息: def writeMem(self, memAddrTag, val):
完整的 Python M221 PLC 用戶端程式您可以從此連結下載完整的 Python M221 PLC 用戶端程式:。此程式包含連線 PLC、讀取/寫入記憶體位元的 API,以及一個執行緒包裝函式類別,可讓您在主程式的平行執行緒中執行 PLC 讀取器,以定期讀取 PLC 狀態。 該程式庫還提供三個測試案例:
與 Siemens S7-1200 PLC 通訊
PLC 簡介
: 西門子 S7-1200 PLC 是一款緊湊且多功能的程式邏輯控制器,專為廣泛的工業自動化應用而設計。它屬於 SIMATIC S7 系列,並以其穩健的效能、可擴展性和易用性而聞名。它具有內建的 PROFINET 介面,並支援各種通訊協定,可無縫整合到工業網路中。S7Comm 是西門子 PLC(包括 S7-1200 系列)使用的專有通訊協定,用於促進裝置和軟體之間的通訊。它透過各種實體層運作,包括乙太網路(透過 PROFINET),允許 PLC、HMI 和 SCADA 系統之間進行資料交換。
步驟 1:設定西門子 S7-1200
將西門子 S7-1200 PLC 連接到您的網路。使用西門子 PLC 編輯器軟體,,以在 PROFINET 介面頁面中設定 IP 位址:
您可以按照本文中概述的步驟:https://www.geekering.com/categories/automation/rodrigovieira/siemens-tia-portal-s7-1200-plc-online-connection-2/來設定 IP 位址並設定 PLC。 步驟 2:設定階梯邏輯和記憶體區域
| ix.x/mx.x | --> | 您的階梯邏輯 | --> | qx.x/mx.x |
若要實作此功能,請建立一個區塊並將階梯邏輯納入如下圖所示:
當使用預設記憶體區域時,接點、線圈和可編輯記憶體的起始位址如下:
步驟 3:了解通訊協定
如需詳細的 S7Comm 封包結構,您可以參考這篇文章:https://blog.viettelcybersecurity.com/security-wall-of-s7commplus-part-1/。封包結構如下所示:
為了使用 S7Comm 協定與 PLC 通訊,我們將使用 Python snap7 程式庫https://python-snap7.readthedocs.io/en/latest/。此程式庫提供函式
步驟 4:使用 Python 與 PLC 通訊4.1 初始化連線 為了建立與 PLC 的通訊,我們初始化一個 snap7 用戶端,該用戶端使用連接埠 102 連接到 PLC 的 IP 位址,如下面的程式碼片段所示: self.plcAgent = snap7.client.Client()
4.2 讀取 PLC 記憶體 S7-1200 支援從不同記憶體區域讀取各種資料類型的資料。支援下列資料類型:
|