最近在研究modbus master和modbus slave。項目要求實現modbus slave虛擬機來做功能測試。
網上modbus master相關的demo很多,但是modbus slave相關的demo很少。還是Google給力,最後在google上找到一些有用的方法實現。
python是很容易實現modbus slave的工具,簡單易上手。
下面是自己寫的modbus slave demo。先安裝Anaconda,Anaconda相當於安裝了python,使用自帶的集成開發環境spyder。用的是modbus_tk庫實現modbus slave。
# -*- coding: utf-8 -*-
"""
Created on Mon Aug 21 17:00:53 2017
@author: Administrator
"""
import sys
import struct
import modbus_tk
import modbus_tk.defines as mtk
import modbus_tk.modbus
import modbus_tk.modbus_tcp
import time
import random
import string
logger = modbus_tk.utils.create_logger(name="console", record_format="%(message)s")
try:
#server = modbus_tk.modbus_tcp.TcpServer()
#這裏的端口和地址都是默認的,地址是本地:
server = modbus_tk.modbus_tcp.TcpServer(port=502, address='127.0.0.1', timeout_in_sec=3)
server.start()
slave_1 = server.add_slave(1)
# slave_2 = server.add_slave(2)
# 創建寄存器,寄存器的別名爲block1,寄存器爲保持寄存器(Holding_Register),寄存器起始地址爲0,寄存器個數爲...
slave_1.add_block('block1', modbus_tk.defines.HOLDING_REGISTERS, 0, 11)
slave_1.set_values('block1', 0, 10*[0])
slave_1.set_values('block1', 10, 255) #PLC--第0011寄存器的初始值爲高八位全爲0,低八位全爲1
# slave_1.add_block('block2', modbus_tk.defines.HOLDING_REGISTERS, 2, 1)
#給slave_1添加一個模塊(模塊名,只讀,地址,長度)
valueAll = slave_1.get_values('block1', 0, 11)
print 'valueAll: ', valueAll
valueSet = slave_1.get_values('block1', 0, 1) # 寄存器0000 -- 狀態位初始值爲全0
print 'valueSet: ', valueSet
while True:
value = slave_1.get_values('block1', 10, 1)
print 'value', value
ss = int(str(value[0]))
print 'ss:', ss
## 判斷執行機構開啓操作
if (((ss & 256) == 256) and (ss & 1) == 0): # 256 判斷“補光燈1啓動”
value1 = slave_1.get_values('block1', 0, 1)
print 'open value1:', value1
ss1 = int(str(value1[0]))
slave_1.set_values('block1', 0, (ss1 | 256))
valueSet = slave_1.get_values('block1', 0, 1)
print 'valueSet: ', valueSet
if (((ss & 256<<1) == 256<<1) and (ss & 1<<1) == 0): # 512 左移一位 判斷“補光燈2啓動”
value2 = slave_1.get_values('block1', 0, 1)
print 'open value2:', value2
ss2 = int(str(value2[0]))
slave_1.set_values('block1', 0, (ss2 | 512))
if (((ss & 256<<2) == 256<<2) and (ss & 1<<2) == 0): # 1024 左移二位 判斷“如氣風機啓動”
value3 = slave_1.get_values('block1', 0, 1)
print 'open value3:', value3
ss3 = int(str(value3[0]))
slave_1.set_values('block1', 0 , (ss3 | 1024))
if (((ss & 256<<3) == 256<<3) and (ss & 1<<3) == 0): # 2048 左移三位 判斷“供液泵啓動”
value4 = slave_1.get_values('block1', 0, 1)
print 'open value4:', value4
ss4 = int(str(value4[0]))
slave_1.set_values('block1', 0 , (ss4 | 2048))
if (((ss & 256<<4) == 256<<4) and (ss & 1<<4) == 0): # 4096 左移四位 判斷“回液泵啓動”
value5 = slave_1.get_values('block1', 0, 1)
print 'open value5:', value5
ss5 = int(str(value5[0]))
slave_1.set_values('block1', 0 , (ss5 | 4096))
## 判斷執行機構關閉操作
if ((ss & 1) == 1): # 判斷“補光燈1關閉”
value01 = slave_1.get_values('block1', 0, 1)
print 'close value01: ', value01
ss01 = int(str(value01[0]))
slave_1.set_values('block1', 0, (ss01 & (~256)))
if ((ss & 1<<1) == 1<<1): # 判斷“補光燈2關閉”
value02 = slave_1.get_values('block1', 0, 1)
print 'close value02: ', value02
ss02 = int(str(value02[0]))
slave_1.set_values('block1', 0, (ss02 & (~(256<<1))))
if ((ss & 1<<2) == 1<<2): # 判斷“如氣風機關閉”
value03 = slave_1.get_values('block1', 0, 1)
print 'close value03: ', value03
ss03 = int(str(value03[0]))
slave_1.set_values('block1', 0, (ss03 & (~(256<<2))))
if ((ss & 1<<3) == 1<<3): # 判斷“供液泵關閉”
value04 = slave_1.get_values('block1', 0, 1)
print 'close value04: ', value04
ss04 = int(str(value04[0]))
slave_1.set_values('block1', 0, (ss04 & (~(256<<3))))
if ((ss & 1<<4) == 1<<4): # 判斷“回液泵關閉”
value05 = slave_1.get_values('block1', 0, 1)
print 'close value05: ', value05
ss05 = int(str(value05[0]))
slave_1.set_values('block1', 0, (ss05 & (~(256<<4))))
value0 = slave_1.get_values('block1', 0, 1)
print 'value0:', value0
value_all = slave_1.get_values('block1', 0, 11)
sys.stdout.write('done: values read: %s\r\n' % (str(value_all)))
print '======================'
time.sleep(0.5)
except:
print '============error==========='
finally:
print '=========stop========'
server.stop()