项目初期BUG记录-20220622

博客内容涉及了一个项目在Modbus和CANOpen通讯中遇到的问题,包括地址转换错误、子地址筛选不当、多段参数显示和转换问题等。作者详细分析了每个问题的原因,并提供了相应的解决方案,如使用binascii和struct包进行数值转换,修正查询通讯字典的方法,以及调整多段参数表的操作处理。所有问题已在2022-6-23完成修复。
摘要由CSDN通过智能技术生成

项目进度:

完成基本参数和运行模式页面的代码,可获取基本参数字典,还没有获取运行模式字典模块。


目录

项目进度:

问题1

问题描述

原因分析

解决方案

问题2

问题描述

原因分析

解决方案

问题3

问题描述

原因分析

解决方案

问题4

问题描述

原因分析

解决方案

问题5

问题描述

原因分析

解决方案

问题6

问题描述

原因分析

解决方案

问题7

问题描述

原因分析

解决方案

问题8

问题描述

原因分析

解决方案


问题1

问题描述

十进制数-10000,转十六进制是0xFFFFD8F0,再转十进制时,数据变成4294957296,再转十六进制没问题,还是0xFFFFD8F0。

原因分析

十进制与十六进制转换函数中,未明确负数转换机制。

python 是将输入的数分割成符号和数值两部分,那就是如电脑计算器算出来的一样:

 不会判断符号位,就导致直接转换十六进制数的现象。

解决方案

使用 binascii 和 struct 包进行转换, 参考:http://t.csdn.cn/zvRHN

主要参考的是这块指导,但链接原文说的不太对:

2.十六进制还原为负数

先提取为十六进制的字符串,并逆置

neghex_s = hex(neghex)[2:-1] = 'ffff0520'

neghex_s=neghex_s[::-1] = '0250ffff'

使用binascii.unhexlify进行去十六进制化

neghex_pack=binascii.unhexlify(neghex_s)='\x02P\xff\xff'

再利用struct.unpack进行解析

neg=struct.unpack('i', neghex_pack)=(-45054,)

那么neg[0]就是neghex还原的负数

 应该是把字符串 'ffff0520' 改为 '2005ffff',再按程序进行去十六进制化和解析,得到的才是我想要的负数。

更正后代码如下:

def value_translate(value, num):
    if value[0:2] == '0x':  # value是十六进制
        if num == 'dec':  # 十进制显示
            value = value[2:]
            if len(value) < 5:    # 如果数据是0x1,则在前面补0,成为0x00000001
                while len(value) < 8:
                    value = '0' + value
            else:
                pass
            value = value[6:8] + value[4:6] + value[2:4] + value[0:2]
            value_pack = binascii.unhexlify(value)
            trans_value = struct.unpack('i', value_pack)
            value = trans_value[0]
            print('当前为十六进制,换算后重新显示', value)
    ......

问题2

问题描述

源地址表中有区分子地址的参数,查找通讯字典对应的地址不正确。举例:

参数:目标位置1,CAN地址:0x3547,子地址:0x01

参数:目标位置2,CAN地址:0x3547,子地址:0x02

查询Modbus通讯地址应为:目标位置1:0x69,目标位置2:0x6B

实际为:目标位置1:0xF0D6,目标位置2:0xF0D8

原因分析

查询通讯字典表时未加入对子地址的数据筛选。

实际是筛选子地址前,会先定位地址,然后应该是以定位地址得到的数据中再次筛选子地址,而当前是以原地址表所有数据筛选子地址了。

解决方案

# 查询Index对应的其他信息
def search(self, index, subindex):
    search_dic = {}
    i = self.mdic.loc[self.mdic['Od_Index'].isin([index])]
    print('ModbusDict')
    print(i)
    # 判断找地址表,找到则返回字典,没找到则返回0
    if i.size > 0:
        if len(i) > 1:  # 有子地址区分
            print('len(i) > 1')
            # 错误语句:i = self.mdic.loc[self.mdic['Od_Subindex_hex'].isin([subindex])]
            # 更正:
            i = i.loc[self.mdic['Od_Subindex_hex'].isin([subindex])]
            print(i)
        else:
            pass

问题3

问题描述

Modbus通讯地址不需转换长度,CANOpen地址和子地址不需转换十进制。

原因分析

进制转换中没对通讯做区分。

解决方案

修改后代码:

if self.B_type.currentIndex() == 0:     # Modbus通讯,地址由十进制变十六进制
    trans_index = modbus_index(index, num)
    print('地址显示:', trans_index)
    self.para_index.setItem(1, column - 3, QtWidgets.QTableWidgetItem(trans_index))
else:       # Modbus通讯地址不需转换长度,CANOpen地址和子地址不需转换十进制
    pass

问题4

问题描述

多段参数表中的运行模式下拉框没有显示对应行列的索引地址。

原因分析

该部分还未完成。

解决方案

2022-6-23 已完成


问题5

问题描述

多段参数表中如有空白的参数,点击时程序退出,无法显示对应的地址。

原因分析

我获取当前点击的单元格用的是QTableWidget.currentItem(),而QTableWidget只有输入数值,才会产生item,因此空白单元格的currentItem()返回是None,而我显示是直接用的currentItem().text(),就会报错None没有text属性。

解决方案

更改为QTableWidget.currentIndex(),无论是否有输入数值,都可以用currentIndex().data()获取空白的内容或输入的数值。


问题6

问题描述

连续点击多段参数表中的参数,显示的地址表中最后一列的标题不对。

原因分析

从列0往列1,列2...删除,要注意每删除一次,原列表的非0索引值会自动递减 1,因此每次都少一删除一列。

# 复原地址表
if self.para_index.columnCount() > 3:
    for j in range(0, self.para_index.columnCount() - 2):   # 只保留3列
    self.para_index.removeColumn(j)
else:
    pass

解决方案

更改为从后面往前面删除:

# 复原地址表
if self.para_index.columnCount() > 3:
    for j in range(self.para_index.columnCount() - 4, -1, -1):   # 只保留3列
    self.para_index.removeColumn(j)
else:
    pass

问题7

问题描述

多段参数表的运行参数1和2的当前取值,需要转换速度单位。

原因分析

该部分还未完成。

解决方案

2022-6-23已完成


问题8

问题描述

由多段参数表查询地址后,切换回其他模式,地址表的列数显示不对。

原因分析

和问题6相同

解决方案

参考问题6


全部解决时间:2022-6-23

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值