Introduction
This example demonstrates how to configure and use Dynamic PDOs (Process Data Objects) in an EtherCAT slave device using the CoE (CANopen over EtherCAT) protocol. Dynamic PDOs allow for flexible data transfer between the slave and master devices, enabling dynamic configuration of data points and their attributes.
Setting up a project in netX Studio.
Create a new PDO
This example is based on the ECS CoE Custom OD example.
open the AppECS_DemoApplication_Config.h and create new object as showed below:
{ .eCommand = OD_CREATE_OBJECT, .pszName = "3. RxPDO", .uCreate.tObject = { .usIndex = 0x1602, .bMaxNumOfSubObjs = 2, .bObjectCode = ODV3_OBJCODE_RECORD, .usAccessFlags = 0, .bValueInfo = 0, .bIndicationFlags = 0, .usDataType = ECAT_OD_DTYPE_PDO_MAPPING, .usAccessRights = ECAT_OD_ACCESS_ALL, .ulMaxFieldUnits = 0, }, .tInitial = {NULL, 0}, .tDefault = {NULL, 0}, .tMinimum = {NULL, 0}, .tMaximum = {NULL, 0}, },
create new PDO :
static const uint32_t s_ab1602_Elements[] = { PDOMAPPING(0x2002, 1, 8), }; static const uint8_t s_b1602_NumElements = HIL_CNT_ELEMENT(s_ab1602_Elements);
add new PDO to Sync Manager
static const uint16_t s_aus1C12_Entries[] = { 0x1600, 0x1601, 0x1602}; { .eCommand = OD_CREATE_SUBOBJECT, .pszName = NULL, .uCreate.tSubObject = { .usIndex = 0x1C12, .bSubindex = 3, .bValueInfo = ODV3_VALUE_INFO_INITIAL_VALUE, .bIndicationFlags = 0, .usDataType = ECAT_OD_DTYPE_UNSIGNED16, .usAccessRights = ECAT_OD_READ_ALL | ECAT_OD_WRITE_PREOP, .ulMaxFieldUnits = 1, }, .tInitial = {&s_aus1C12_Entries[2], sizeof(s_aus1C12_Entries[2])}, },
Add request
We need to add a special command that allows the application to inform the stack about a change in the input/output size. This is essential for dynamic PDO changes.
Go to the file AppECS_DemoApplication_DynPDO_Handler.c
Locate the function AppECSCustomOd_WriteObjectInd().
In this function, you'll find new code that receives the SyncManager objects 0x1C12 and 0x1C13.
uint32_t AppECSCustomOd_WriteObjectInd( APP_ECS_CHANNEL_HANDLER_RSC_T *ptEcsRsc, CIFX_PACKET* ptPacket ) { uint32_t ulRet = CIFX_NO_ERROR; uint8_t bSendPck = true; ODV3_WRITE_OBJECT_REQ_T* ptRes = (ODV3_WRITE_OBJECT_REQ_T*) ptPacket; ODV3_WRITE_OBJECT_REQ_T *ptReq = (ODV3_WRITE_OBJECT_REQ_T*) ptPacket; switch(ptRes->tData.usIndex) { case 0x1C12: PRINTF("case 0x1C012:" NEWLINE); case 0x1C13: PRINTF("case 0x1C013:" NEWLINE); bSendPck = false; /*Pkt_SendPacket inside function*/ ulRet = AppECS_OD_WriteInd_PDOAssignmentParameter(ptEcsRsc, ptReq); break; default: ulRet = ERR_ODV3_OBJECT_DOES_NOT_EXIST; break; } if(false != bSendPck) { ptRes->tHead.ulSta = ulRet; ptRes->tHead.ulCmd |= 0x01; ptRes->tHead.ulLen = sizeof(ptRes->tData); ulRet= Pkt_SendPacket( ptEcsRsc->hPktIfRsc, (CIFX_PACKET *) ptRes, APPECS_DEMOAPPLICATION_TIMEOUT); } return ulRet; }
The function AppECS_OD_WriteInd_PDOAssignmentParameter
contains two other functions: AppECS_OD_CalculatePdoOffsets
and AppECS_SetIoSizeReq
.
When the EtherCAT master sends a synchronization manager object to the slave, the slave's application must determine which PDO the master is interested in. Then, the application calculates the new size of the PDO and uses AppECS_SetIoSizeReq
to inform the EtherCAT stack about this new size.
Due to recent code changes, the application now has PDO 0x1602 with a size of one byte. To support this new PDO, it is necessary to modify the AppECS_OD_CalculatePdoOffsets
function.
EtherCat Master (TwinCAT)
You can check the result with ECM e.g. TwinCAT :
Copy the new ESI file to the TwinCAT ESI file folder. In the new project now activate PDO assignment.
Now in the list you can see the new PDO 0x1602 :
and under Startup also :
The task is completed and you can modify and supplement this example at your own choice and according to your tasks.
Conclusion
By following these steps and leveraging the capabilities of Dynamic PDOs, you can create flexible and efficient EtherCAT slave devices that can adapt to changing communication requirements.