一、项目结构与SDK集成
1. 引入厂商SDK
- 将厂商提供的DLL文件(如`GTS.dll`、`EziMOTIONPlus.dll`、`AdvantechMotion.dll`、`INOVANCE.dll`)复制到项目`bin/Debug`目录。
- 在WPF项目中添加对DLL的引用(右键项目 添加 参考 浏览选择DLL文件)。
2. 声明厂商API函数
使用`DllImport`动态加载不同厂商的DLL,示例代码如下:
csharp
// 固高控制卡(GTS.dll)
DllImport("GTS.dll")
private static extern short GT_Open(int cardnum, int option);
// 雷赛控制卡(EziMOTIONPlus.dll)
DllImport("EziMOTIONPlus.dll")
private static extern short dmc_board_init();
// 研华控制卡(AdvantechMotion.dll)
DllImport("AdvantechMotion.dll")
private static extern bool AdvantechMoveTo(int axis, double position);
// 汇川控制卡(INOVANCE.dll)
DllImport("INOVANCE.dll")
private static extern bool INOVMotorControl(int axis, int command, double param);
---
二、WPF界面设计
xml
<Window x:Class="MultiVendorMotionControl.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<ComboBox x:Name="VendorComboBox" SelectedValuePath="Content" SelectedValue="{Binding SelectedVendor}">
<ComboBoxItem Content="固高"/>
<ComboBoxItem Content="雷赛"/>
<ComboBoxItem Content="研华"/>
<ComboBoxItem Content="汇川"/>
</ComboBox>
<StackPanel Margin="10">
<Button Content="初始化控制卡" Click="InitializeCard_Click"/>
<Button Content="点位运动" Click="PointToPoint_Click" Margin="0,10,0,0"/>
<Button Content="直线插补" Click="LinearInterpolation_Click" Margin="0,10,0,0"/>
<Button Content="急停" Click="EmergencyStop_Click" Margin="0,10,0,0"/>
</StackPanel>
<TextBlock x:Name="StatusText" Margin="10" FontSize="14" FontWeight="Bold"/>
</StackPanel>
</Grid>
---
三、核心控制逻辑
1. 固高控制卡(GoogoltechCard)
csharp
public class GoogoltechCard : IMotionCard
{
DllImport("GTS.dll")
private static extern short GT_Open(int cardnum, int option);
DllImport("GTS.dll")
private static extern void GT_Reset(int cardnum);
DllImport("GTS.dll")
private static extern void GT_Zeropos(int cardnum, int axis, int position);
public void Initialize()
{
short card = GT_Open(0, 1);
if (card != 0)
{
GT_Reset(card);
GT_Zeropos(card, 1, 0); // 初始化X轴原点
StatusText.Text = "固高控制卡初始化成功";
}
else
{
StatusText.Text = $"初始化失败,错误码:{card}";
}
}
public void MoveTo(int axis, double position)
{
short card = GT_Open(0, 1);
if (card != 0)
{
GT_MoveTo(card, axis, position);
GT_Close(card);
}
}
public void EmergencyStop()
{
short card = GT_Open(0, 1);
if (card != 0)
{
GT_Stop(card);
GT_Close(card);
}
}
}
2. 雷赛控制卡(LeadshineCard)
csharp
public class LeadshineCard : IMotionCard
{
DllImport("EziMOTIONPlus.dll")
private static extern short dmc_board_init();
DllImport("EziMOTIONPlus.dll")
private static extern void dmc_line_multicoor(short cardnum, ushort axes, int distances, int mode);
public void Initialize()
{
short card = dmc_board_init();
if (card >= 0)
{
StatusText.Text = "雷赛控制卡初始化成功";
}
else
{
StatusText.Text = $"初始化失败,错误码:{card}";
}
}
public void MoveTo(int axis, double position)
{
short card = dmc_board_init();
if (card >= 0)
{
dmc_pmove(card, (short)axis, (int)(position * 1000)); // 转换为微步
dmc_board_close(card);
}
}
public void LinearInterpolation(int axes, double positions)
{
short card = dmc_board_init();
if (card >= 0)
{
ushort axisMask = 0;
foreach (int axis in axes)
{
axisMask |= (ushort)(1 << (axis - 1));
}
dmc_line_multicoor(card, axisMask, axes.Select(a => (int)(positionsa - 1 * 1000)).ToArray(), 0);
dmc_board_close(card);
}
}
public void EmergencyStop()
{
short card = dmc_board_init();
if (card >= 0)
{
dmc_emg_stop(card);
dmc_board_close(card);
}
}
}
3. 研华控制卡(AdvantechCard)
csharp
public class AdvantechCard : IMotionCard
{
DllImport("AdvantechMotion.dll")
private static extern bool AdvantechMoveTo(int axis, double position);
DllImport("AdvantechMotion.dll")
private static extern bool AdvantechSetDoBit(int doType, int index, bool value);
public void Initialize()
{
// 研华初始化通常无需特殊操作
StatusText.Text = "研华控制卡已连接";
}
public void MoveTo(int axis, double position)
{
bool success = AdvantechMoveTo(axis, position);
if (!success)
{
throw new Exception("研华移动失败");
}
}
public void EmergencyStop()
{
AdvantechSetDoBit(12, 1, false); // 假设12号DO输出急停信号
}
}
4. 汇川控制卡(InovanceCard)
csharp
public class InovanceCard : IMotionCard
{
DllImport("INOVANCE.dll")
private static extern bool INOVMotorControl(int axis, int command, double param);
public void Initialize()
{
// 汇川初始化命令(具体参数需参考SDK网页)
INOVMotorControl(0, 1001, 0); // 假设1001为初始化命令
StatusText.Text = "汇川控制卡已连接";
}
public void MoveTo(int axis, double position)
{
INOVMotorControl(axis, 1002, position); // 假设1002为点位运动命令
}
public void LinearInterpolation(int axes, double positions)
{
// 汇川插补需通过多轴同步实现(示例代码)
INOVMotorControl(0, 1003, 0); // 假设1003为插补启动命令
}
public void EmergencyStop()
{
INOVMotorControl(0, 1004, 0); // 假设1004为急停命令
}
}
---
四、动态库接口使用说明
厂商 API功能 调用示例 参数说明
固高 初始化控制卡 `GT_Open(0, 1)` `cardnum=0`表示第一张卡,`option=1`为初始化模式
雷赛 点位运动 `dmc_pmove(card, axis, distance)` `distance`单位为微步(需根据实际分辨率转换)
研华 设置速度 `AdvantechSetSpeed(axis, speed)` `speed`单位为脉冲/秒
汇川 直线插补 `INOVMotorControl(axis, 1003, params)` `params`包含目标坐标和速度
---
五、关键注意事项
1. 错误处理
csharp
try
{
_currentCard.Initialize();
}
catch (Exception ex)
{
StatusText.Text = $"初始化失败: {ex.Message}";
}
2. 线程安全
使用`BackgroundWorker`执行耗时操作:
csharp
private void PointToPoint_Click(object sender, RoutedEventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
{
_currentCard.MoveTo(1, 1000);
};
{
};
worker.RunWorkerAsync();
}
3. 硬件调试
- 固高:通过`ZDevelop`软件验证轴是否响应。
- 雷赛:使用`MotionStudio`检查插补轨迹。
- 研华:通过`ADVANCE_MOTION_EXAMPLE`测试例程验证功能。
- 汇川:使用`Inovance Studio`配置电机参数。
---
六、扩展功能建议
1. 多轴联动
csharp
private void LinearInterpolation_Click(object sender, RoutedEventArgs e)
{
int axes = { 1, 2 }; // 选择轴1和轴2
double targets = { 2000, 3000 };
_currentCard.LinearInterpolate(axes, targets, 1000);
}
2. 状态监控
使用`DispatcherTimer`定期查询轴位置:
csharp
private DispatcherTimer _timer;
private void StartMonitoring()
{
_timer = new DispatcherTimer(TimeSpan.FromMilliseconds(100), null,
(s, e) =>
{
double position = GetAxisPosition(1); // 获取轴1当前位置
});
_timer.Start();
}
---
七、完整代码示例
---
通过以上方案,可快速构建支持四大主流厂商的运动控制卡上位机程序,具体实现需根据厂商提供的详细SDK网页调整API调用参数和功能逻辑。
领取专属 10元无门槛券
私享最新 技术干货