zoukankan      html  css  js  c++  java
  • ModbusRTU控制SV660P说明

    帖子目的

    Modbus RTU是工业控制现场经典的控制协议,本贴结合市场一线实际工作经验,总结上位机通过ModbusRTU控制SV660P的注意事项,希望对大家有所帮助

    1.Modbus协议说明

    Modbus通信的底层为RS485信号,采用双绞线进行联接就可以了,因此传输距离较远,可达1000米,抗干扰性能比较好,且成本低,在工业控制设备的通信中被广泛使用,现在众多厂家的变频器、控制器都采用了该协议。
    传送数据格式有HEX码数据和ASCII码两种,分别称为Modbus-RTU和Modbus-ASC 协议。
    前者为数据直接传送,而后者需将数据变换为ASCII码后传送,因此Modbus-RTU协议的通信效率较高,处理简单,使用得更多。
    Modbus为单主多从通信方式,采用的是主问从答方式,每次通信都是由主站首先发起,从站被动应答。因此,如变频器之类的被控设备,一般内置的是从站协议,而PLC之类的控制设备,则需具有主站协议、从站协议。

    2.常用Modbus 功能码及数据编址

    SV660P作为Modbus从站时,支持Modbus协议功能码0x03, 0x06, 0x10;
    Modbus通信主机在访问(读取或改写) 伺服从机的内部变量时,必须遵循如下的通信命令帧定义,以及变量地址索引方法,才能进行正常的通信操作

    功能码 0x03(03):读寄存器

    功能码 0x10(16):写多个寄存器

    3.错误响应帧

     

     

    4.接线&SV660P参数设置

     

     

     注:如线束制作不便,可直接购买 USB-S6-L-T00-3.0 数据线使用

     

     

    5.通讯例子

    5.1 写动作H31-00

    5.1.1 伺服使能,H31-00的bit0设置为1
    Send->
    01 10 31 00 00 01 02 00 01 47 53
    Recv<-
    01 10 31 00 00 01 0F 35

    5.1.2 伺服断使能,H31-00的bit0设置为0
    Send->
    01 10 31 00 00 01 02 00 00 86 93

    5.1.3 正点动,H31-00的bit1设置为1
    Send->
    01 10 31 00 00 01 02 00 03 C6 92

    5.1.4 反点动,H31-00的bit2设置为1
    Send->
    01 10 31 00 00 01 02 00 05 46 90

    5.1.5 绝对定位,H31-00的bit3设置为1
    Send->
    01 10 31 00 00 01 02 00 01 47 53 (先写0)
    Send->
    01 10 31 00 00 01 02 00 09 46 95 (再写1)

    5.1.6 原点回归使能,H31-00的bit4设置为1
    Send->
    01 10 31 00 00 01 02 00 01 47 53(先写0)
    Send->
    01 10 31 00 00 01 02 00 11 46 9F(再写1)

    5.1.7 VDI急停,H31-00的bit5设置为1
    Send->
    01 10 31 00 00 01 02 00 21 46 8B (先写1,触发急停,面板报Er.900)
    Send->
    01 10 31 00 00 01 02 00 01 47 53 (再写0,解除急停)

    5.1.8 报警复位,H31-00的bit6设置为1
    Send->
    01 10 31 00 00 01 02 00 41 46 A3 (先写1,报警复位)
    Send->
    01 10 31 00 00 01 02 00 01 47 53 (再写0)

    5.2 写参数

    注意:参数掉电保持H0C-13=1,且参数设置好后,断电重启,然后必须关闭H0C-13=0,保护EEPROM。

    5.2.1 写目标位置H11-0C=10000(假设写入ABCD数据,格式为CDAB)
    Send->
    01 10 11 0C 00 02 04 27 10 00 00 38 DB
    Recv->
    01 10 11 0C 00 02 84 F7

    5.2.2 写点动速度H06-04=32rpm
    Send->
    01 10 06 04 00 01 02 00 20 C0 0C
    Recv->
    01 10 06 04 00 01 40 80

    5.2.3 功能码急停,断使能,面板不报Er.900,H0D-05=1
    Send->
    01 10 0D 05 00 01 02 00 01 BB 05 (先写1,触发急停)
    Send->
    01 10 0D 05 00 01 02 00 00 7A C5(再写1,解除急停)
    Recv->
    01 10 0D 05 00 01 13 64

    5.2.4 驱动重启H0D-00=1
    Send->
    01 10 31 00 00 01 02 00 00 86 93(伺服断使能,重启后自动恢复为0)
    Send->
    01 10 0D 00 00 01 02 00 01 BB 50(驱动重启)
    Recv->
    01 10 0D 00 00 01 03 65 (正确返回)
    Recv->
    01 90 04 4D C3 (从站设备故障,请先断使能)

    5.3 读参数

    5.3.1 读实际位置H0B-07(假设读取格式为CDAB,实际数据为ABCD)
    Send->
    01 03 0B 07 00 02 77 EE
    Recv->
    01 03 04 09 B2 00 00 59 88(当前位置为0x09B2=2482)

    5.3.2 读故障代码H0B-34
    Send->
    01 03 0B 22 00 01 26 24
    Recv->
    01 03 02 07 40 BB 84 (Er.740编码器故障)
    Recv->
    01 03 02 E9 39 37 C6(Er.939动力线断线)

     5.3.3 读物理DO信号H0B-05
    Send->
    01 03 0B 05 00 01 96 2F
    Recv->
    01 03 02 00 1A 39 8F(上电默认,bit0-伺服准备好,bit2-零速信号)
    Recv->
    01 03 02 00 18 B8 4E(定位完成,bit1-定位完成,保持信号)
    Recv->
    01 03 02 00 08 B9 82(回原完成,bit4-原点回零完成,保持信号)

    5.3.4 以当前位置为零点(位置=0)H05-30=6
    Send->
    01 10 05 1E 00 01 02 00 06 70 EC
    Recv->
    01 10 05 1E 00 01 61 03

    6.CRC16计算方法

    以C++为例,可参考以下代码:[i]

    #include <cstdio>
    #include <iostream>
    using namespace std;
    
    uint16_t CRC16(uint8_t* arr_buff, int len)
    {
            uint16_t crc = 0xFFFF;
            uint16_t i, j, Data;
            for (j = 0; j<len; j++)
            {
                    crc = crc ^*arr_buff++;
                    for (i = 0; i<8; i++)
                    {
                            if ((crc & 0x0001) >0)
                            {
                                    crc = crc >> 1;
                                    crc = crc ^ 0xa001;
                            }
                            else
                                    crc = crc >> 1;
                    }
            }
            return (crc);
    }
    
    void main()
    {
            uint8_t dataIn[9] = { 0x01,0x10,0x31,0x00,0x00,0x01,0x02,0x00,0x01 };
            cout << "dataIn[" << sizeof(dataIn) << "]" << "= { ";
            for (int i = 0; i < sizeof(dataIn); i++)
            {
                    printf("%02x ", dataIn[i]);
            }
            cout << "};" << endl;
            uint16_t Result = CRC16(dataIn, sizeof(dataIn));
            cout << "CRC16 Result : " << hex << Result%0x100 << " " << hex << Result/0x100 << endl;
            system("Pause");
    }

    [i]运行结果如下:

    本文来自博客园,作者:古道轻风,转载请注明原文链接:https://www.cnblogs.com/88223100/p/How_To_Control_SV660P_Use_Modbus.html

  • 相关阅读:
    Codeforces Round #276 (Div. 1) E. Sign on Fence 二分+主席树
    Codeforces Round #229 (Div. 2) C. Inna and Candy Boxes 树状数组s
    HDU 5918 Sequence I KMP
    HDU 5919 Sequence II 主席树
    hdu 5833 Zhu and 772002 高斯消元
    Codeforces Round #143 (Div. 2) E. Cactus 无向图缩环+LCA
    codeforces 45C C. Dancing Lessons STL
    deeplab hole algorithm
    有时候只是担心多余
    lstm
  • 原文地址:https://www.cnblogs.com/88223100/p/How_To_Control_SV660P_Use_Modbus.html
Copyright © 2011-2022 走看看