恒洋光电旋转台开发
本文档主要介绍开发光纤水听器旋转台主要内容以及相关参数说明
一、设备组成
1. 控制机箱
本次项目所使用的机箱为单轴GLD-1
参数
2. 旋转台
参数
二、 官方例程
1. 官方调试工具
计算脉冲角度系数
通过系统配置进行辅助计算
点击确定后关闭即可查看角度对应得开环步数,360度 = 720000 实际测试时发现通过api发送运动信号需要将系数再除4,即1度 = 500
2. 二次开发程序
三、程序控制
注意事项
-
测试过程中发现控制程序的查找零位如果电机已经旋转了360度或者在360度左右,直接查找零位会设置当前位置为0点然后继续运行的话会导致其沿着360继续旋转。可以考虑只在程序开始设置零位,程序运行过程中需要回到零位时设置绝对位置为0位进行归零。
-
为了确保电机不会超出范围运行,程序一开始连接的时候就自动设置进行复位并且打开正负限位并使能,其中负限位为0,正限位为360度也就是电机只能在该范围内进行旋转,遇到限位会立即停下
-
获取电机当前状态时并不能直接得出其运动方向为负方向,需要根据当前运动状态以及当前运动方向一起判断,也就是当前运动时其方向为0即可判断其往负方向运动,正方向运动时其方向参数为1
1. 环境配置
需要将MT_API相关文件放在VC程序源目录
引入对应MT_API.h头文件
上面相关的第三方库可以去恒洋光学开发例程中找到。
2. 初始化设置
父类对话框声明RotaryTable对象并在初始化的时候调用其初始化方法
/**
初始化电机参数
*/
BOOL CRotaryTable::RT_Initialize() {
MT_Init();
m_nAxis = 0; // 默认设置0为第一轴
// 设置最大速度
RT_Set_Speed_Max(RT_AngleToPulses(5));
// 设置加速度
RT_Set_Acceleration(RT_AngleToPulses(5));
// 设置减速度
RT_Set_Deceleration(RT_AngleToPulses(5));
return true;
}
上述方法中MT_Init()方法需要在一开始就进行调用,用于初始化MTAPI的环境。本项目中旋转台默认为1个因此设为0。接着设定最大速度、加速度以及减速度。
/**
* 角度转换成脉冲
@Param fAngle 角度
@Return 脉冲数
*/
int CRotaryTable::RT_AngleToPulses(float fAngle) {
int iRef;
iRef = (int)(fAngle * RT_IPULSEANGLE_RATIO);
return iRef;
}
通过使用官方的调试软件可以计算出脉冲与旋转台对应的比例,使用lzp2为例,其旋转比为1:180。通过官方程序最后计算得出
360度 = 720000,然而实际测试过程中发现2000对应旋转台转过的角度为4度而并不是1度,因此设置脉冲角度系数为500,即500个脉冲旋转台旋转1度。
3. 连接旋转台
考虑到项目使用时会有很多端口需要使用,因此采用循环的方式对串口一一进行连接查找存在板卡的串口。
/*
连接设备
@Param 设备名
@Return 返回是否连接成功
*/
BOOL CRotaryTable::RT_Connect(CString &comName) {
//CString strCom;
int count = 0;
HANDLE hCom;
INT32 iResult;
//CString str;
// 防止多次连接
if (m_BIsConnect)
{
return true;
}
MT_Close_UART();
MT_Close_USB();
iResult = MT_Open_USB();
// 打开串口失败
if (iResult != R_OK)
{
return false;
}
iResult = MT_Check();
if (R_OK != iResult)
{
return FALSE;
}
复位并设置正负限位
RT_Reset_To_Zero(RT_AngleToPulses(-8));
//RT_Set_Software_Limit_Disable();
// 设置正负软件限位
RT_Set_Software_Limit_Neg(0);
RT_Set_Software_Limit_Pos(180000);
// 设置限位使能
RT_Set_Software_Limit_Enable();
// 设置最大速度
RT_Set_Speed_Max(RT_AngleToPulses(10));
// 设置加速度
RT_Set_Acceleration(RT_AngleToPulses(10));
// 设置减速度
RT_Set_Deceleration(RT_AngleToPulses(10));
// 使用串口的形式打开
//for (int nCom = 1; nCom < 10; nCom++)
//{
// MT_Close_UART();
// strCom.Format(_T("COM%d"), nCom);
// USES_CONVERSION;
// //strCom = "COM5";
// char *p = W2A(strCom);
//
// iResult = MT_M_Open_UART(0, p);
// // 打开串口失败
// if (iResult != R_OK)
// {
// continue;
// }
// //检测板卡
// iResult = MT_Check();
// if (R_OK != iResult)
// {
// continue;
// }
// //检测板卡成功
// comName = strCom;
//
// /*str.Format(_T("连接成功,设备端口号为:%s"), strCom);
// MessageBox(NULL, str, _T("连接旋转台"), MB_ICONINFORMATION);*/
// // 复位并设置正负限位
// RT_Reset_To_Zero(RT_AngleToPulses(-8));
// RT_Set_Software_Limit_Disable();
// // 设置正负软件限位
// RT_Set_Software_Limit_Neg(0);
// RT_Set_Software_Limit_Pos(180000);
// // 设置限位使能
// RT_Set_Software_Limit_Enable();
// return true;
//}
return true;
}
但是其检测板卡的方法iResult = MT_Check();查询比较缓慢,因此使用其提供的连接usb的方法,需要通过具体的测试才能知道其正常工作中能否正常连接到相应设备,其方法为iResult = MT_Open_USB();
4. 控制电机
1. 相对移动
输入角度时电机相对移动
/**
* 相对移动
@Param fAngle 旋转度数
@Return 返回是否成功
*/
BOOL CRotaryTable::RT_Move_Relative(float fAngle) {
if (m_BIsConnect)
{
return FALSE;
}
CString str;
// 将角度转换成脉冲
int iPulses = RT_AngleToPulses(fAngle);
INT32 iResult;
//TODO 判断角度
//进入位置模式,如果过程中模式不改,只需要设置一次,也可以放在窗口初始化
MT_Set_Axis_Mode_Position(m_nAxis);
iResult = MT_Set_Axis_Position_P_Target_Rel(m_nAxis, iPulses);
if (R_OK == iResult)
{
m_nCurMode = 2;
return TRUE;
}
str.Format(_T("运动失败"));
MessageBox(NULL, str, _T("相对运动"), MB_ICONERROR);
return FALSE;
}
2. 绝对移动
输入角度时电机移动到绝对角度
/*
绝对移动
@Param fAngle 移动角度
@Return 是否执行成功
*/
BOOL CRotaryTable::RT_Move_Absolute(float fAngle) {
CString str;
if(m_BIsConnect)
{
return FALSE;
}
//TODO 判断角度
if (fAngle > 360 || fAngle < 0)
{
return FALSE;
}
//设置绝对方式移动,支持正负值
int iPulses = RT_AngleToPulses(fAngle);
INT32 iResult;
//进入位置模式,如果过程中模式不改,只需要设置一次,也可以放在窗口初始化
MT_Set_Axis_Mode_Position(m_nAxis);
iResult = MT_Set_Axis_Position_P_Target_Abs(m_nAxis, iPulses);
if (R_OK == iResult)
{
m_nCurMode = 2;
return TRUE;
}
return FALSE;
}
3. 设置加速度
设置电机运动过程中的加速度,开始连接电机时该方法内初始化了一个初值
/*
设置加速度
@Param iPulses 脉冲
@Return 是否成功
*/
BOOL CRotaryTable::RT_Set_Acceleration(int iPulses) {
if(m_BIsConnect)
{
return FALSE;
}
//设置加速度
INT32 iResult;
iResult = MT_Set_Axis_Acc(m_nAxis, iPulses);
if (R_OK == iResult)
{
return TRUE;
}
return FALSE;
}
4. 设置减速度
设置电机运动过程中的减速度
/*
设置减速度
@Param 脉冲
*/
BOOL CRotaryTable::RT_Set_Deceleration(int iPulses)
{
if(m_BIsConnect)
{
return FALSE;
}
INT32 iResult;
iResult = MT_Set_Axis_Dec(m_nAxis, iPulses);
if (R_OK == iResult)
{
return TRUE;
}
return FALSE;
}
5. 设置最大速度
设置电机运动过程中的最大运动速度
/*
设置最大速度
@Param iPulses 脉冲
*/
BOOL CRotaryTable::RT_Set_Speed_Max(int iPulses) {
if(m_BIsConnect)
{
return FALSE;
}
INT32 iResult;
iResult = MT_Set_Axis_Position_V_Max(m_nAxis, iPulses);
if (R_OK == iResult)
{
return TRUE;
}
return FALSE;
}
6. 零点复位
将电机复位到零点,注意如果电机当前处于零点范围内,不论其当前是否已经旋转了360度都会直接设置当前位置为0度
/*
复位到零位
@Param iPulses 脉冲 -3200
*/
BOOL CRotaryTable::RT_Reset_To_Zero(int iPulses) {
if (m_BIsConnect)
{
return FALSE;
}
//设置指定速度找零位,支持正负值,慢速会精确一些
INT32 iResult;
MT_Set_Axis_Mode_Home(m_nAxis);
iResult = MT_Set_Axis_Home_V(m_nAxis, iPulses);
if (R_OK == iResult)
{
m_nCurMode = 0;
return TRUE;
}
return FALSE;
}
7. 停止电机运动
第三方api没有提供所有模式停止的功能,需要根据当前运动模式进行判断然后停止对应的运动模式,0零位模式,1速度模式,2位置模式
/*
停止,根据相应的减速度进行减速
*/
BOOL CRotaryTable::RT_Stop() {
if (m_BIsConnect)
{
return FALSE;
}
//设置指定速度找零位,支持正负值,慢速会精确一些
INT32 iResult;
//MT_Get_Axis_Status_Mode(m_nAxis, &nMode);
if (m_nCurMode == 0) //目前旋转台处于零位模式
{
iResult = MT_Set_Axis_Home_Stop(m_nAxis);
}
else if (m_nCurMode == 1) // 目前旋转台处于速度模式
{
iResult = MT_Set_Axis_Velocity_Stop(m_nAxis);
}
else if (m_nCurMode == 2) // 目前旋转台处于位置模式
{
iResult = MT_Set_Axis_Position_Stop(m_nAxis);
}
if (R_OK == iResult)
{
return TRUE;
}
return FALSE;
}
8. 紧急停止
没有减速过程,该方法在实际运用过程中需要慎重使用
/*
急停,紧急情况使用,中间不会有减速过程,如果速度过大会导致设备产生损坏
*/
BOOL CRotaryTable::RT_Stop_Emergency()
{
if (m_BIsConnect)
{
return FALSE;
}
// TODO: Add your control notification handler code here
// 立即停止
INT32 iResult;
iResult = MT_Set_Axis_Halt(m_nAxis);
if (R_OK == iResult)
{
return TRUE;
}
return FALSE;
}
9. 设置软件限位正限位
/*
设置软件正限位
*/
BOOL CRotaryTable::RT_Set_Software_Limit_Pos(int nPulses)
{
if (m_BIsConnect)
{
return FALSE;
}
// TODO: Add your control notification handler code here
// 立即停止
INT32 iResult;
iResult = MT_Set_Axis_Software_Limit_Pos_Value(m_nAxis, nPulses);
if (R_OK == iResult)
{
return TRUE;
}
return FALSE;
}
10.设置软件限位负限位
/*
设置软件负限位
*/
BOOL CRotaryTable::RT_Set_Software_Limit_Neg(int nPulses)
{
if (m_BIsConnect)
{
return FALSE;
}
// TODO: Add your control notification handler code here
// 立即停止
INT32 iResult;
iResult = MT_Set_Axis_Software_Limit_Neg_Value(m_nAxis, nPulses);
if (R_OK == iResult)
{
return TRUE;
}
return FALSE;
}
11. 软件限位使能
软件限位正负限位设置好后使能即可正常使用
/*
启动软件限位
*/
BOOL CRotaryTable::RT_Set_Software_Limit_Enable()
{
if (m_BIsConnect)
{
return FALSE;
}
// TODO: Add your control notification handler code here
// 立即停止
INT32 iResult;
iResult = MT_Set_Axis_Software_Limit_Enable(m_nAxis);
if (R_OK == iResult)
{
return TRUE;
}
return FALSE;
}
12. 禁用软件限位
/*
禁用软件限位
*/
BOOL CRotaryTable::RT_Set_Software_Limit_Disable()
{
if (m_BIsConnect)
{
return FALSE;
}
// TODO: Add your control notification handler code here
// 立即停止
INT32 iResult;
iResult = MT_Set_Axis_Software_Limit_Disable(m_nAxis);
if (R_OK == iResult)
{
return TRUE;
}
return FALSE;
}
13. 获取当前电机运动状态
获取是否运动、运动方向、正限位、负限位、零位、运动模式等
/*
获取当前运动状态
@Param &iRun 返回运动状态 >0 表示正在运动
@Param &iDir 运动方向 >0表示正向
@Param &iNeg 负限位
@Param &iPos 正限位
@Param &iZero 是否在零位 >0 在零位
@Param &iMode 运动模式 0 零位模式 1 速度模式 2 位置模式
*/
BOOL CRotaryTable::RT_Get_Current_State(byte &iRun, byte &iDir, byte &iNeg, byte &iPos, byte &iZero, byte &iMode) {
//定制器中读取状态,可以通过在本定时器中通过判断状态来完成连续组合动作
if (m_BIsConnect)
{
return FALSE;
}
INT32 iResult;
iResult = MT_Get_Axis_Status(m_nAxis, &iRun, &iDir, &iNeg, &iPos, &iZero, &iMode);
if (R_OK == iResult)
{
return TRUE;
}
}
14. 获取当前位置
/*
获取当前位置
@Param nPosition 返回当前位置
*/
BOOL CRotaryTable::RT_Get_Current_Position(int &nPosition) {
if (m_BIsConnect)
{
return FALSE;
}
INT32 iResult;
iResult = MT_Get_Axis_Software_P_Now(m_nAxis, &nPosition);
if (R_OK == iResult)
{
return TRUE;
}
return FALSE;
}
15. 获取当前速度
/*
获取当前速度
@Param nSpeed 返回当前速度
*/
BOOL CRotaryTable::RT_Get_Current_Speed(int &nSpeed) {
if (m_BIsConnect)
{
return FALSE;
}
INT32 iResult;
iResult = MT_Get_Axis_V_Now(m_nAxis, &nSpeed);
if (R_OK == iResult)
{
return TRUE;
}
return FALSE;
}
16. 根据脉冲角度系数将角度转换为脉冲
/**
* 角度转换成脉冲
@Param fAngle 角度
@Return 脉冲数
*/
int CRotaryTable::RT_AngleToPulses(float fAngle) {
int iRef;
iRef = (int)(fAngle * RT_IPULSEANGLE_RATIO);
return iRef;
}
17. 获取当前运动模式
/*
获取当前运动模式
@Param &iMode 运动模式 0 零位模式 1 速度模式 2 位置模式
*/
BOOL CRotaryTable::RT_Get_Current_Mode(int &iMode) {
//定制器中读取状态,可以通过在本定时器中通过判断状态来完成连续组合动作
if (m_BIsConnect)
{
return FALSE;
}
INT32 iResult;
iResult = MT_Get_Axis_Mode(m_nAxis, &iMode);
if (R_OK == iResult)
{
return TRUE;
}
}
= MT_Get_Axis_V_Now(m_nAxis, &nSpeed);
if (R_OK == iResult)
{
return TRUE;
}
return FALSE;
}
#### 16. 根据脉冲角度系数将角度转换为脉冲
/**
- 角度转换成脉冲
@Param fAngle 角度
@Return 脉冲数
*/
int CRotaryTable::RT_AngleToPulses(float fAngle) {
int iRef;
iRef = (int)(fAngle * RT_IPULSEANGLE_RATIO);
return iRef;
}
#### 17. 获取当前运动模式
/*
获取当前运动模式
@Param &iMode 运动模式 0 零位模式 1 速度模式 2 位置模式
*/
BOOL CRotaryTable::RT_Get_Current_Mode(int &iMode) {
//定制器中读取状态,可以通过在本定时器中通过判断状态来完成连续组合动作
if (m_BIsConnect)
{
return FALSE;
}
INT32 iResult;
iResult = MT_Get_Axis_Mode(m_nAxis, &iMode);
if (R_OK == iResult)
{
return TRUE;
}
}