Closed Davidinos closed 2 years ago
You should not try to manipulate the SDO's of 0x1c32. In very rare cases you can, with certain slaves, but normally these are read only parameters. See : https://infosys.beckhoff.com/english.php?content=../content/1033/ethercatsystem/2469122443.html&id= The fact that you enable SYNC0 will change the slave internal configuration and the sync mode in 0x1c32:01 will reflect this.
Hello @ArthurKetels, thank you very much for your prompt reply. I agree with you. As shown in attachment datasheet screenshot, when DC sync mode is chosen, 0x1c32, subindex 1 should change automatically when passing from PreOP to SafeOP. But it doesn't, because when I read with SDO, I always read 0. That's the reason why I tried to force it, unsuccesfully.
From your above datasheet it is clear that the drive expects SYNC0 to be started before SafeOP. The side effect of ec_config_map() is that it starts the transition to SafeOP. So ec_configDC() needs to be started before this. And in turn this means that the master and slave need to be synchronized before SafeOP. You can read in other posts here how to do that.
Hello, @Davidinos Are you found out where the problem came from? I got the same problem with SOEM v1.3.1, and I'm using Panasonic Minas-A6B as well
No matter what I wrote through ecx_SDOwrite() , I got nothing , no feedback from servo driver( no alarm); And I tried writing SDO in state Init and Pre-OP , nothing happened yet; When using ec_SDOread() , I always got 0, just like what happened to you; my test code just as simple as tutorial
if (ec_init(""))
{
if (ec_config_init(TRUE) > 0)
{
if ((ec_slavecount >= 1)) //assuming just 1 slave found here
{
ec_configdc(); //1
PdoMappings(ec_slavecount ); //where I Mapping PDOs using ecx_SDOwrite()
ec_config_map(&_iomap); //2
ec_dcsync0(slc,TRUE,1000000,0); //3;
//No matter what order of function calls(1,2,3), never works with Minas-A6B
}
}
else
{
printf("no slave found!");
}
}
Before this servo, I just drove a Yaskawa Servo , which works besides comes with a startup Sync Error; Which turns out that PDO rx timeout, still to be fixed; But when I disable the Error check, just works fine; Pretty new to SOEM, I know there probably wrong using, please let me know.
And I checked the differences between the lastest release 1.4.0 with 1.3.1, nothing useful in sight yet; https://github.com/OpenEtherCATsociety/SOEM/compare/v1.3.1...v1.4.0
Hello @ArthurKetels and @DIns76 , actually yes, I could find a solution that I write below for checking. I've based my solution on this thread: https://github.com/OpenEtherCATsociety/SOEM/issues/520#issuecomment-852381531
.....
case ECAT_MASTER_PREOP_IN_PROGRESS:
ec_readstate();
// wait for all slaves to reach PRE_OP state
if(ec_slave[0].state == EC_STATE_PRE_OP)
{
PRINTF("All slaves set in EC_STATE_PRE_OP.\n");
// Modifying PDOs need delay
osal_timer_start (&tself, EC_TIMEOUTSTATE * 4);
ecatManager.state = ECAT_MASTER_PREOP;
}
else if(osal_timer_is_expired (&tself))
{
ecatManager.state = ECAT_MASTER_ERROR;
PRINTF("Could not set EC_STATE_PRE_OP.\n");
ecatManager_abort();
}
break;
case ECAT_MASTER_PREOP:
if(osal_timer_is_expired (&tself))
{
// The PDOs configuration must be done before ec_config_map
// Consider to use instead int (*PO2SOconfigx)(ecx_contextt * context, uint16 slave);
for(int i=1; i<=ec_slavecount; i++)
{
if(ecatManager.slaveInitCallback[i]!=0)
ecatManager.slaveInitCallback[i](i);
}
// configure DC options for every DC capable slave found in the list
ec_configdc();
// This flag prevent ec_config_map to switch to SafeOp (state change must be done manually)
ecx_context.manualstatechange = 1;
// configure IOMap and don't start transition to SafeOP yet
int iomap_size = ec_config_map(&IOmap);
PRINTF("SOEM IOMap size: %d\n", iomap_size);
// Enable sync0 output for the first slave and second one
ec_dcsync0(MINASA6, TRUE, 500000, 0);
ec_dcsync0(ARDUINO_BAUSANO, TRUE, 500000, 0);
osal_timer_start (&tself, EC_TIMEOUTSTATE * 4);
ecatManager.state = ECAT_MASTER_SYNC_IN_PROGRESS;
}
break;
case ECAT_MASTER_SYNC_IN_PROGRESS:
// Enable PDOs communication for syncing master and slave and wait
dorun = true;
if(osal_timer_is_expired (&tself))
{
ecatManager.state = ECAT_MASTER_SYNC;
}
break;
case ECAT_MASTER_SYNC:
// Manually change the state to SafeOP
ec_slave[0].state = EC_STATE_SAFE_OP;
ec_writestate(0);
osal_timer_start (&tself, EC_TIMEOUTSTATE * 4);
ecatManager.state = ECAT_MASTER_SAFEOP_IN_PROGRESS;
break;
case ECAT_MASTER_SAFEOP_IN_PROGRESS:
ec_readstate();
// wait for all slaves to reach SAFE_OP state
if(ec_slave[0].state == EC_STATE_SAFE_OP)
{
PRINTF("All slaves set in EC_STATE_SAFE_OP.\n");
expectedWKC = (ec_group[0].outputsWKC * 2) + ec_group[0].inputsWKC;
PRINTF("Calculated workcounter %d\n", expectedWKC);
ecatManager.state = ECAT_MASTER_SAFEOP;
}
else if(osal_timer_is_expired (&tself))
{
ecatManager.state = ECAT_MASTER_ERROR;
PRINTF("Could not set EC_STATE_SAFE_OP.\n");
ecatManager_abort();
}
break;
......
In this way register 0x1c32 and 0x1c33 subindex1,2 populate automatically correctly. I start PDOs with slaves still in PREOP so that I reach the syncronization (see where I set dorun variable). I have two questions:
Thank you for your help, Davidinos
Hi @Davidinos, great piece of code you posted. This is very helpful for others facing the same problems. I like programmers that use state machines to solve these kind of temporal issues.
I would indeed recommend to use PO2SOconfigx hook. Then the automatic recovery functions of SOEM will work correctly.
Again, good job!
Hello @ArthurKetels, thank you for your compliments, I'm blushing :). And thank you for your suggestions and clarifications. I'm going to use FRMW packets, instead of setting dorun variable, for obtaining the syncronization. In this way I could set dorun variable and start effective PDOs communication with slaves in OP state as it was before.
Thank you again for your help. Davidinos
Advisable is to start PDO transfers in safe-OP. Most slaves will throw an error if they do not receive PDOs in safe-OP.
Another tip is to send FRMW packets with zero timeout value. It is no use the master waits for the packets to return. It is more efficient to send them bakc-to-back with no delay. As configured slave address you should take the reference slave.
context->slavelist[context->grouplist[group].DCnext].configadr
Goodmorning, I'm trying to configure an Ethercat net with a Panasonic Minas-A6B motor slave. Starting from red_test example, my initialization code loop is the following:
My questions are:
SDO write operations are called for each slave. Is it the correct place to put them (right before ec_config_map(&IOmap))?
Thank you. Davidino
P.S. I know that using SDOs operation with the slave in OP state affects the comunication stability, but with the motor still, as long as it doesn't warn error, it shouldn't matter.