布瑞特单圈绝对值旋转编码器串口数据读取

布瑞特单圈绝对值旋转编码器串口数据读取

数据手册:http://briter.net/col.jsp?id=109 (2.1版本RS485说明书通信协议 单圈.pdf)

绝对式编码器为布瑞特BRT38-ROM16384-RT1,采用RS485通信。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WymwNSfZ-1690888823352)(C:/Users/Fengzhen/AppData/Roaming/Typora/typora-user-images/image-20230801142219392.png)]
该绝对式编码器共有5根线:红、黄、黑、绿、白
在这里插入图片描述

由于需要通过绝对是编码器采集数据,并通过串口上传至上位机。因此,需要使用RS485转USB模块进行转接。

1.2 MODBUS-RTU 帧格式

本编码器支持 MODBUS 的 0x03(读保持寄存器)、0x06(写单个寄存器)。

1.2.1 0x03 读保持寄存器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dwNaHDsv-1690888823354)(C:/Users/Fengzhen/AppData/Roaming/Typora/typora-user-images/image-20230801145531134.png)]

1.2.2 0x06 写单个寄存器

在这里插入图片描述

1.3 寄存器定义

1.3.1 编码器寄存器

在这里插入图片描述
在这里插入图片描述

如上表可知,该编码器共有13个寄存器,每个寄存器对应着一种功能,可通过对这13个寄存器进行设置,实现特定的功能。

由1.2可知,寄存器有两种模式:读和写。支持功能码为0x03为读保持寄存器,支持功能码为0x06为写保持寄存器。

编码器通信设置:

1、 读取编码器虚拟多圈值

Tx:01 03 00 00 00 02 (C4 0B)
Rx:01 03 04 00 01 76 3B (CC 40)

主站发送:

Tx寄存器字节1(ADR)2(读)3(起始寄存器高字节)4(起始寄存器低字节)5(寄存器低字节)6(寄存器低字节)7(CRC高字节)8(CRC低字节)
内容010300000002C40B

寄存器的第3和4个字节构成寄存器的地址即0x0000

从站回送:

Rx寄存器字节1(ADR)2(读)3(字节总数)4、5(寄存器数据1)6、7(寄存器数据2)M-1、M(寄存器数据M)M+1(CRC高字节)M+2(CRC低字节)
内容01030400 0176 3BCC40

注:括号内为 CRC 校验位,编码器值返回数据是 00 01 76 3B (十进制:95803)

2、设置编码器波特率

Tx:01 06 00 05 00 02 (18 0A)
Rx:01 06 00 05 00 02 (18 0A)
注:括号内为 CRC 校验位,设置的波特率为 38400 (0x02)

主站发送:

Tx寄存器字节1(ADR)2(写)3(寄存器高字节)4(寄存器低字节)5(寄存器数高字节)6(寄存器数低字节)7(CRC高字节)8(CRC低字节)
内容010600050002180A

寄存器的第3和4个字节构成寄存器的地址即0x0005,第5和6个字节构成要发送的数据为0x0002。

当从站接收正确,从站回送:

Rx寄存器字节1(ADR)2(读)3(寄存器高字节)4(寄存器低字节)5(寄存器数高字节)6(寄存器数低字节)7(CRC高字节)8(CRC低字节)
内容010600050002180A

寄存器的第3和4个字节构成寄存器的地址即0x0005,第5和6个字节构成要发送的数据为0x0002。

3、设置编码器数据模式

Tx: 01 06 00 06 00 01 (A8 0B)
Rx: 01 06 00 06 00 01 (A8 0B)
注:括号内为 CRC 校验位,设置当前编码器数据模式为自动回传(默认查询)

4、设置编码器自动回传时间(毫秒)

Tx: 01 06 00 07 00 64 (39 E0)
Rx: 01 06 00 07 00 64 (39 E0)
注:括号内为 CRC 校验位,设定自动回传时间为 100 毫秒(HEX:0x0064)
千万注意:一旦设置自动回传时间小于 20 毫秒,编码器将无法再设置其他参数,谨慎使用!!

5、设置编码器零点

Tx:01 06 00 08 00 01 (C9 C8)
Rx:01 06 00 08 00 01 (C9 C8)
注:括号内为 CRC 校验位,设置当前编码器当前点为零点

6、设置编码器数值递增方向

Tx:01 06 00 09 00 01 (98 08)
Rx:01 06 00 09 00 01 (98 08)
注:括号内为 CRC 校验位,设置当前编码器逆时针数值增加(默认顺时针)

7、设置编码器当前位置值

Tx 01 06 00 0B 03 E8 (F8 B6)
Rx: 01 06 00 0B 03 E8 (F8 B6)
注:括号内为 CRC 校验位,设置的位置为 1000 (HEX:0x3E8)

8、编码器转速计算:

编码器旋转速度 = 编码器角速度值 / 单圈精度 / 转速计算时间(单位:转/分钟)
例如:编码器角速度值回传为 1000,单圈精度为 32768,转速采样时间为
100ms(0.1/60min)
编码器旋转速度 = 1000/32768/(0.1/60) = 1000*0.0183 = 18.31 转/分钟

完整代码如下:

**串口设置:**串口号为COM15(根据实际情况设置);波特率:115200;数据位:8;停止位:1;超时时间:None

#模式切换   转换成16进制
modecmd1 = bytes([0x01, 0x06, 0x00, 0x06, 0x00, 0x01, 0xA8, 0x0B])                 #自动回传
modecmd2 = bytes([0x01, 0x06, 0x00, 0x06, 0x00, 0x00, 0x69, 0xCB])                 #查询
modecmd3 = bytes([0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B])                 #读取编码器虚拟多圈值
BUF_SIZE = 10
buf = bytearray([0x01, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
c = c1 = c2 = ib = flag = 0

def CRC16(data, length): # CRC校验函数代码:使用参考手册提供的代码。
    CRC = 0xFFFF
    for i in range(length):
        CRC ^= data[i]
        for _ in range(8):
            if CRC & 0x0001:
                CRC = (CRC >> 1) ^ 0xA001
            else:
                CRC >>= 1
    return CRC

if __name__ == '__main__':
    ser = serial.Serial(port="COM15",
                        baudrate=115200,
                        bytesize=8,
                        parity=serial.PARITY_NONE,
                        stopbits=1,
                        timeout=None)

    if ser.isOpen():
        print("Open Successfully ", end='')
        print(ser.name)
    else:
        print("Open Fail")

    # write_len = ser.write(modecmd1) #  写指令:切换模式,设置参数

    while True:
        R = ser.read(1) # 读取一个字节
        if R == b'': # 接收字符串为空
            print("Read Fail")
            ser.close()
            break
        c = int.from_bytes(R, byteorder='big') # 将十六进制转换为整数

        if flag > 0:
            if ib < BUF_SIZE - 1:
                buf[ib] = c
                ib += 1
            else:
                CRC = CRC16(buf, BUF_SIZE - 3) # 校验位,数据手册有提供
                if (CRC & 0xFF) == buf[7] and ((CRC >> 8) & 0xFF) == buf[8]:
                    A = (buf[5] << 8) + buf[6] # 将buf[5]左移8位后与buf[6]相加,结果赋值给A。
                    print(A)
                else:
                    print("CRC Fail")
                flag = 0
        if flag == 0:
            if c2 == 0x01 and c1 == 0x03 and c == 0x04: # 判断帧头,且帧头要连续,即为0x01、0x03、0x04
                flag = 1
                ib = 3
        c2 = c1
        c1 = c

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值