搜索网卡

接口:IMC_FindNetCard

参数1:网卡信息结构体

参数2:网卡数量

返回值:接口状态码

示例代码

1
2
3
4
5
6
7
8
9
10
11
NIC_INFO info;
int num;
IMC_STATUS Status = IMC_FindNetCard(&info, &num);
if(Status == IMC_OK) {
for(int i = 0; i < num; i++) {
ui->netid->addItem(info.description[i]);
}
}
else {
qDebug() << "Find net card error : " << Status;
}

打开设备

接口:IMC_Open

参数1:IMC设备句柄

参数2:IMC设备编号

返回值:接口状态码

示例代码

1
2
3
4
5
IMC_STATUS st;
st = IMC_Open(&m_Handle, m_netid, m_imcid);
if(Status != IMC_OK) {
qDebug() << "IMC dev open failed!";
}

关闭设备

接口:IMC_Close

参数1:IMC设备句柄

返回值:接口状态码

示例代码

1
IMC_Close(m_Handle);

参数和指令

16位指令设置

1
IMC_API IMC_STATUS WINAPI IMC_SetParam16(IMC_HANDLE Handle, IMC16 paramloc, IMC16 thedata,IMC32 axis,int Sel);

32位指令设置

1
IMC_API IMC_STATUS WINAPI IMC_SetParam32(IMC_HANDLE Handle, IMC16 paramloc, IMC32 thedata,IMC32 axis,int Sel);

48位指令设置

1
IMC_API IMC_STATUS WINAPI IMC_SetParam48(IMC_HANDLE Handle, IMC16 paramloc, __int64 thedata,IMC32 axis,int Sel);

参数1:IMC设备句柄

参数2:参数地址

参数3:参数指令,有16位指令、32位指令、48位指令

参数4:当前控制轴编号

参数5:**fifo模式,指定该指令发往那个 FIFO **

返回值:接口状态码

示例代码

1
2
3
4
5
IMC_STATUS status;
status = IMC_SetParam16(m_Handle, smoothLoc, 0, axis, SEL_IFIFO);
status = IMC_SetParam16(m_Handle, mcsgoLoc, 0, axis, SEL_IFIFO);
status = IMC_SetParam32(m_Handle, mcsvelLoc, 0, axis, SEL_IFIFO);
status = IMC_SetParam32(m_Handle, mcstgvelLoc, 0, axis, SEL_IFIFO);

控制卡配置

控制卡上电时需要针对控制轴进行一些配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void MainWindow::initAxis(int axis)
{
IMC_STATUS status;
if(m_Handle==NULL) return;
status = IMC_SetParam16(m_Handle, clearLoc, -1, axis, FIFO_SEL::SEL_IFIFO);
status = IMC_SetParam32(m_Handle, accellimLoc, 50000, axis, FIFO_SEL::SEL_IFIFO);
status = IMC_SetParam32(m_Handle, vellimLoc, 5000000, axis, FIFO_SEL::SEL_IFIFO);
status = IMC_SetParam32(m_Handle, mcsmaxvelLoc, this->m_velocity, axis, FIFO_SEL::SEL_IFIFO);
status = IMC_SetParam32(m_Handle, mcsaccelLoc, 1000, axis, FIFO_SEL::SEL_IFIFO);
status = IMC_SetParam32(m_Handle, mcsdecelLoc, 1000, axis, FIFO_SEL::SEL_IFIFO);
status = IMC_SetParam16(m_Handle, steptimeLoc, 300, axis, FIFO_SEL::SEL_IFIFO);
status = IMC_SetParam16(m_Handle, enaLoc, -1, axis, FIFO_SEL::SEL_IFIFO);
status = IMC_SetParam16(m_Handle, aioctrLoc, 0x0000, axis, FIFO_SEL::SEL_IFIFO);
status = IMC_SetParam16(m_Handle, homeseqLoc, 0x0014, axis, FIFO_SEL::SEL_IFIFO);
status = IMC_SetParam32(m_Handle, lowvelLoc, 83646, axis, FIFO_SEL::SEL_IFIFO);
status = IMC_SetParam32(m_Handle, highvelLoc, 83646, axis, FIFO_SEL::SEL_IFIFO);
status = IMC_SetParam16(m_Handle, exitfiltLoc, 0, axis, FIFO_SEL::SEL_IFIFO);
status = IMC_SetParam16(m_Handle, stopfiltLoc, -1, axis, FIFO_SEL::SEL_IFIFO);
status = IMC_SetParam16(m_Handle, gout1Loc, -1, axis, FIFO_SEL::SEL_IFIFO);
status = IMC_SetParam16(m_Handle, runLoc, -1, axis, FIFO_SEL::SEL_IFIFO);
g_naxis = PKG_IMC_GetNaxis(m_Handle);
}

clearLoc:写入非零值对该轴实施清零操作。清零该轴的编码器计数、指令位置、目标位置等各种位置参数

accellimLoc:设置该轴的加速度极限值

vellimLoc:设置该轴的速度极限值

mcsmaxvelLoc:点到点运动的最大速度(主坐标系)

mcsaccelLoc:加速度(主坐标系)

mcsdecelLoc:减速度(主坐标系)

steptimeLoc:设定脉冲有效电平宽度,单位是系统的时钟周期

enaLoc:脉冲输出及驱动器使能,写入FFFFh则使能脉冲输出及使能驱动器

aioctrLoc:轴I/O数据寄存器,某I/O设为输入时,读出的是对应管脚的实时信号值,写入0或1可使该管脚输出低或高电平,读则得到写入到该寄存器的值

homeseqLoc:设置搜寻原点过程的运动序列和操作方式

lowvelLoc:搜寻原点时,低速段的速度预设值

highvelLoc:搜寻原点时,高速段的速度预设值

exitfiltLoc:指定发生何种错误时停止该轴运行,exitfilt中置位的位域将致使:若错误寄存器error中对应的位域置位则停止运行(清零run)

stopfiltLoc:指定发生何种错误时停止规划运动,stopfilt中置位的位域将致使:若错误寄存器error中对应的位域置位则停止运动

gout1Loc:全局开关量输出gout1

runLoc:运行该轴,只有运行该轴才能进行运动规划,若该轴因错误退出运行,run清零,该轴处于停止运行状态

设置和搜索原点

设置原点

1.原点的偏移位置值,设置机械原点时,该值被拷贝到指令位置寄存器curpos和编码器寄存器encp中

2.设置搜索速度

3.进行搜索

1
2
3
4
5
6
IMC16 direction, RiseEdge, stop, useI;
direction = ui->direction->currentIndex();
RiseEdge = stop = useI = 0;
IMC_SetParam32(m_Handle, homeposLoc, 0, m_axis, SEL_IFIFO);
SetHomeVel(2000000, 1000000, SEL_IFIFO);
FindHome(direction, RiseEdge, stop, useI, m_axis);

搜索速度

1.设置搜寻原点时,低速段的速度预设值

2.搜寻原点时,高速段的速度预设值

1
2
3
4
5
6
7
bool MainWindow::SetHomeVel(int highvel, int lowvel, FIFO_SEL fifo)
{
IMC_STATUS status = IMC_OK;
status = IMC_SetParam32(m_Handle, highvelLoc, highvel, 0, fifo);
status = IMC_SetParam32(m_Handle, lowvelLoc, lowvel, 0, fifo);
return status == IMC_OK;
}

搜索原点

根据指定方向(正负),边沿,停止标记,索引,轴编号配置搜索过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
IMC_STATUS MainWindow::FindHome(IMC16 direction, IMC16 RiseEdge, IMC16 stop, IMC16 useindex, IMC32 axis)
{
IMC_STATUS status = IMC_OK;
if (!isOpen())
return IMC_DEVICE_NOT_OPEN;
do
{
if(!useindex){
status = IMC_HomeSwitch1(m_Handle, direction, RiseEdge, stop, axis, SEL_IFIFO);
}else{
status = IMC_HomeSwitchIndex1(m_Handle, direction, RiseEdge, stop, axis, SEL_IFIFO);
}
if (status != IMC_OK)
IsError(status);
} while (status != IMC_OK);
return status;
}

点对点运动

以绝对位置运动为例:需要配置IMC设备句柄、运动位置、运动轴、fifo模式,调用使电机移动到绝对位置的函数,运行过程中的指令是发送到QFIFO的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bool MainWindow::MoveAbs(int pos, int axis)
{
IMC_STATUS status;
if (!isOpen())
return false;
do
{
status = IMC_MoveAbsolute(m_Handle, pos, axis, SEL_QFIFO);
if (status != IMC_OK){
IsError(status);
QThread::sleep(1);
}
} while (status != IMC_OK);
return status == IMC_OK;
}

等待运动结束

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bool MainWindow::WaitMoved(int axis)
{
IMC_STATUS status;
if (!isOpen())
return false;
do
{
status = IMC_WaitParam(m_Handle, movingLoc, 0, 0, axis, SEL_QFIFO);
if (status != IMC_OK){
IsError(status);
QThread::sleep(1);
}
} while (status != IMC_OK);
return status == IMC_OK;
}

movingLoc:标志是否规划运动(包括主坐标系和辅坐标系)以及运动平滑处理中,0:停止规划运动且停止平滑处理,FFFFh:规划运动未完成或运动平滑处理进行中

急停和停止

停止点对点:往地址mcsgoLoc写入FFFFh启动点到点运动,写入0,停止当前的点到点运动(主坐标系)

1
2
3
4
5
6
7
bool MainWindow::StopPos2Pos(int axis)
{
IMC_STATUS status;
status = IMC_SetParam16(m_Handle, mcsgoLoc, 0, axis, SEL_IFIFO);
status = IMC_ClearFIFO(m_Handle, SEL_QFIFO);
return status == IMC_OK;
}

点对点急停:暂停该轴的运动

1
2
3
4
5
6
7
8
9
bool MainWindow::PosEmstop(int axis)
{
IMC_STATUS status;
status = IMC_SetParam16(m_Handle, smoothLoc, 0, axis, SEL_IFIFO);
status = IMC_SetParam16(m_Handle, mcsgoLoc, 0, axis, SEL_IFIFO);
status = IMC_SetParam32(m_Handle, mcsvelLoc, 0, axis, SEL_IFIFO);
status = IMC_SetParam32(m_Handle, mcstgvelLoc, 0, axis, SEL_IFIFO);
return status == IMC_OK;
}

smoothLoc:运动平滑因子

mcsgoLoc:写入FFFFh启动点到点运动,写入零,停止当前的点到点运动(主坐标系)

mcsvelLoc:当前规划速度(主坐标系)

mcstgvelLoc:连续速度运动的目标速度(主坐标系)

以上地址配置为0即可急停该轴运动

多线程

IMC系列接口在进行点对点运动时需要开辟一个线程来执行(不然会堵塞主线程),以Qt为例turnToAngles动作需要放到子线程去执行

1
QFuture<void> future = QtConcurrent::run(this, &MainWindow::turnToAngles);

位置反馈

数据原因声明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 参数类型原型
typedef struct _WR_MUL_DES_{
WORD addr; //参数地址
WORD axis; //轴号
WORD len; //参数长度(单位:字(16位宽), 其值为1、2、3; 1:表示一个字(short) 2:表示2个字(long) 3:表示3个字())
WORD data[4];//写或读回的数据
}WR_MUL_DES, *pWR_MUL_DES;

.......

#define m_Naxis 4
WR_MUL_DES m_encpDes[m_Naxis];
WR_MUL_DES m_curposDes[m_Naxis];
WR_MUL_DES m_errorDes[m_Naxis];

配置机械位置、指令位置、错误寄存器地址信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for (int axis = 0; axis < m_Naxis; axis++)
{
m_encp[axis] = 0;
m_curpos[axis] = 0;
m_error[axis] = 0;

m_encpDes[axis].addr = encpLoc;
m_encpDes[axis].axis = axis;
m_encpDes[axis].len = 2;

m_curposDes[axis].addr =curposLoc;
m_curposDes[axis].axis = axis;
m_curposDes[axis].len = 2;

m_errorDes[axis].addr = errorLoc;
m_errorDes[axis].axis = axis;
m_errorDes[axis].len = 1;
}

开辟定时器轮询机械位置、指令位置、错误信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void MainWindow::timerEvent(QTimerEvent *event)
{
if(event->timerId() == m_timeID)
{
if (!isOpen())
return ;

IMC_STATUS st;
int i;
st = IMC_GetMulParam(m_Handle, m_encpDes, (short)m_Naxis);
if (st == IMC_OK)
{
for (i = 0; i < m_Naxis; i++)
{
m_encp[i] = m_encpDes[i].data[0] + (m_encpDes[i].data[1] << 16);
if(i == m_axis) {
ui->machinePos->setText(QString::number(m_encp[i]));
}
}
}

st = IMC_GetMulParam(m_Handle, m_curposDes, (short)m_Naxis);
if (st == IMC_OK)
{
for (i = 0; i < m_Naxis; i++)
{
m_curpos[i] = m_curposDes[i].data[0] + (m_curposDes[i].data[1] << 16);
if(i == m_axis) {
ui->commandPos->setText(QString::number(m_curpos[i]));
}
}
}
}
}

接口:IMC_GetMulParam

参数1:IMC设备句柄

参数2:多轴参数结构体,包括参数地址、轴号、参数长度、写或读回的数据

参数3:总轴数

返回值:接口状态码


『 下里巴人 』
海纳百川,文以载道
hywing技术自留地
总访问 113701 次 | 本页访问 326