试试用pyqt做一个上位机软件,但愿不会烂尾(十一):从PLC的变量表自动建立变量

1、首先,创建一个PLC的变量表。

2、将其导出到python工程所在的文件夹:

导出以后的excel文件如下:

 将“comment”一列用excel公式或者简单一些用下拉的方式,生成按照类型和地址命名的一列,这一列就是将来要自动生成的变量名。

 3、打开python,建立一个简单的测试程序

首次要安装一下pandas或者其他的excel编辑库。方法自行百度。

import pandas

varis = []
plc_tags = pandas.read_excel('PLCTags.xlsx', sheet_name='PLC Tags')  # 读取PLC的变量表
plc_tags.rows = plc_tags.shape[0]  # 变量表的总行数


if __name__ == '__main__':
    for row in range(plc_tags.rows):
        new_vari = plc_tags.iloc[row, 4]   # 变量名称所在的列
        new_type = plc_tags.iloc[row, 2].lower()   # 变量类型所在的列,需要将其转换为小写
        exec(new_vari + " = " + new_type)           # 按照excel变量表里的变量名称和类型自动生成变量
                                                                           # 由于PLC与python在变量命名上并不通用,需要进行一些大小写和类型名称
                                                                        # 改变。例如Bool-bool, real-float。
        exec('varis.append(' + new_vari + ')')     # 其实最终的目的是要在这里搞一个字典,使用时直接用中文变量功能来映射变量名称,目前的水平还达不到     
    print(varis)

运行结果:

[<class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>, <class 'bool'>]
<class 'bool'>

Process finished with exit code 0
 

可见,程序按照要求自动生成了变量。

建立一个简单画面验证一下变量的存在:新建test3.ui:放置一个按钮btn和一个指示灯lamp,注意lamp要提升为前面文章自定义的多态部件。保存,退出。

       

创建主程序:

import pandas
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication
import  sys


plc_tags = pandas.read_excel('PLCTags.xlsx', sheet_name='PLC Tags')  # 读取PLC的变量表
plc_tags.rows = plc_tags.shape[0]  # 变量表的总行数


def btn_clicked():     # 按钮单击以后的响应事件
    global DBM_0_0     # M联锁状态  这里的变量名称和作用直接从打开的excel变量表里拷贝粘贴如下图所示:  
    if DBM_0_0:        # M联锁状态    
        DBM_0_0 = False
    else:
        DBM_0_0 = True
    form.lamp.on_off_color(DBM_0_0, 'red')   # 改变指示灯的颜色


if __name__ == '__main__':
    app = QApplication(sys.argv)
    
    for row in range(plc_tags.rows):       # 按照变量表生成变量
        new_vari = plc_tags.iloc[row, 4]   # 变量名称所在的列
        new_type = plc_tags.iloc[row, 2].lower()   # 变量类型所在的列,需要将其转换为小写
        exec(new_vari + " = " + new_type)           # 按照excel变量表里的变量名称和类型自动生成变量
                                                    # 由于PLC与python在变量类型的命名上并不通用,需要进行一些大小写和类型名称改变。例如Bool改成bool, real改成float。

    form = uic.loadUi('test3.ui')  # 导入ui
    form.btn.clicked.connect(btn_clicked)   # 按钮的动作连接
    form.show()     # 显示窗口
    sys.exit(app.exec_())

  运行结果:

         这里,简单实现了变量的无输入自动生成和调用,方法有些原始,毕竟自己的python知识太少,很多高级应用还无暇学习。但也算顺手,尤其是需要定义几百上千个变量的时候,在PLC程序里打字输入一次即可,python里面不用一个一个去编名称和打字输入了,使用的时候从excel文件里直接复制粘贴,变量的命名按照种类和地址的规律,具有唯一性。为了防止存在大量的变量使用时,功能和记忆上的混乱,在使用时,将变量名称拷贝的同时将其功能也拷贝备注在语句后面。

如:global DBM_0_0 # M联锁状态

        if DBM_0_0: # M联锁状态

                DBM_0_0 = False

4、将位从字节中取出

        首先明确的是,通信的基本单位是字节,即使是bool变量也不按bit进行通信,那样效率会很低,所以就需要一个函数将byte的各个bit转换成bool,也许有现成函数可用,懒得查了,自己编一个,能用就好。将来与PLC通信的内容预计为b'\xff\x00\xab'这种字节的形式,还没有验证,先假设就是它吧,将来如果不对再改。

BitOfByte.py:

"""
将输入的byte按照位转换为bool
"""


def bit(in_byte, n):
    if in_byte & (2 ** n) == 0:
        return False
    else:
        return True


if __name__ == '__main__':
    for i in range(7, -1, -1):
        print(bit(b'\x88\xff'[0], i), end=' ')

    print('')

    for i in range(7, -1, -1):
        print(bit(b'\x88\xf8'[1], i), end=' ')

###   运行结果:

True False False False True False False False 
True True True True True False False False 
进程已结束,退出代码0

实现了将字节的各个位转换为bool的需求。

睡觉,休息,有点累

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
可以使用PyModbus库和PyQt5库来实现Modbus通讯上位机。以下是一个简单的示例代码,可以作为参考: ```python from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QLineEdit, QTextEdit from PyQt5.QtCore import Qt from pymodbus.client.sync import ModbusTcpClient class MainWindow(QMainWindow): def __init__(self): super().__init__() # 创建GUI控件 self.label_ip = QLabel('IP地址:', self) self.label_ip.move(10, 10) self.edit_ip = QLineEdit('127.0.0.1', self) self.edit_ip.move(70, 10) self.label_port = QLabel('端口号:', self) self.label_port.move(10, 40) self.edit_port = QLineEdit('502', self) self.edit_port.move(70, 40) self.label_slave = QLabel('从站地址:', self) self.label_slave.move(10, 70) self.edit_slave = QLineEdit('1', self) self.edit_slave.move(70, 70) self.label_address = QLabel('起始地址:', self) self.label_address.move(10, 100) self.edit_address = QLineEdit('0', self) self.edit_address.move(70, 100) self.label_count = QLabel('数量:', self) self.label_count.move(10, 130) self.edit_count = QLineEdit('10', self) self.edit_count.move(70, 130) self.button_read = QPushButton('读取', self) self.button_read.move(10, 160) self.button_read.clicked.connect(self.on_read_clicked) self.text_result = QTextEdit('', self) self.text_result.move(10, 190) self.text_result.setReadOnly(True) def on_read_clicked(self): # 读取Modbus数据 client = ModbusTcpClient(self.edit_ip.text(), port=int(self.edit_port.text())) client.connect() result = client.read_holding_registers(int(self.edit_address.text()), int(self.edit_count.text()), unit=int(self.edit_slave.text())) client.close() # 显示结果 if result.isError(): self.text_result.setText('读取失败: %s' % result) else: values = result.registers self.text_result.setText('读取成功: %s' % values) if __name__ == '__main__': app = QApplication([]) window = MainWindow() window.show() app.exec_() ``` 上述代码中,我们创建了一个MainWindow类,包含了用于配置Modbus通讯参数和读取数据的GUI控件。当用户点击“读取”按钮时,程序会使用PyModbus库连接到指定的Modbus TCP从站,读取指定的寄存器数据,并在文本框中显示结果。 注意,这只是一个简单的示例代码,实际应用中还需要处理各种错误和异常情况,以确保程序的稳定性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深蓝海拓

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值