W10平台;SOEM V1.4.0;
想要实现使用SOEM来驱动汇川sv660n伺服,但根据返回的信息来看,伺服无法从安全运行状态转到运行状态。
这是PDO配置:
int Servosetup(uint16 slave)
{
//int retval=0;
uint8 u8val;
uint16 u16val;
uint32 u32val;
printf("成功调用servosetup函数\n");
u8val = 0;
ec_SDOwrite(slave, 0x1c12, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM);//清除0x1c12数据
u8val = 0;
ec_SDOwrite(slave, 0x1600, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM);//清除0x1600数据
u16val = 0x1600;
ec_SDOwrite(slave, 0x1c12, 0x01, FALSE, sizeof(u16val), &u16val, EC_TIMEOUTRXM);//设定为所选的PDO映像配置
u32val = 0x60400010;
ec_SDOwrite(slave, 0x1600, 0x01, FALSE, sizeof(u32val), &u32val, EC_TIMEOUTRXM);//增加0x1600子索引
u32val = 0x607A0020;
ec_SDOwrite(slave, 0x1600, 0x02, FALSE, sizeof(u32val), &u32val, EC_TIMEOUTRXM);//增加0x1600子索引
u8val = 2;
ec_SDOwrite(slave, 0x1600, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM);//设定为PDO映射中的映射数
u8val = 1;
ec_SDOwrite(slave, 0x1c12, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM);//启用PDO配置
/**********************************************************************************************************/
u8val = 0;
ec_SDOwrite(slave, 0x1c13, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM);//清除0x1c13数据
u8val = 0;
ec_SDOwrite(slave, 0x1A00, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM);//清除0x1A00数据
u16val = 0x1A00;
ec_SDOwrite(slave, 0x1c13, 0x01, FALSE, sizeof(u16val), &u16val, EC_TIMEOUTRXM);//设定为所选的PDO映像配置
u32val = 0x60410010;
ec_SDOwrite(slave, 0x1A00, 0x01, FALSE, sizeof(u32val), &u32val, EC_TIMEOUTRXM);
u32val = 0x60640020;
ec_SDOwrite(slave, 0x1A00, 0x02, FALSE, sizeof(u32val), &u32val, EC_TIMEOUTRXM);
u8val = 2;
ec_SDOwrite(slave, 0x1A00, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM);//设定为PDO映射中的映射数
u8val = 1;
ec_SDOwrite(slave, 0x1c13, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM);//启用PDO配置
while (EcatError) printf("%s", ec_elist2string());
return 1;
}
状态转换:
void simpletest(char* ifname)
{
int i, j, oloop, iloop, wkc_count, cnt, chk, slc;
UINT mmResult;
//uint8 u8val;
//uint16 c;
needlf = FALSE;
inOP = FALSE;
printf("Starting simple test\n");
/* initialise SOEM, bind socket to ifname */
if (ec_init(ifname))
{
printf("ec_init on %s succeeded.\n", ifname);
/* find and auto-config slaves */
if (ec_config_init(FALSE) > 0)
{
printf("%d slaves found and configured.\n", ec_slavecount);
if ((ec_slavecount > 1))
{
for (slc = 1; slc <= ec_slavecount; slc++)
{
printf("try to link Servosetup\n");
//if ((ec_slave[slc].eep_man == 0x0001048576) && (ec_slave[slc].eep_id == 0x0000786701))
//{
printf("Found %s at position %d\n", ec_slave[slc].name, slc);
//u8val = 8;
//ec_SDOwrite(slc, 0x6060, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM);
ec_slave[slc].PO2SOconfig = &Servosetup;
//ec_slave[slc].PO2SOconfig = &AEPsetup;
// link slave specific setup to preop->safeop hook
//}
}
}
printf("eep_man:%i\n",ec_slave[1].eep_man);
printf("eep_id:%i\n",ec_slave[1].eep_id);
//printf("slave:%i\n", ec_ODlistt.slave);
//process_data_config();
printf("config map\n");
ec_config_map(&IOmap);
printf("configdc\n");
ec_configdc();
//int k = sizeof(1);
//ec_SDOread(1, 0x1600, 0x01, FALSE, k, &1, EC_TIMEOUTRXM);
//c = sizeof(1);
//SDO2string(0, 0x1600, 0x01, c);
ec_dcsync0(1, TRUE, 10000000, 3000);
ec_dcsync0(2, TRUE, 10000000, 3000);
printf("Slaves mapped, state to SAFE_OP.\n");
/* wait for all slaves to reach SAFE_OP state */
ec_statecheck(0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE * 4);
printf("Slave 1 State=0x%04x\r\n", ec_slave[1].state);//cln add
printf("Slave 2 State=0x%04x\r\n", ec_slave[2].state);//cln add
do
{
ec_statecheck(1, EC_STATE_SAFE_OP, 50000);
ec_statecheck(2, EC_STATE_SAFE_OP, 50000);
} while ((ec_slave[1].state != EC_STATE_SAFE_OP) || (ec_slave[2].state != EC_STATE_SAFE_OP));
printf("Slave 1 State=0x%04x\r\n", ec_slave[1].state);//cln add
printf("Slave 2 State=0x%04x\r\n", ec_slave[2].state);//cln add
oloop = ec_slave[0].Obytes;
if ((oloop == 0) && (ec_slave[0].Obits > 0)) oloop = 1;
if (oloop > 8) oloop = 8;
iloop = ec_slave[0].Ibytes;
if ((iloop == 0) && (ec_slave[0].Ibits > 0)) iloop = 1;
if (iloop > 8) iloop = 8;
printf("segments : %d : %d %d %d %d\n", ec_group[0].nsegments, ec_group[0].IOsegment[0], ec_group[0].IOsegment[1], ec_group[0].IOsegment[2], ec_group[0].IOsegment[3]);
printf("Request operational state for all slaves\n");
expectedWKC = (ec_group[0].outputsWKC * 2) + ec_group[0].inputsWKC;
printf("%d %d\n", ec_group[0].outputsWKC, ec_group[0].inputsWKC);
printf("Calculated workcounter %d\n", expectedWKC);
ec_slave[1].state = EC_STATE_OPERATIONAL;
ec_slave[2].state = EC_STATE_OPERATIONAL;
/* send one valid process data to make outputs in slaves happy*/
ec_send_processdata();
//printf("send_wkc:%d\n", wkc);
wkc=ec_receive_processdata(EC_TIMEOUTRET);
//printf("receive_wkc:%d\n", wkc);
/* start RT thread as periodic MM timer */
//mmResult = timeSetEvent(1, 0, RTthread, 0, TIME_PERIODIC);
if (wkc == expectedWKC)
{
printf("wkc计数符合预期\n");
}
//printf("configindex:", ec_slave.configindex);
/* request OP state for all slaves */
ec_writestate(0);
mmResult = timeSetEvent(1, 0, RTthread, 0, TIME_PERIODIC);
chk = 40;
/* wait for all slaves to reach OP state */
do
{
ec_statecheck(0, EC_STATE_OPERATIONAL, 50000);
} while (chk-- && (ec_slave[0].state != EC_STATE_OPERATIONAL));
for (cnt = 1; cnt <= ec_slavecount; cnt++)
{
printf("\nSlave:%d\n Name:%s\n Output size: %dbits\n Input size: %dbits\n State: %d\n Delay: %d[ns]\n Has DC: %d\n",
cnt, ec_slave[cnt].name, ec_slave[cnt].Obits, ec_slave[cnt].Ibits,
ec_slave[cnt].state, ec_slave[cnt].pdelay, ec_slave[cnt].hasdc);
printf(" Configured address: %x\n", ec_slave[cnt].configadr);
//printf(" Outputs address: %i\n", ec_slave[cnt].outputs);
//printf(" Inputs address: %i\n", ec_slave[cnt].inputs);
for (j = 0; j < ec_slave[cnt].FMMUunused; j++)
{
printf(" FMMU%1d Ls:%x Ll:%4d Lsb:%d Leb:%d Ps:%x Psb:%d Ty:%x Act:%x\n", j,
(int)ec_slave[cnt].FMMU[j].LogStart, ec_slave[cnt].FMMU[j].LogLength, ec_slave[cnt].FMMU[j].LogStartbit,
ec_slave[cnt].FMMU[j].LogEndbit, ec_slave[cnt].FMMU[j].PhysStart, ec_slave[cnt].FMMU[j].PhysStartBit,
ec_slave[cnt].FMMU[j].FMMUtype, ec_slave[cnt].FMMU[j].FMMUactive);
}
printf(" FMMUfunc 0:%d 1:%d 2:%d 3:%d\n",
ec_slave[cnt].FMMU0func, ec_slave[cnt].FMMU2func, ec_slave[cnt].FMMU2func, ec_slave[cnt].FMMU3func);
}
ec_readstate();
if (ec_slave[0].state == EC_STATE_OPERATIONAL)
{
printf("Operational state reached for all slaves.\n");
wkc_count = 0;
inOP = TRUE;
/* cyclic loop, reads data from RT thread */
for (i = 1; i <= 500; i++)
{
if (wkc >= expectedWKC)
{
printf("Processdata cycle %4d, WKC %d , O:", rtcnt, wkc);
for (j = 0; j < oloop; j++)
{
printf(" %2.2x", *(ec_slave[0].outputs + j));
}
printf(" I:");
for (j = 0; j < iloop; j++)
{
printf(" %2.2x", *(ec_slave[0].inputs + j));
}
printf(" T:%lld\r", ec_DCtime);
needlf = TRUE;
}
osal_usleep(50000);
}
inOP = FALSE;
}
else
{
printf("Not all slaves reached operational state.\n");
ec_readstate();
for (i = 1; i <= ec_slavecount; i++)
{
if (ec_slave[i].state != EC_STATE_OPERATIONAL)
{
printf("Slave %d State=0x%2.2x StatusCode=0x%4.4x : %s\n",
i, ec_slave[i].state, ec_slave[i].ALstatuscode, ec_ALstatuscode2string(ec_slave[i].ALstatuscode));
}
}
}
/* stop RT thread */
timeKillEvent(mmResult);
printf("\nRequest init state for all slaves\n");
ec_slave[0].state = EC_STATE_INIT;
/* request INIT state for all slaves */
ec_writestate(0);
}
else
{
printf("No slaves found!\n");
}
printf("End simple test, close socket\n");
/* stop SOEM, close socket */
ec_close();
}
else
{
printf("No socket connection on %s\nExcecute as root\n", ifname);
}
}
这是PC连接到伺服上,运行程序反馈的信息:
请问是哪里出了问题,我应该从那几个方面改。
不知道你这个问题是否已经解决, 如果还没有解决的话:抱歉,由于问题未给出,我无法给出任何解决方案。请提供具体的问题以获得帮助。