用Python采用Modbus-Tcp的方式读取PLC模块数据

这篇具有很好参考价值的文章主要介绍了用Python采用Modbus-Tcp的方式读取PLC模块数据。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

使用计算器得到需要的寄存器地址

这里PLC地址是83,对应的程序16进制读取地址是53
实际上由于PLC地址从1开始,所以这里实际地址应该是52,因为计算机从0开始

用Python采用Modbus-Tcp的方式读取PLC模块数据,Python学习私人笔记,物联网,python,tcp/ip,物联网,IOT,Modbus

使用网络调试助手生成报文

用Python采用Modbus-Tcp的方式读取PLC模块数据,Python学习私人笔记,物联网,python,tcp/ip,物联网,IOT,Modbus

使用Python中的内置函数int()。以下是将人员卡号’b’3b44’'转换为十进制的示例代码:

card_number = '3b44'
decimal_number = int(card_number, 16)
print(decimal_number)

使用response[-4:]获取了响应数据的后4个字节作为value96。然后,通过struct.unpack(‘>f’, value96)[0]将4字节的二进制字符串解包为单精度浮点数,并将其打印出来。

#实时电量
request = bytes.fromhex("00 20 00 00 00 06 01 03 00 5F 00 02 ")
client_socket.send(request)
response = client_socket.recv(1024)

value96 = response[-4:]
value96 = struct.unpack('>f', value96)[0]
value96=value96*10.00
value96=round(value96,2)
print("实时电量 单精度浮点数: {:.2f}".format(value96))

value40 是一个包含两个字节的字节串,即 b’\x00\x00’,将其转换为二进制,并保留8位。

以下是将字节串转换为二进制并保留8位的示例代码:

value40 = b'\x00\x00'
binary_value = bin(int.from_bytes(value40, byteorder='big'))[2:].zfill(8)
print("状态:", binary_value)

DEMO代码

#!D:/workplace/python
# -*- coding: utf-8 -*-
# @File  : main0523_04.py
# @Author:Romulushe
# @Time    : 2023/5/23 10:38
# @Software: PyCharm
# @Use: PyCharm
import socket
import struct
import time
import binascii

interval = 5
ip_address = ''#根据实际情况自定义
port_number = 502
polling_interval = float(interval)

def print_binary_value(value, name):
    binary_value = bin(int.from_bytes(value, byteorder='big'))[2:].zfill(8)[::-1]
    print(f"{name}: {binary_value}")

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client_socket:
    try:
        client_socket.settimeout(3)
        client_socket.connect((ip_address, port_number))

        while True:
            try:
                ##电压
                request = bytes.fromhex("00 22 00 00 00 06 01 03 00 53 00 02 ")
                client_socket.send(request)
                response = client_socket.recv(1024)

                value84 = response[-4:]
                value84= struct.unpack('>f', value84)[0]
                # value84 = value84 * 10.00
                value84 = round(value84, 2)
                print("实时电压 单精度浮点数: {:.2f}".format(value84))

                ##电流
                request = bytes.fromhex("00 24 00 00 00 06 01 03 00 4F 00 02  ")
                client_socket.send(request)
                response = client_socket.recv(1024)

                value80 = response[-4:]
                value80 = struct.unpack('>f', value80)[0]
                # value84 = value80 * 10.00
                value80 = round(value80, 2)
                print("实时电流 单精度浮点数: {:.2f}".format(value80))

                ##实时温度1
                request = bytes.fromhex("00 2E 00 00 00 06 01 03 00 57 00 02 ")
                client_socket.send(request)
                response = client_socket.recv(1024)

                value88 = response[-4:]
                value88 = struct.unpack('>f', value88)[0]
                # value88 = value88 * 10.00
                value88 = round(value88, 2)
                print("实时温度1 单精度浮点数: {:.2f}".format(value88))

                #实时温度2
                request = bytes.fromhex("00 2C 00 00 00 06 01 03 00 5B 00 02 ")
                client_socket.send(request)
                response = client_socket.recv(1024)

                value92 = response[-4:]
                value92 = struct.unpack('>f', value92)[0]
                # value92 = value92 * 10.00
                value92 = round(value92, 2)
                print("实时温度2 单精度浮点数: {:.2f}".format(value92))

                ##车速
                request = bytes.fromhex("00 31 00 00 00 06 01 03 00 3B 00 01 ")
                client_socket.send(request)
                response = client_socket.recv(1024)

                speed= binascii.hexlify(response)[-4:]
                speed = int(speed, 16)
                print("车速:", speed)

                # #实时电量
                request = bytes.fromhex("00 20 00 00 00 06 01 03 00 5F 00 02 ")
                client_socket.send(request)
                response = client_socket.recv(1024)

                value96 = response[-4:]
                value96 = struct.unpack('>f', value96)[0]
                value96=value96*10.00
                value96=round(value96,2)
                print("实时电量 单精度浮点数: {:.2f}".format(value96))

                #充放电状态

                #超速报警

                #低电量报警

                #温度过高1

                #温度过高2

                #00 18 00 00 00 06 01 03 00 28 00 01
                request = bytes.fromhex("00 33 00 00 00 06 01 03 00 28 00 01 ")
                client_socket.send(request)
                response = client_socket.recv(1024)

                value40 = response[-2:]
                value40= bin(int.from_bytes(value40, byteorder='big'))[2:].zfill(8)[::-1]
                print("充放电状态:",value40[4])
                print("超速报警:", value40[0])
                print("低电量报警:", value40[2])
                print("温度1过高:", value40[3])
                print("温度2过高:", value40[7])


                #车牌号
                #
                request = bytes.fromhex("00 00 00 00 00 06 01 03 00 1E 00 02 ")  # 车牌号
                client_socket.send(request)
                response = client_socket.recv(1024)

                car_num= binascii.hexlify(response)[-8:-4]
                car_num = int(car_num, 16)
                print("车牌号:", car_num)

                #人员卡号
                request = bytes.fromhex("00 00 00 00 00 06 01 03 00 42 00 02 ")  # 人员卡号
                client_socket.send(request)
                response = client_socket.recv(1024)

                card = binascii.hexlify(response)[-8:-4]
                card = int(card, 16)
                print("人员卡号:", card)

            except socket.timeout:
                print('TIMEOUT ERROR: 服务器未及时响应')
    except Exception as e:
        print('CONNECT ERROR:', e)

DEMO结果

E:\software\python\python.exe E:/projects/Forklift/t2.py

实时电压 单精度浮点数: 48.85

实时电流 单精度浮点数: 0.26

实时温度1 单精度浮点数: 31.10

实时温度2 单精度浮点数: 30.85

车速: 0

实时电量 单精度浮点数: 68.52

充放电状态: 0

超速报警: 0

低电量报警: 0

温度1过高: 0

温度2过高: 0

车牌号: 15172

人员卡号: 10763

其他:地址表

用Python采用Modbus-Tcp的方式读取PLC模块数据,Python学习私人笔记,物联网,python,tcp/ip,物联网,IOT,Modbus文章来源地址https://www.toymoban.com/news/detail-589940.html

附带数据库&log存储的代码:

#!D:/workplace/python
# -*- coding: utf-8 -*-
# @File  : main0523_04.py
# @Author:Romulushe
# @Time    : 2023/5/23 10:38
# @Software: PyCharm
# @Use: PyCharm
import socket
import struct
import time
import binascii
import pymysql
import os,sys,datetime,logging

interval = 5
ip_address = ''#根据实际情况自定义
port_number = ''#根据实际情况自定义
polling_interval = float(interval)


base_path = os.path.dirname(os.path.realpath(sys.argv[0]))


def get_log_path():
    return os.path.join(base_path, 'logs')


def cleanup_logs():
    log_path = get_log_path()
    current_time = time.time()
    for file_name in os.listdir(log_path):
        file_path = os.path.join(log_path, file_name)
        if os.path.isfile(file_path):
            creation_time = os.path.getctime(file_path)
            if current_time - creation_time > (3 * 24 * 60 * 60):
                os.remove(file_path)


def configure_logging():
    log_path = get_log_path()
    os.makedirs(log_path, exist_ok=True)
    log_filename = get_log_filename()
    log_file = os.path.join(log_path, log_filename)
    logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s', filename=log_file)


def get_log_filename():
    now = datetime.datetime.now()
    return now.strftime("%Y-%m-%d_%H-%M.log")


def create_new_log():
    log_path = get_log_path()
    log_files = os.listdir(log_path)
    if len(log_files) >= 20:
        oldest_file = min(log_files)
        os.remove(os.path.join(log_path, oldest_file))
    log_filename = get_log_filename()
    log_filepath = os.path.join(log_path, log_filename)
    return log_filepath


def check_log_size(log_filepath):
    log_size = os.path.getsize(log_filepath)
    if log_size > 2 * 1024 * 1024:
        # 创建新的日志文件
        new_log_filepath = create_new_log()
        try:
            shutil.move(log_filepath, new_log_filepath)
            return new_log_filepath
        except PermissionError:
            insert_log(logger, f'{log_filepath} {PermissionError}', log_filepath)
            time.sleep(0.1)
            return log_filepath
    return log_filepath

def insert_log(logger, log_message, log_filepath):
    log_filepath = check_log_size(log_filepath)

    # 创建文件处理器
    file_handler = RotatingFileHandler(log_filepath, maxBytes=2 * 1024 * 1024, backupCount=1)
    file_handler.setLevel(logging.DEBUG)
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    file_handler.setFormatter(formatter)

    # 添加文件处理器到日志记录器
    logger.addHandler(file_handler)

    try:
        logger.debug(log_message)
    except PermissionError:
        insert_log(logger, f'{log_message} {PermissionError}', log_filepath)
        time.sleep(0.1)  # 延迟0.1秒

    # 移除文件处理器
    logger.removeHandler(file_handler)
# 连接数据库
def connect_database(host, port, user, password, db_name):
    try:
        conn = pymysql.connect(host=host, port=port, user=user, password=password, db=db_name)
        # print("成功连接到数据库")
        return conn
    except pymysql.Error as e:
        insert_log(logger, f'DATABASE CONNECT FAILED', log_filepath)
        # print(f"数据库连接失败: {e}")

# 插入数据
def insert_data(conn, types,table_name, create_time, location_no, parameter_desc, location, param_value):
    try:
        cursor = conn.cursor()
        sql = f"INSERT INTO {table_name} (TYPE, CREATE_TIME, LOCATION_NO, PARAMETER_DESC, LOCATION, PARAMVALUE) " \
              f"VALUES (%s, %s, %s, %s, %s, %s)"
        cursor.execute(sql, (types,create_time, location_no, parameter_desc, location, param_value))
        conn.commit()
        # print(f"数据插入成功: {create_time}, {parameter_desc}: {param_value}")
        cursor.close()
    except pymysql.Error as e:
        insert_log(logger, f'DATABASE INSERT DATA FAILED', log_filepath)
        # print(f"数据插入失败: {e}")


with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client_socket:
    configure_logging()
    cleanup_logs()

    log_filepath = create_new_log()

    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)

    try:
        client_socket.settimeout(3)
        client_socket.connect((ip_address, port_number))

        # 连接数据库
        host = ''#根据实际情况自定义
        port = 3306
        user = ''#根据实际情况自定义
        password = ''#根据实际情况自定义
        db_name = ''#根据实际情况自定义
        table_name =''#根据实际情况自定义
        try:
            # 连接数据库
            conn = connect_database(host, port, user, password, db_name)
        except Exception as e:
            print("COON ERROR:",e)

        while True:

            try:
                types ='叉车'
                location ='F2堆02'



                ##电压
                request = bytes.fromhex("00 22 00 00 00 06 01 03 00 53 00 02 ")
                client_socket.send(request)
                response = client_socket.recv(1024)

                value84 = response[-4:]
                value84= struct.unpack('>f', value84)[0]
                # value84 = value84 * 10.00
                value84 = round(value84, 2)
                print("实时电压 单精度浮点数: {:.2f}".format(value84))

                location_no ='F01-1'
                parameter_desc ='实时电压'
                param_value=value84

                insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)

                ##电流
                request = bytes.fromhex("00 24 00 00 00 06 01 03 00 4F 00 02  ")
                client_socket.send(request)
                response = client_socket.recv(1024)

                value80 = response[-4:]
                value80 = struct.unpack('>f', value80)[0]
                # value84 = value80 * 10.00
                value80 = round(value80, 2)
                print("实时电流 单精度浮点数: {:.2f}".format(value80))
                location_no = 'F01-2'
                parameter_desc = '实时电流'
                param_value=value80

                insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)

                ##实时温度1
                request = bytes.fromhex("00 2E 00 00 00 06 01 03 00 57 00 02 ")
                client_socket.send(request)
                response = client_socket.recv(1024)

                value88 = response[-4:]
                value88 = struct.unpack('>f', value88)[0]
                # value88 = value88 * 10.00
                value88 = round(value88, 2)
                print("实时温度1 单精度浮点数: {:.2f}".format(value88))
                location_no = 'F01-3'
                parameter_desc = '实时温度1'
                param_value = value88

                insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)

               #实时温度2
                request = bytes.fromhex("00 2C 00 00 00 06 01 03 00 5B 00 02 ")
                client_socket.send(request)
                response = client_socket.recv(1024)

                value92 = response[-4:]
                value92 = struct.unpack('>f', value92)[0]
                # value92 = value92 * 10.00
                value92 = round(value92, 2)
                print("实时温度2 单精度浮点数: {:.2f}".format(value92))
                location_no = 'F01-4'
                parameter_desc = '实时温度2'
                param_value = value92

                insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)

                ##车速
                request = bytes.fromhex("00 31 00 00 00 06 01 03 00 3B 00 01 ")
                client_socket.send(request)
                response = client_socket.recv(1024)

                speed= binascii.hexlify(response)[-4:]
                speed = int(speed, 16)
                print("车速:", speed)
                location_no = 'F01-5'
                parameter_desc = '车速'
                param_value = speed

                insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)

                # #实时电量
                request = bytes.fromhex("00 20 00 00 00 06 01 03 00 5F 00 02 ")
                client_socket.send(request)
                response = client_socket.recv(1024)

                value96 = response[-4:]
                value96 = struct.unpack('>f', value96)[0]
                value96=value96*10.00
                value96=round(value96,2)
                print("实时电量 单精度浮点数: {:.2f}".format(value96))
                location_no = 'F01-6'
                parameter_desc = '实时电量'
                param_value = value96

                insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)

                #充放电状态

                #超速报警

                #低电量报警

                #温度过高1

                #温度过高2

                #00 18 00 00 00 06 01 03 00 28 00 01
                request = bytes.fromhex("00 33 00 00 00 06 01 03 00 28 00 01 ")
                client_socket.send(request)
                response = client_socket.recv(1024)

                value40 = response[-2:]
                value40= bin(int.from_bytes(value40, byteorder='big'))[2:].zfill(8)[::-1]
                print("充放电状态:",value40[4])
                print("超速报警:", value40[0])
                print("低电量报警:", value40[2])
                print("温度1过高:", value40[3])
                print("温度2过高:", value40[7])
                location_no = 'F01-7'
                parameter_desc = '充放电状态'
                param_value = value40[4]
                insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)

                location_no = 'F01-8'
                parameter_desc = '超速报警'
                param_value = value40[0]
                insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)

                location_no = 'F01-9'
                parameter_desc = '低电量报警'
                param_value = value40[2]
                insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)

                location_no = 'F01-10'
                parameter_desc = '温度1过高'
                param_value = value40[3]
                insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)

                location_no = 'F01-11'
                parameter_desc = '温度2过高'
                param_value = value40[7]
                insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)

                # 车牌号
                #
                request = bytes.fromhex("00 00 00 00 00 06 01 03 00 1E 00 02 ")  # 车牌号
                client_socket.send(request)
                response = client_socket.recv(1024)

                car_num = binascii.hexlify(response)[-8:-4]
                car_num = int(car_num, 16)
                print("车牌号:", car_num)
                location_no = 'F01-12'
                parameter_desc = '车牌号'
                param_value = car_num
                insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)

                # 人员卡号
                request = bytes.fromhex("00 00 00 00 00 06 01 03 00 42 00 02 ")  # 人员卡号
                client_socket.send(request)
                response = client_socket.recv(1024)

                card = binascii.hexlify(response)[-8:-4]
                card = int(card, 16)
                print("人员卡号:", card)
                location_no = 'F01-13'
                parameter_desc = '人员卡号'
                param_value = card
                insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)

            except socket.timeout:
                print('TIMEOUT ERROR: 服务器未及时响应')
    except Exception as e:
        print('CONNECT ERROR:', e)

到了这里,关于用Python采用Modbus-Tcp的方式读取PLC模块数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • LabVIEW实现Modbus-TCP通信

    Modbus协议是一种已广泛应用于当今工业控制领域的通用通讯协议,按其格式可分为Modbus-RTU、Modbus-ASCII和Modbus-TCP。其中,前两者适用于串行通信控制网络中,例如RS485、RS232等,而Modbus-TCP主要应用于基于以太网TCP/IP通信的控制网络中。通过此协议,控制器相互之间、或控制器经

    2024年02月15日
    浏览(34)
  • CCLINK转MODBUS-TCP网关cclink利modbus区别

    大家好,今天我们要聊的是生产管理系统中的CCLINK和MODBUS-TCP协议,它们的不同使得数据互通比较困难,但远创智控YC-CCLK-TCP网关的出现改变了这一切。 1, 远创智控YC-CCLK-TCP是一款自主研发的CCLINK从站功能的通讯网关,它的主要功能是将各种MODBUS-TCP设备接入到CCLINK总线中。网

    2024年02月15日
    浏览(34)
  • python 与PLC 基于 modbus tcp 协议通讯

    Modbus是一种串行通信协议,是工业领域通信协议的业界标准,是工业电子设备之间常用的连接方式。最近在工作中需要上位机python程序和PLC做通讯,就测试了下使用modbus tcp 通讯。         目前实际测试结果是与西门子PLC/信捷PLC都可以正常通讯使用,但是看到网上说可以传输

    2024年02月17日
    浏览(29)
  • MODBUS-TCP协议简介与编程流程图

      本文主要目的是为了写一个简单的MODBUS-TCP服务器-客户端程序而记录的知识点,里面包含了编程所需要的必要背景知识和协议解析流程图。   MODBUS有四种基本数据类型:    离散量输入 :客户端只能读取它,由服务器提供,占1个比特位,可以传输现实中的开关量输入

    2023年04月08日
    浏览(27)
  • Java与Modbus-TCP/IP网络通讯

    通过Java与Modbus-TCP/IP网络通讯实现举例5中的功能

    2024年02月10日
    浏览(36)
  • TwinCAT3 Modbus-TCP Client/Server使用

    目录 一、环境配置和准备 1、PLC中安装TF6250-Modbus-TCP库 2、勾选TF6250的license 3、PLC工程中添加Tc2_ModbusSrv库文件 4、分别创建测试ModbusTCP测试的Server和Client程序 二、PLC作为Client端 1、设置测试电脑IP地址 2、运行MobusTCP测试工具 3、PLC端程序编写 (1)读取离散量输入 (2)读取线圈

    2024年01月16日
    浏览(33)
  • 通过Python连接 modbus tcp 和台达PLC通信测试记录

    安装台达梯形图软件 “WPLSoft” http://downloadcenter.delta-china.com.cn/DownloadCenter?v=1q=WPLsort_expr=cdatesort_dir=DESC 2.硬件连接 2.1 电脑网卡 连接PLC以太网, IP设为192.168.1.x网段,PLC默认IP为192.168.1.5. 2.2 PLC 供电24V, S/S输入公共端接GND,UP0/ZP0输出驱动电源的端口接GND / 24V 2.3 在 PLC X0输入触

    2024年01月23日
    浏览(42)
  • CCLINK转MODBUS-TCP网关cclink通讯接线图 终端电阻

    大家好,今天我们要聊的是生产管理系统中的CCLINK和MODBUS-TCP协议,它们的不同使得数据互通比较困难,但捷米JM-CCLK-TCP网关的出现改变了这一切。 1捷米JM-CCLK-TCP是一款自主研发的CCLINK从站功能的通讯网关,它的主要功能是将各种MODBUS-TCP设备接入到CCLINK总线中。网关连接到C

    2024年02月13日
    浏览(32)
  • MFC+Modbus-Tcp协议实现温湿度传感器采集 二、libmodbus驱动库

    本文简单介绍 MFC 使用 Modbus -Tcp通信实现 RS-WS-ETH-6 系列 MODBUSTCP 型温湿度传感器采集数据。  一文看懂Modbus协议:一文看懂Modbus协议  libmodbus驱动库的使用:Modbus驱动库—libmodbus驱动库的使用_whik1194的博客-CSDN博客_libmodbus  modbus 中文手册: libmodbus官方手册中文翻译_跃动的风

    2024年02月02日
    浏览(36)
  • Python3通过串口服务器读取设备Modbus数据【modbus_rtu_over_tcp】

    工业采集设备支持ModbusRtu 协议,通讯端口为232串口 或485接口,上位机连接采集终端,不方便走线【串口线 、485总线】,利用现有网络,通过串口服务器进行连接。 实现方案: 1、虚拟串口,上位机通过串口直接采集数据, 缺点:需要安装、开启虚拟串口程序,增加不稳定因

    2024年02月11日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包