目的
使用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();
//}
}
}
}

3551

被折叠的 条评论
为什么被折叠?



