snap7读写西门子plc1200步骤(python) PLC通讯
本文是利用snap7進行對plc1200進行讀寫,所用語言是python3,windows7下,plc具體型號為S7-1212DC/DC/DC??
注意在ubuntu安裝的時候,先安裝python3-pip在進行pip3 install,否則默認使用python2環境。
1.snap7安裝
?win+R打開運行串口,輸入cmd,確定后,輸入下面的命令:(需要提前安裝python 和 pip)
使用python的pip命令安裝即可:pip install python-snap7
截圖是我已經安裝過了,如果有問題,請檢查python安裝是夠正確,是否增加python的路徑到環境變量中。
snap7相關內容可以查看鏈接https://blog.csdn.net/Paul22101574/article/details/81583198。
不做深入探究,請繼續向下看。
******************************************************************************************
windows安裝報錯:
Traceback (most recent call last):File "Y:\Lonnox\Projekte\Bibliothek\Python und SPS\S7-1200 Test.py", line 6, in <module>plc = snap7.client.Client()File "C:\Python34\lib\site-packages\snap7\client.py", line 30, in __init__self.library = load_library()File "C:\Python34\lib\site-packages\snap7\common.py", line 54, in load_libraryreturn Snap7Library(lib_location).cdllFile "C:\Python34\lib\site-packages\snap7\common.py", line 46, in __init__raise Snap7Exception(msg) snap7.snap7exceptions.Snap7Exception: can't find snap7 library. If installed, try running ldconfig解決方法:將dll lib文件拷入python安裝文件夾。資源處有。
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
2021.3.1更新
如果在linux出現同樣的報錯,解決方法如下:
https://www.cnblogs.com/yinsedeyinse/p/13657904.html
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
******************************************************************************************
在ubantu14.04中linux系統安裝及配置
系統自帶python2,同樣的pip install python-snap7,安裝snap7庫成功。
下面配置系統的ip地址:
1.確保ubantu關閉了防火墻
?啟用
sudo ufw enablesudo ufw default deny 作用:開啟了防火墻并隨系統啟動同時關閉所有外部對本機的訪問(本機訪問外部正常)。關閉
sudo ufw disable
?查看防火墻狀態
sudo ufw status2.配置eth0或者eth1 的靜態ip地址
$gedit /etc/network/interfaces
# interfaces eth0 for snap7 connect plc auto eth0 iface eth0 inet static address 192.168.0.100 netmask 255.255.255.0 gateway 192.168.0.1保存,重啟。
ifconfig就可以看見修改了。
?
?
?
2.設置西門子PLC
使用博圖軟件對PLC屬性進行設置
(1)打開plc,更改IP地址:(注意這一步不是必須的,我自己鏈接的時候使用默認192.168.0.1總是出現連接超時或者失敗,修改了IP就好了,修改為192.168.1.11)。
(2)打開保護,修改為無保護,默認無保護。
(3)數據讀寫可以對輸入(I)、輸出(Q)、M區甚至是T區(時鐘)區讀寫,但是實際操作中,我對I區讀寫沒有任何反應,對M區和Q區測試可以,所以建議使用全局DB數據塊進行讀寫,然后PLC程序稍加修改就行。例如,原來的I0.1可以使用M10.1的數字使用==指令判別,==1接通,邏輯差不多,就是需要把I區的開關轉換成M區。
好了,廢話到此。建立全局數據塊DB_1,這里的DB號為1.
點到項目樹的DB1右擊打開屬性列表,保護為無保護。
取消優化的塊訪問,默認塊訪問是優化的
好了,看下DB塊中的數據吧。
我這里只用了這幾個,重要的是看數據塊的偏移量,這里是后面要用到的地址。
暫停,請打開網址,端好小板凳,認真觀看??http://www.ad.siemens.com.cn/service/elearning/Course/455.html
這三個視頻。如果想怎加記憶,每個視屏同名的會有強化記憶的小程序。
PLC的部分到此結束,請給PLC接上24V電源,用網線把電腦和PLC連接,把剛才修改plc的項目導入plc中。如果連不上,可以手動修改電腦的ip為192.168.1.0,和之前設置的plc需要在同一個子網下面。
下面打開python的shell,確認是否能夠連接和讀寫。
輸入下面的命令
>>> import snap7 >>> plc=snap7.client.Client() >>> plc.connect('192.168.1.11',0,1)這里需要注意的是ip和你設置的Plc的ip一致,connect的參數,0,1位一般為默認參數,是指代plc的網口插槽位置的。斷開連接直接調用plc.disconnect()就可以斷開連接了。
下面介紹兩個最最重要的函數:也就基本上只使用到這些:
read_area(area,dbnumber,start,size)write(area,dbnumber,start,data)首先介紹第一個參數,我們讀寫,主要的區別就是地址不同,plc自帶地址分類,如下:
0x81是輸入區,0x82輸出區,0x84是db塊。
第二個參數是dbnumber,輸入輸出區域默認為0,db塊就是塊的序號,我這里是數據塊_1,其實就是1號,所以寫1.
下面兩個參數,start和size,對于I0.3起始地址為0,對應size為3
對于M3.4,對應的就是M(0x83),起始地址是3,對應bit位是4,
用write_area(self, area, dbnumber, start, data):函數寫I\Q\M區不同類型寄存器的值:
??????過程與read_area相逆,根據地址和數據類型,把值填到函數的data中。
??????舉個寫的例子:client.write_area(0x82, 0,0,struct.pack('B',24)) 意思是向PLC的開關量輸出口D0.3和D0.4值寫1,24的二進制是00011000。
這里需要提醒下,因為讀寫獲得的都是16進制的數字,需要把相對應的解碼和編碼到10進制方便讀寫。
>>> plc.write_area(0x84,1,0,struct.pack('B',1))
>>> data=plc.read_area(0x84,1,0,8)
>>> print(data)
bytearray(b'\x01\x00\x00\x00\x00\x00\x00\x00')
這是對db塊的M1.0寫1,讀寫例子,。讀取時候為了減少多次讀取,我是用了一次性讀取了8位。
這里給出我記錄的某一博文的例子,有錯誤不管,哈哈哈
---------------------------------------------------------------老子是分割線--------------------------------------------------------------------------
通過讀寫PLC的M10.1、MW201來具體看看如何讀寫PLC。
import struct
import time
import snap7
def plc_connect(ip, rack=0, slot=1):
"""
連接初始化
:param ip:
:param rack: 通常為0
:param slot: 根據plc安裝,一般為0或1
:return:
"""
client = snap7.client.Client()
client.connect(ip, rack, slot)
return client
def plc_con_close(client):
"""
連接關閉
:param client:
:return:
"""
client.disconnect()
def test_mk10_1(client):
"""
測試M10.1
:return:
"""
area = snap7.snap7types.areas.MK
dbnumber = 0
amount = 1
start = 10
print(u'初始值')
mk_data = client.read_area(area, dbnumber, start, amount)
print(struct.unpack('!c', mk_data))
print(u'置1')
client.write_area(area, dbnumber, start, b'')
print(u'當前值')
mk_cur = client.read_area(area, dbnumber, start, amount)
print(struct.unpack('!c', mk_cur))
def test_mk_w201(client):
"""
測試MW201,數據類型為word
:param client:
:return:
"""
area = snap7.snap7types.areas.MK
dbnumber = 0
amount = 2
start = 201
print(u'初始值')
mk_data = client.read_area(area, dbnumber, start, amount)
print(struct.unpack('!h', mk_data))
print(u'置12')
client.write_area(area, dbnumber, start, b'')
print(u'當前值')
mk_cur = client.read_area(area, dbnumber, start, amount)
print(struct.unpack('!h', mk_cur))
time.sleep(3)
print(u'置3')
client.write_area(area, dbnumber, start, b'')
print(u'當前值')
mk_cur = client.read_area(area, dbnumber, start, amount)
print(struct.unpack('!h', mk_cur))
if __name__ == "__main__":
client_fd = plc_connect('192.168.0.1')
test_mk10_1(client_fd)
test_mk10_1(client_fd)
plc_con_close(client_fd)
從代碼可見,MW201,根據M確定area為MK,根據W確定數據amount為2Btye,根據201確定start為201,讀出來的數據根據數據長度用struct進行unpack,寫數據對應strcut的pack。
這里給出PLC變量類型和大小,這樣對應確定讀寫的amount。
---------------------------------------------------------------老子是分割線--------------------------------------------------------------------------
下面是我讀寫i0.1的例子,可是卻沒有成功,原因未知。
>>> plc.write_area(0x81,0,0,struct.pack('B',1)) >>> data=plc.read_area(0x81,0,0,1) >>> print(data) bytearray(b'\x00') >>> data=plc.read_area(0x81,0,0,8) >>> print(data) bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')下面這個同樣的,不過使用了轉碼,以供轉碼的示范
>>> plc.write_area(0x81,0,0,struct.pack('B',1)) >>> data=plc.read_area(0x81,0,0,1) >>> print(struct.unpack('!B',data)[0]) 0 >>> data=plc.read_area(0x81,0,0,0)特別提醒,對于DB塊M的讀寫時,當是多個字時,低地址的字節其實在寫入時候位于數字的高字節段,也就是高位,高地址的字節反而位于數字的低位數段。所謂的大端模式和小端模式,請自行百度。知道就行。
寫數據都是8位一次寫入,如果寫入MW類型或者Real等更大數據,需要8位分割,我的實現是每次進行位與操作,然后通過移位8位獲得高位。
?
在提供幾篇不錯的博客::
https://blog.csdn.net/xiaoxianerqq/article/details/81661010
https://blog.csdn.net/weixin_29482793/article/details/79555836
第二個博客博主做了個軟件,如果大家只是玩一下,可以看看,但是源碼沒有開放,可以用QT也完成該界面操作。
***************************************************************************更新 2020.12.15 WJ*************************************************************
如上文所示,存在字節大小端問題,所以每次讀寫的時候需要去編解碼,轉換,很費事。
偶然嘗試用可變字節數組bytearray獲得新的方法
import snap7 plc=snap7.client.Client() plc.connect('192.168.1.11',0,1)#DB1中偏移2位置寫入兩個字節 plc.write_area(0x84,1,2,b'\x12\x34')##DB1中偏移6位置寫入四個字節 plc..write_area(0x84,1,6,b'\x12\x34\x56\x78')#讀取 first=plc.read_area(0x84,1,2,2) second=plc.read_area(0x84,1,6,4)#這里可以打印出來不過都會視為字符串等 #我需要將其轉換成整數 data1=int.from_bytes(first,'big') #需要注意這里會視為無符號的整形數據 #如果存在符號,可以使用減法去計算超過你最大正整數時的復數數據#例如data2=int.from_bytes(second,'big')-0xFFFFFFFF-1?
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的snap7读写西门子plc1200步骤(python) PLC通讯的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java邮件系统(java邮件收发系统源
- 下一篇: MSP430F5529 DriverLi