国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

python 基于modbus_tk庫實現(xiàn)modbusTCP 主站和從站[非常詳細]

這篇具有很好參考價值的文章主要介紹了python 基于modbus_tk庫實現(xiàn)modbusTCP 主站和從站[非常詳細]。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


最近做了一個modbus tcp 傳輸浮點數(shù)的項目,參考了一些CSDN大佬的文章,這里做一個 整合和記錄

modbus 協(xié)議

modbus 通信過程

  • 摘自詳解Modbus通信協(xié)議—清晰易懂
  • 一主多從的通信協(xié)議:Modbus 通信中只有主機可以發(fā)送請求。其他從設備接收主機發(fā)送的數(shù)據(jù)來進行響應——處理信息和使用 Modbus 將其數(shù)據(jù)發(fā)送給主站。從機不會主動發(fā)送消息給主站。
  • Modbus 不能同步進行通信,主機在同一時間內(nèi)只能向一個從機發(fā)送請求,總線上每次只有一個數(shù)據(jù)進行傳輸,即主機發(fā)送,從機應答,主機不發(fā)送,總線上就沒有數(shù)據(jù)通信。
  • Modbus沒有忙機制判斷,比方說主機給從機發(fā)送命令, 從機沒有收到或者正在處理其他東西,這時候就不能響應主機,因為 modbus 的總線只是傳輸數(shù)據(jù),沒有其他仲裁機制,所以需要通過軟件的方式來判斷是否正常接收。

Modbus 數(shù)據(jù)傳輸?shù)姆绞?,可以簡單地理解成打電話。并且是單向通信的打電?/p>

主機發(fā)送數(shù)據(jù),首先需要從機的電話號碼(區(qū)分每個從機,每個地址必須唯一),告訴從機打電話要干什么事情,然后是需要發(fā)送的內(nèi)容,最后再問問從機,我說的話你都聽清楚了沒有呀,沒有聽錯吧?

然后從機這里,得到了主機打過來的電話,從機回復主機需要的內(nèi)容,主機得到從機數(shù)據(jù),這樣就是一個主機到從機的通信過程

modbus 存儲區(qū)

  • 忘記從哪找的了hhh

  • 從機存儲數(shù)據(jù) -> 存儲區(qū)

    • 文件操作 -> 只讀(-r)和讀寫(-wr)
    • 數(shù)據(jù)類型 -> 布爾量 和 16 位寄存器
      • 布爾量比如 IO 口的電平高低,燈的開關(guān)狀態(tài)等。
      • 16 位寄存器比如 傳感器的溫度數(shù)據(jù),存儲的密碼等。
  • Modbus 協(xié)議規(guī)定了 4 個存儲區(qū),分別是 0 1 3 4 區(qū) 其中 1 區(qū)和 4 區(qū)是可讀可寫,1 區(qū)和 3 區(qū)是只讀

    區(qū)號 名稱 讀寫 地址范圍
    0 區(qū) 輸出線圈 可讀可寫布爾量 00001-09999
    1 區(qū) 輸入線圈 只讀布爾量 10001-19999
    3 區(qū) 輸入寄存器 只讀寄存器 30001-39999
    4 區(qū) 保持寄存器 可讀可寫寄存器 40001-49999
  • Modbus 給每個區(qū)都劃分了地址范圍,主機向從機獲取數(shù)據(jù)時,只需要告訴從機數(shù)據(jù)的起始地址,還有獲取多少字節(jié)的數(shù)據(jù),從機就可以發(fā)送數(shù)據(jù)給主機

  • 每一個從機,都有實際的物理存儲,跟 modbus 的存儲區(qū)相對應,主機讀寫從機的存儲區(qū),實際上就是對從機設備對應的實際存儲空間進行讀寫

Modbus-TCP 協(xié)議

Modbus-TCP 報文幀結(jié)構(gòu)

  • 摘自ModbusTCP協(xié)議報文詳細分析

  • 報文幀結(jié)構(gòu)

    > > > MBAP 報文頭(7 bytes) > 協(xié)議數(shù)據(jù)單元(PDU)
    事務處理標識符 協(xié)議標識符 長度 單元標識符 功能碼 數(shù)據(jù)
    2 bytes 2 bytes 2 bytes 1 byte 1 byte N bytes
  • MBAP 報文頭

    長度 說明 客戶機 服務器
    事務處理標識符 2 字節(jié) Modbus 請求/響應事務處理的標識 客戶機啟動 復制響應
    協(xié)議標識符 2 字節(jié) 0=Modbus 協(xié)議 客戶機啟動 復制響應
    長度 2 字節(jié) 長度之后的字節(jié)總數(shù) 客戶機啟動 服務器啟動
    單元標識符 1 字節(jié) 串行鏈路或其它總線的從站識別 客戶端啟動 復制響應

    事務處理標識符 and 協(xié)議標識符 正常使用設置為 0 即可,長度為 4 個字節(jié) -> 0x00000000

  • 功能碼

    功能碼 功能說明
    01H 讀取輸出線圈
    02H 讀取輸入線圈
    03H 讀取保持寄存器
    04H 讀取輸入寄存器
    05H 寫入單線圈
    06H 寫入單寄存器
    0FH 寫入多線圈
    10H 寫入多寄存器
  • 每次可讀數(shù)據(jù)最長長度(260 字節(jié) - 9 字節(jié) = 251 字節(jié))

    • Modbus TCP 報文幀最長為 260 字節(jié) -> MBAP 7 字節(jié) + PDU 253 字節(jié)
    • 返回報文的 PDU 中: 功能碼 1 字節(jié) + 字節(jié)計數(shù) 1 字節(jié) + 數(shù)據(jù) 251 字節(jié)
    • 一個寄存器 2 字節(jié)
    • 當數(shù)據(jù)為 32 位浮點數(shù),一個數(shù)據(jù)占用兩個寄存器 -> 一個數(shù)據(jù) 4 字節(jié)
    • 每次最多可讀取:數(shù)據(jù) 251 字節(jié) -> 125 個寄存器 -> 62 個 32 位浮點數(shù)(讀取 124 個寄存器)
    • 從站返回報文格式詳解
    > > 返回報文編碼格式詳解
    字節(jié)位 結(jié)構(gòu) 編碼格式
    前 6 個字節(jié) 事務/協(xié)議和數(shù)據(jù)長度 ‘>HHH’
    第 7 個字節(jié) 單元標識 ‘>B’
    第 8 個字節(jié) 功能碼 ‘>B’
    第 9 個字節(jié) 數(shù)據(jù)長度 ‘>B’
    剩余字節(jié) 數(shù)據(jù) data_format(default or 自定義)

mosbus_tk庫

介紹

  • 安裝: pip install modbus_tk
  • github主頁
  • 主站示例代碼
  • 從站示例代碼

從站記錄的數(shù)據(jù)格式

timestamp lon lat cog
1651924800 108.6030967 20.57094167 169.9
1651925400 108.6061227 20.56535943 170.7
1651926000 108.6091487 20.5597772 171.7
1651926600 108.6121746 20.55419496 143.8
1651927200 108.6152006 20.54861273 203.8
1651927800 108.6182266 20.5430305 207.8
1651928400 108.6212526 20.53744826 181.4
1651929000 108.6242786 20.53186603 180.6
1651929600 108.6273046 20.52628379 179.2
1651930200 108.6303306 20.52070156 172.9
1651930800 108.6333566 20.51511933 172.6
1651931400 108.6363826 20.50953709 173

主站

  • 根據(jù)示例改的,直接上代碼
import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_tcp, hooks
import numpy as np
import pandas as pd

master = modbus_tcp.TcpMaster()
master.set_timeout(5.0)
print("connected")

# 連接從站讀取數(shù)據(jù),一次最多讀取125個寄存器,由于2個寄存器為一個數(shù)據(jù),故 size 設置為124
data = []  # 存放讀取的數(shù)據(jù)
data += master.execute(  # 向從站發(fā)報文讀取[0,123]區(qū)間的寄存器數(shù)據(jù)
    1,  # 從站標識符
    cst.READ_HOLDING_REGISTERS,  # 功能碼
    0,  # 起始寄存器地址
    124,  # 讀取的寄存器數(shù)量
    data_format='62f',  # 數(shù)據(jù)解碼格式
)
data += master.execute( # 向從站發(fā)送報文讀取[124,247]區(qū)間的寄存器數(shù)據(jù)
    1, cst.READ_HOLDING_REGISTERS, 124, 124, data_format='62f'
)

# 將數(shù)據(jù)保存到csv文件中
if len(data) % 4 != 0:  # 如果數(shù)據(jù)長度不是4的倍數(shù),則用 0 補齊
    for i in range(0, 4 - len(data) % 4):
        data.append(0)
data = np.reshape(data, (-1, 4))  # 將數(shù)據(jù)重新轉(zhuǎn)為4列的二維數(shù)組
# print(data, data.shape) # 打印數(shù)據(jù)
df = pd.DataFrame(
    data, columns=['timestamp', 'lon', 'lat', 'cog']
)  # 將數(shù)據(jù)轉(zhuǎn)為DataFrame,設置列名
df.to_csv('data_recv.csv', index=False)  # 將數(shù)據(jù)保存到csv文件中
  • 常見問題:
    • Modbus Error: Exception code = 3: 看看是不是接收的數(shù)據(jù)超出最大長度了

    • struct.error: unpack requires a buffer of xx bytes: 如果在master.execute()時設置了data_format,注意data_format必須與接收到的數(shù)據(jù)長度匹配!

      • 例如傳輸?shù)臄?shù)據(jù)為32位float,每個數(shù)據(jù)為4個字節(jié),收到24字節(jié)的數(shù)據(jù),那么收到了6個數(shù)據(jù),那么data_format必須為'6f'

從站

  • 從站負責接收主站的請求并返回數(shù)據(jù),modbut_tk庫已經(jīng)集成好了這些功能,所有從站的代碼非常簡單。
  • 當我們給從站存入數(shù)據(jù)時,一個寄存器只有2個字節(jié),那么怎么存入4個字節(jié)的數(shù)據(jù)呢?
    1. 當量縮放:量程固定時不傳輸具體數(shù)據(jù),只傳輸百分比0-100%
    2. 用兩個寄存器存一個數(shù)據(jù):把32位浮點數(shù)分為兩部分(代碼中就是這種方法)
pi_bytes = [int(a_byte) for a_byte in struct.pack("f", num)]
pi_register1 = pi_bytes[0] * 256 + pi_bytes[1]
pi_register2 = pi_bytes[2] * 256 + pi_bytes[3]
registers_list.append(pi_register1)
registers_list.append(pi_register2)
  • 上完整代碼!
import sys

import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_tcp, hooks
import struct
import pandas as pd
'''
可使用的函數(shù):
創(chuàng)建從站: server.add_slave(slave_id)
    slave_id(int):從站id
為從站添加存儲區(qū): slave.add_block(block_name, block_type, starting_address, size)
    block_name(str):block名
    block_type(int):block類型,COILS = 1,DISCRETE_INPUTS = 2,HOLDING_REGISTERS = 3,ANALOG_INPUTS = 4
    starting_address(int):起始地址
    size(int):block大小
設置block值:slave.set_values(block_name, address, values)
    block_name(str):block名
    address(int):開始修改的地址
    values(a list or a tuple or a number):要修改的一個(a number)或多個(a list or a tuple)值
獲取block值:slave.get_values(block_name, address, size)
    block_name(str):block名
    address(int):開始獲取的地址
    size(int):要獲取的值的數(shù)量
'''
# 創(chuàng)建從站總服務器
server = modbus_tcp.TcpServer(address='127.0.0.1')  # address必須設置,port默認為502
print("running...")
print("enter 'quit' for closing the server")
server.start()

# 創(chuàng)建從站
slave_1 = server.add_slave(1)  # slave_id = 1
# 為從站添加存儲區(qū)
slave_1.add_block(
    '0', cst.HOLDING_REGISTERS, 0, 1200
)  # block_name = '0', block_type = cst.HOLDING_REGISTERS, starting_address = 0, size = 1200

# 將數(shù)據(jù)存入寄存器
data = pd.read_csv('modbus_tcp.csv').values  # 讀取數(shù)據(jù)data
num_array = data.flatten()  # 將data壓為一維數(shù)組

registers_list = []  # 要存入寄存器的數(shù)據(jù)

# 將數(shù)據(jù)轉(zhuǎn)化為32位float格式,每個數(shù)據(jù)4個字節(jié) -> 占2個寄存器
for num in num_array:
    pi_bytes = [int(a_byte) for a_byte in struct.pack("f", num)]
    pi_register1 = pi_bytes[0] * 256 + pi_bytes[1]
    pi_register2 = pi_bytes[2] * 256 + pi_bytes[3]
    registers_list.append(pi_register1)
    registers_list.append(pi_register2)
slave_1.set_values(
    '0', 0, registers_list
)  # 將數(shù)據(jù)存入寄存器, block_name = '0', address = 0, values = registers_list

while True:
    cmd = sys.stdin.readline()  # input
    args = cmd.split(' ')  # 按空格分割輸入

    if cmd.find('quit') == 0:  # 指令 quit -> 退出服務器
        print('bye-bye')
        break
  • 可以看到,從站的代碼非常簡單!從站只需要一直開著(while True),當主站發(fā)送請求時,從站就會自動處理請求

hook函數(shù)

  • 主站從站都可以設置多個hook函數(shù),實現(xiàn)自定義的功能
def on_before_connect(args):
    '''
    鉤子函數(shù),連接前輸出主站信息

    Args:
        args (tuple): (self(主站對象),)
    '''
    master = args[0]
    print("host: {0},port: {1}".format(master._host, master._port))

hooks.install_hook("modbus_tcp.TcpMaster.before_connect", on_before_connect)

def on_after_recv(args):
    '''
    鉤子函數(shù),在收到報文后輸出報文總長度

    Args:
        args (tuple): (self(主站對象), response(從站返回的數(shù)據(jù)))
    '''
    response = args[1]
    print("{0} bytes received".format(len(response)))

hooks.install_hook("modbus_tcp.TcpMaster.after_recv", on_after_recv)
  • 設置hook函數(shù)分三步
    • 定義函數(shù)
      • 參數(shù)args是一個元組,是主站/從站在執(zhí)行完某個操作,如發(fā)送數(shù)據(jù),后使用hook函數(shù)時傳入的參數(shù),元祖中包含的參數(shù)不固定,可以自己查看源碼
    • 載入函數(shù): hooks.install_hook('觸發(fā)hook函數(shù)的操作名',函數(shù)名)
    • 愉快的使用!
  • modbus_tk.hooks中定義了哪些操作可以觸發(fā)hook,具體請自行查看源碼!

有問題隨時留言!文章來源地址http://www.zghlxwxcb.cn/news/detail-780546.html

到了這里,關(guān)于python 基于modbus_tk庫實現(xiàn)modbusTCP 主站和從站[非常詳細]的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

  • 匯川AM403PLC作為ModbusTCP主站通訊實例

    匯川AM403PLC作為ModbusTCP主站通訊實例

    一、通訊方案實例 ?1.客戶端/服務端 ??客戶端和服務端是計算機網(wǎng)絡中常見的兩種網(wǎng)絡設備類型,在工業(yè)通信中也稱之為主站/從站,它們在網(wǎng)絡通信過程中扮演著不同的角色。簡單來說,客戶端通常在網(wǎng)絡中發(fā)起請求,而服務端則為客戶端提供資源或數(shù)據(jù)。本例中使用主

    2024年02月03日
    瀏覽(28)
  • 西門子S7-1200建立ModbusTCP通訊數(shù)據(jù)交互實例(從站+主站)

    西門子S7-1200建立ModbusTCP通訊數(shù)據(jù)交互實例(從站+主站)

    協(xié)議:Modbus TCP 設備類型:S7-1200 CPU 1215C 組態(tài)軟件:TIA Portal V17 測試工具:Modbus Slave Modbus Poll 插入CPU設備,并分配IP地址 PLC_1:192.168.2.11 記錄PLC網(wǎng)卡硬件標識符,默認為64 新建一個DB塊(DB_ConnPara_1),在DB塊中創(chuàng)建一個\\\"TCON_IP_v4\\\"類型的變量,修改其參數(shù)值如下: 新建一個DB塊

    2024年03月08日
    瀏覽(73)
  • PMAC與Modbus主站進行Modbus Tcp通訊

    PMAC與Modbus主站進行Modbus Tcp通訊

    在項目的PMAC Script LanguageGlobal Includes下創(chuàng)建一個名為00_Modbus_Para.pmh的pmh文件。 具體的參數(shù)查看手冊,樣例使用的是本機的回環(huán)地址。 在C LanguageBackground Programs下添加一個后臺C應用程序,名為capp1。在capp1文件夾下創(chuàng)建一個capp1.c的source文件。 在PMAC Script LanguagePLC Programs文件夾

    2024年02月11日
    瀏覽(23)
  • STM32開發(fā)之Modbus協(xié)議(主站RTU)

    在單片機方面,針對于通訊常用的協(xié)議之一modbus,這里將modbus協(xié)議和硬件之間的關(guān)系完全獨立出來,硬件和協(xié)議之間的聯(lián)系采用的是回調(diào)的方式進行一個關(guān)聯(lián)。 1、此協(xié)議可直接移植,并不需要關(guān)心硬件相關(guān)的。 2、modbus相關(guān)協(xié)議概念自行查找,本文只做代碼的實現(xiàn)。 宏定義(

    2024年02月12日
    瀏覽(33)
  • Modbus/TCP:主站、從站、客戶端和服務端關(guān)系

    主站主動找從站讀寫數(shù)據(jù) 客戶端主動找服務端讀寫數(shù)據(jù) 所以當使用Modbus/TCP時,主站一般作為客戶端,從站一般作為服務端 當使用Modbus/TCP時,modbus poll一般模擬客戶端,modbus slave一般模擬服務端

    2024年02月12日
    瀏覽(24)
  • Modbus RTU(Remote Terminal Unit)與RS-485協(xié)議(rs485)介紹(主站設備(Master)、從站設備(Slave))Modbus TCP、Modbus ASCII

    Modbus RTU(Remote Terminal Unit)與RS-485協(xié)議(rs485)介紹(主站設備(Master)、從站設備(Slave))Modbus TCP、Modbus ASCII

    參考文章:ModBus協(xié)議 參考文章:一篇文章了解 RS485 和 MODBUS 的區(qū)別,它們有什么不同? Modbus RTU和RS-485是工業(yè)通信中常用的兩種協(xié)議。Modbus RTU 是一種數(shù)據(jù)表示協(xié)議,而 RS-485 則是物理傳輸標準。盡管這兩者有時被并列討論,但它們在通信系統(tǒng)中的角色卻大不相同。以下內(nèi)容將

    2024年02月05日
    瀏覽(108)
  • Modbus PLC攻擊分析:從Modbus Poll Slave到M340_intouch modbustcp 讀取 m340

    Modbus PLC攻擊分析:從Modbus Poll Slave到M340_intouch modbustcp 讀取 m340

    先自我介紹一下,小編浙江大學畢業(yè),去過華為、字節(jié)跳動等大廠,目前阿里P7 深知大多數(shù)程序員,想要提升技能,往往是自己摸索成長,但自己不成體系的自學效果低效又漫長,而且極易碰到天花板技術(shù)停滯不前! 因此收集整理了一份《2024年最新網(wǎng)絡安全全套學習資料》

    2024年04月28日
    瀏覽(25)
  • Modbus通信從入門到精通_2_Modbus TCP通信詳解及仿真(搭建ModbusTCP仿真環(huán)境:創(chuàng)建虛擬PLC并進行ModbusTCP通訊;寄存器與PLC中映射關(guān)系;適合理解如何編寫上位機)

    Modbus通信從入門到精通_2_Modbus TCP通信詳解及仿真(搭建ModbusTCP仿真環(huán)境:創(chuàng)建虛擬PLC并進行ModbusTCP通訊;寄存器與PLC中映射關(guān)系;適合理解如何編寫上位機)

    本篇將會以西門子PLC軟件搭建ModbusTCP仿真環(huán)境,并通過仿真環(huán)境,介紹基礎(chǔ)知識及模擬實際應用中寫一個簡單的通信讀取PLC數(shù)據(jù)方法,并簡介了編寫上位機的方法。 由于具有TCP/IP棧協(xié)議,通常在Modbus TCP通訊的上位機開發(fā)中, 上位機是作為客戶端,控制器作為服務器 。Modbu

    2024年02月08日
    瀏覽(918)
  • 用IoTClient模擬ModbusTCP從站,用Modbus Poll軟件進行模擬測試的方法及軟件下載

    用IoTClient模擬ModbusTCP從站,用Modbus Poll軟件進行模擬測試的方法及軟件下載

    IoTClient是一個物聯(lián)網(wǎng)設備通訊協(xié)議實現(xiàn)客戶端,將包括主流PLC通信讀取、ModBus協(xié)議、Bacnet協(xié)議等常用工業(yè)通訊協(xié)議。本組件基于.NET Standard 2.0,可用于.Net的跨平臺開發(fā),如Windows、Linux甚至可運行于樹莓派上。 1、打開IoTClient軟件? ,選擇modbus tcp? ,設置IP 127.0.0.1 端口502? ,

    2024年04月10日
    瀏覽(31)
  • 運動控制器設計——基于FreeModbus在STM32F4平臺實現(xiàn)ModbusTCP和ModbusRTU

    運動控制器設計——基于FreeModbus在STM32F4平臺實現(xiàn)ModbusTCP和ModbusRTU

    本文筆者最近的項目是設計一款運動控制器,MCU使用的是STM32F429,要求是通過Modbus TCP協(xié)議實現(xiàn)與示教器通訊,并通過ModbusRTU實現(xiàn)與觸摸屏通訊。 本文將介紹在STM32F4上實現(xiàn) ModbusTCP和ModbusRTU通訊 的過程。筆者才疏學淺,如有錯誤還請指正。 Modbus協(xié)議是典型的主-從通訊結(jié)構(gòu),鏈

    2024年02月05日
    瀏覽(15)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包