PySide6通过串口modbus-rtu-rs485协议发送程序到模拟量输出模块输出模拟量

本人打算做一个模拟量控制伺服电机的工控设备。
买了一块正负10V输出的模拟量输出模块;
用PySide6编上位机程序,通过MODBUS-RTU协议,RS485通讯,读取文本框输入电压值,点击按钮把电压值发给模块的寄存器,通过模块输出电压;
从而控制伺服电机的转速,正反转。
为了避免广告嫌疑,我拍实物照片供参考,桌面有点杂乱,就看红字的三个件是本次主题。
(蓝色模块是模拟量采集模块,刚好与本次主题模块相反,暂时无关)。

废话不说了,上代码,代码简单,没有界面美化,纯粹为了实现模拟量输出的功能,注释完整,供非科班出身的入门工友参考扩展。
输入7,代表7V电压

实测6.83V,模拟量模块和万用表是存在精度误差的。

import serial  
from PySide6.QtWidgets import QApplication, QWidget, QLineEdit, QPushButton, QVBoxLayout  
import crcmod  #crc校验库
  
class MyWidget(QWidget):  
    def __init__(self):  
        super().__init__()  
        self.setWindowTitle("通过串口发送程序到模拟量输出模块输出模拟量")  
        self.setGeometry(200,200,400, 300)  #窗口大小
        self.initUI()  
        self.hex_address='01 06 00 0A'  #模拟量输出模块的站号01功能码06和寄存器码000A,根据自己的设备调整。
  
    def initUI(self):  
        # 创建输入电压的文本框和发送电压值的按钮  
        self.coltage_text = QLineEdit()  
        self.coltage_btn = QPushButton('发送') 
        # 创建布局  
        vbox = QVBoxLayout()  
        vbox.addWidget(self.coltage_text)  
        vbox.addWidget(self.coltage_btn)  
        # 设置主窗口布局  
        self.setLayout(vbox)  
        # 设置按钮点击事件  
        self.coltage_btn.clicked.connect(self.sendData)    
  
    def address(self):   #定义站号和功能码    
        adress_split=self.hex_address.split()    #分割字符串  
        hex_address = "".join(c[0:4] for c in adress_split)    #转换为4位16进制数
        return hex_address #返回站号功能码
        
    def input_coltage(self):   #输入电压的转换            
        input_coltage=float(self.coltage_text.text())  #获取输入的电压的文本框数据
        input_coltage_change=input_coltage*204.75+2047.5  #0-4095码对应-10V-+10V电压,2047.5是分界点,2047.5/10=204.75每伏刻度,计算电压码。 
        if input_coltage_change>4095:        #保留小数点后3位,设置上下限范围,超过则按极值处理。
            input_coltage_change=4095
            if input_coltage_change<0:
                input_coltage_change=0
        else:
            input_coltage_change=round(input_coltage_change,3)      
        hex_input_coltage = hex(int(input_coltage_change))[2:].zfill(4)  # 电压浮点数转换为4位十六进制
        return hex_input_coltage         #返回电压码
    
    def check_crc(self):    #定义CRC-16校验码得到发送码
        hex_address=self.address()  #引用 hex_address
        hex_input_coltage=self.input_coltage()  #引用 hex_input_coltage
        hex_str_12 = hex_address + hex_input_coltage #2位站号+2位功能码+4位寄存器码+4位电压码,共12位
        data = bytes.fromhex(hex_str_12)  # 将数据转换为bytes
        crc = crcmod.mkCrcFun(0x18005, rev=True, initCrc=0xFFFF, xorOut=0x0000)(data)  # 使用crcmod进行CRC-16计算      
        crc_bytes = crc.to_bytes(2, 'big')  # 将CRC校验码转换为字节字符串    
        crc_str_low = format(crc_bytes[1], '02x')  # 提取低字节并转换为十六进制字符串,前面填充0以满足4位的要求    
        crc_str_high = format(crc_bytes[0], '02x')  # 提取高字节并转换为十六进制字符串,前面填充0以满足4位的要求    
        crc_str = crc_str_low+crc_str_high  # 将高字节和低字节进行交换    
        hex_str = hex_str_12 + crc_str  # 将CRC添加到数据中,共16位
        return hex_str          #返回待发送的16位码
    
    def sendData(self):  # 通过串口发送出去     
        hex_str=self.check_crc()    #引用发送码     
        ser = serial.Serial('COM5', 9600)   #定义串口
        ser.write(bytes.fromhex(hex_str))   #写入发送码
        ser.close() #关闭串口

if __name__ == '__main__':
    app = QApplication([])
    windown = MyWidget()
    windown.show()
    app.exec()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

gfdncs

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

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

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

打赏作者

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

抵扣说明:

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

余额充值