通过Modbus RTU控制汇川SV660P伺服,报文详解及C#代码示例

该文章已生成可运行项目,

目的

使用C#上位机通过Modbus RTU控制SV660P,实现速度环点动(可调速)运行、位置环(可定位)旋转运行。

1.硬件

伺服软件版本:606.2;
FPGA:版本654.6;
电机:MS1H4-40B30CB-A331;
驱动器:SV660PS2R8I;
伺服通讯线:S6-L-T00-2.0;
USB转RS232线缆。

准备好线缆,硬件连接比较简单,不再描述。

2.伺服设置

控制方式:位置控制
编码器:增量位置模式(不需要绝对位置,无需增加电池盒)
位置指令来源:多段位置指令

H02在这里插入图片描述
H05
在这里插入图片描述
H0C
在这里插入图片描述
H11
在这里插入图片描述
H17
在这里插入图片描述
设置完成后,重启伺服驱动器。

3.通讯示例

写H31-00
伺服使能ON , H31-00的bit0设置为1
Send->
01 06 31 00 00 01 46 F6
Recv<-
01 06 31 00 00 01 46 F6

伺服断使能OFF , H31-00的bit0设置为0
Send->
01 06 31 00 00 00 87 36
Recv<-
01 06 31 00 00 00 87 36

定位,H31-00的bit1设置为1
Send->
01 06 31 00 00 03 C7 37
Recv<-
01 06 31 00 00 03 C7 37

写位置100000 数据顺序CDAB
Send->
01 10 11 0C 00 02 04 86 A0 00 01 DB 00
Recv<-
01 10 11 0C 00 02 84 F7

正点动,H31-00的bit2设置为1
Send->
01 06 31 00 00 05 47 35
Recv<-
01 06 31 00 00 05 47 35

写速度300
Send->
01 06 06 04 01 2C C8 CE
Recv<-
01 06 06 04 01 2C C8 CE

通讯报文如下所示。
在这里插入图片描述

4.C#示例

Nuget 安装NModbus
在这里插入图片描述
Modbus功能码
WriteSingleRegisterAsync 功能码06
WriteMultipleRegistersAsync 功能码10

Demo界面
在这里插入图片描述

using Modbus.Device;
using System;
using System.IO.Ports;
using System.Windows.Forms;

namespace SV660PDemo
{
    public partial class Form1 : Form
    {
        private static IModbusMaster master;
        private static SerialPort port;
        private ushort register;
        private ushort[] registerAry;
        //参数(分别为从站地址,起始地址,长度)
        private byte slaveAddress;
        private ushort startAddress;
        private string portName;
        private int baudRate;
        private Parity parity;
        private int dataBits;
        private StopBits stopBits;

        public Form1()
        {
            InitializeComponent();
        }
        private SerialPort InitSerialPortParameter()
        {
            try
            {
                portName = cmb_portname.SelectedItem.ToString();
                baudRate = int.Parse(cmb_baud.SelectedItem.ToString());

                switch (cmb_parity.SelectedItem.ToString())
                {
                    case "Odd":
                        parity = Parity.Odd;
                        break;
                    case "Even":
                        parity = Parity.Even;
                        break;
                    case "None":
                        parity = Parity.None;
                        break;
                    default:
                        break;
                }
                dataBits = int.Parse(cmb_databBits.SelectedItem.ToString());
                switch (cmb_stopBits.SelectedItem.ToString())
                {
                    case "1":
                        stopBits = StopBits.One;
                        break;
                    case "2":
                        stopBits = StopBits.Two;
                        break;
                    default:
                        break;
                }
                port = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
                return port;
            }
            catch (Exception ex)
            {
                MessageBox.Show("打开串口异常"+ex.Message);
                return null;
            } 
        }
        private void button8_Click(object sender, EventArgs e)
        {
            try
            {
                //初始化串口参数
                InitSerialPortParameter();
                master = ModbusSerialMaster.CreateRtu(port);
                if (port.IsOpen == false)
                {
                    port.Open();
                    btn_DisConnect.Enabled = true;
                    btn_Connect.Enabled = false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("初始化异常"+ex.Message);
            }
        }
        private void button9_Click(object sender, EventArgs e)
        {
            if (port.IsOpen == true)
            {
                port.Close();
                btn_DisConnect.Enabled = false;
                btn_Connect.Enabled = true;
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            slaveAddress = byte.Parse(txt_slave1.Text);
            startAddress = 0x3100;
            register = 0x01;
            master.WriteSingleRegisterAsync(slaveAddress, startAddress, register);
        }
        private void button2_Click(object sender, EventArgs e)
        {
            slaveAddress = byte.Parse(txt_slave1.Text);
            startAddress = 0x3100;
            register = 0x00;
            master.WriteSingleRegisterAsync(slaveAddress, startAddress, register);
        }
        private void button3_Click(object sender, EventArgs e)
        {
           
            slaveAddress = byte.Parse(txt_slave1.Text);
            startAddress = 0x3100;
            register = 0x03;
            master.WriteSingleRegisterAsync(slaveAddress, startAddress, register);
        }
        private void button4_Click(object sender, EventArgs e)
        {
            slaveAddress = byte.Parse(txt_slave1.Text);
            startAddress = 0x3100;
            register = 0x05;
            master.WriteSingleRegisterAsync(slaveAddress, startAddress, register);
        }
        private void button5_Click(object sender, EventArgs e)
        {
            slaveAddress = byte.Parse(txt_slave1.Text);
            startAddress = 0x3100;
            register = 0x09;
            master.WriteSingleRegisterAsync(slaveAddress, startAddress, register);
        }
        private void button6_Click(object sender, EventArgs e)
        {
            slaveAddress = byte.Parse(txt_slave1.Text);
            startAddress = 0x0604;
            register = ushort.Parse(txt_vel.Text);
            master.WriteSingleRegisterAsync(slaveAddress, startAddress, register);
        }
        private void button7_Click(object sender, EventArgs e)
        {
            ushort[] registerAry = new ushort[2];
            try
            {
                Modbus.SetInt(registerAry, 0, txt_pos1.Text);
                slaveAddress = byte.Parse(txt_slave1.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show("输入异常" + ex.Message);
            }
            
            startAddress = 0x110C;
            master.WriteMultipleRegistersAsync(slaveAddress, startAddress, registerAry);
        }
        private void InitializeCom()
        {
            //Com Ports
            string[] ArrayComPortsNames = SerialPort.GetPortNames();
            if (ArrayComPortsNames.Length == 0)
            {
                MessageBox.Show("无可用串口" );
                btn_DisConnect.Enabled = false;
                btn_Connect.Enabled = false;

            }
            else
            {
                Array.Sort(ArrayComPortsNames);
                for (int i = 0; i < ArrayComPortsNames.Length; i++)
                {
                    cmb_portname.Items.Add(ArrayComPortsNames[i]);
                }
                cmb_portname.Text = ArrayComPortsNames[0];
                btn_DisConnect.Enabled = false;
                btn_Connect.Enabled = true;
            }
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            InitializeCom();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //if (port.IsOpen == true)
            //{
            //    port.Close();
            //}
        }
    }
}

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值