Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Link Lost and RX Frame Error counters #850

Open
royerboat opened this issue Aug 22, 2024 · 3 comments
Open

Link Lost and RX Frame Error counters #850

royerboat opened this issue Aug 22, 2024 · 3 comments

Comments

@royerboat
Copy link

Hello,

Is it possible with SOEM to get the Link Lost counters and RX Frame Error counters?
We are trying to gather some diagnostic information from the slaves on the bus to help us with troubleshooting. Our EtherCAT bus consists of 6 ELMO Gold Triple Twitter EtherCAT motor controllers and 1 Up Squared computer running the SOEM master.

This is the api call we have been trying to send from our master to the individual slaves:

int ret = ec_SDOread(device_index, index, subindex, complete_access, &size, &value, EC_TIMEOUTRXM);

device_index is 1-6
The indexes we have tried to read are 0x0300 - 0x0307 and 0x0310 - 0x0313.
Subindex is 0
We have tried complete_access with both true and false.
size is the sizeof(uint8_t) which should be 1.
value is a pointer.
EC_TIMEOUTRXM is a constant set to 700000.

The return value from the function is 0. The ec_SDOread calls a ecx_SDOread and from there we are getting an ECT_SDO_ABORT error with abort code 0x06020000 (Object does not exist in object dictionary).

We are able to get other object values from slaves using the ec_SDOread call, so we know that we can communicate. When requesting these registers, we always get errors.

Is the ec_SDOread the right api to call to read the Link Lost and RX Frame Error counters? Are there other things we should try?

Thanks!

@royerboat
Copy link
Author

Hello again,

We were able to get this information from the slave by using the ec_FPRD function. To make this callable outside of the ethercatbase.c file, we made the following changes to ethercatcoe.h and ethercatcoe.cpp.

// ethercatcoe.h
int ec_REGread(uint16_t device_id, uint16_t ADO, uint16_t length, void *data);
// ethercatcoe.c
int ec_REGread(uint16_t device_id, uint16_t ADO, uint16_t length, void *data)
{
    return ec_FPRD(ecx_context.slavelist[device_id].configadr, ADO, length, data, EC_TIMEOUTRET3);
}

Now, we think we are able to get the data we want. For example:

uint8_t buf8 = 0;
if (ec_REGread(ec_device_index, 0x0310, sizeof(buf8), &buf8) > 0)
{
    printf("Register 0x0310 has %d\n", buf8);
else
{
    printf("Error with retrieving register 0x0310\n");
}

We are not sure if this was the right place to make these changes, but this works for our use case. Does this seem reasonable? Is this getting the correct data for 0x0310 (Link Lost Counter)?

Thanks!

@ArthurKetels
Copy link
Contributor

The ec_FPRD function is already accessible. Why wrap it in ec_REGread? ec_FPRD is a basic EtherCAT function, just as reading and writing registers in the ESC. And it has no place in the CoE header as it is not related to the CoE protocol.

The most effective way is to define a struct that envelops all error counters and read those registers in on go. The minimum frame length is 60 bytes, so you can just as well use all of those. Reading multiple registers have no time penalty.

@royerboat
Copy link
Author

Thank you Arthur for the reply and for the helpful tip about requesting multiple registers in one go!

The reason we created a wrapper function is because the rest of our code is isolated from the context in the ethercatbase. Based on your suggestion, we will move it somewhere else.

Thanks for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants