OpenEtherCATsociety / SOEM

Simple Open Source EtherCAT Master
Other
1.33k stars 675 forks source link

Problem receiving data from slave #370

Closed jakomoo closed 4 years ago

jakomoo commented 4 years ago

Hi, I am currently trying to implement a code to allow ethercat communication between a STM32f767zi controller (master) and a speedgoat (slave). So far I have managed to connect the two machines and change the state of the speedgoat to operational. I have also managed to send data to the speedgoat which has received it successfully. My problem occurs when I try to receive the data sent from the speedgoat. My expected working counter is 2 and my current working counter becomes 3 from the moment the speedgoat sends the data (the data type is uint8_t). On the slave side I'm using a bloc that sends uint8_t every 0.001s. I'm unable to solve the problem and that's why I'm trying my luck here. My code is mainly based on easyCAT_LAB.
Thanks for your help.

here is my code :

config.txt soem.start.txt output.txt main.txt

Thanks for your help :)

nakarlsson commented 4 years ago

The working counter is expected to be 3 for a Input/Output slave when running LRW commands used by SOEM. The Wkc is produced in HW.

Can you post a wireshark?

jakomoo commented 4 years ago

Hello, Unfortunately I can't have wireshark capture since the controller communicates directly with the speedgoat and the controller doesn't have windows/linux. Do you have another way to test the communication? I also noticed that when I send data to the slave, the slave receives it even though the working coutner is 2.

Thank you for your help

jakomoo commented 4 years ago

I have an other question. What is the best way to communicate with a slave? and what's the difference between 1) and 2). Tanks you again.

1) typedef struct attribute((packed)) { uint8_t valueSent; }out_netXt;

void MapLocalStructures (void) { out_netX = (out_netXt)((char )ec_slave[netX].outputs - &IOmap[0] + &IOmapSafe[0]);
}

out_netX->valueSent = 0x04;

and 2) uint8_t data_to_send; int wdl = 1; int slave = 1; int wkc = ec_SDOwrite(slave, 0x2000, 0x01, FALSE, wdl, &data_to_send, EC_TIMEOUTRXM);

nakarlsson commented 4 years ago

You can add a switch between the "Master and 1st Slave" and use a computer running Wireshark in between.


  1. Is the proper way using logic read/write of processdata eg multiple data in several slaves in the same frame.

  2. Is slow communication via mailbox protocol, eg read/write of a single SDO

jakomoo commented 4 years ago

All right, I'll try to get a wireshark capture with a switch.

Thank you very much !

In the meantime, do you have any idea why I'm able to communicate with the slave as follows:

typedef struct attribute((packed)) { uint8_t valueSent; }out_netXt;

void MapLocalStructures (void) { out_netX = (out_netXt)((char )ec_slave[netX].outputs - &IOmap[0] + &IOmapSafe[0]); }

out_netX->valueSent = 0x04;

But the only way to receive data from the slave is reading single SDO?

I am not able of receiving data using :

typedef struct attribute((packed)) { uint8_t value_read; }in_netXt;

void MapLocalStructures (void) { in_netX = (in_netXt)((char )ec_slave[netX].inputs - &IOmap[0] + &IOmapSafe[0]); }

uint8_t value = in_netX->value_read;

thank you for your time and help, it's very appreciated.

nakarlsson commented 4 years ago

ec_slave[netX].outputs/inputs holds pointer refs to the IOmap location where the outputs/inputs are stored. So below pseudo code show the concept.

void MapLocalStructure(void)
   in_netX = (in_netXt*)ec_slave[netX].inputs;
   out_netX = (out_netXt*)ec_slave[netX].outputs;

void application_loop
    out_netX->valueSent = 0x04;
    ec_send_processdata  // send data  taken from ec_slave[netX].outputs
    ec_receive_processdata // store data at ec_slave[netX].inputs
    uint8_t value = in_netX->value_read;
nakarlsson commented 4 years ago

I had a similar issue recently, a slave was generating wkc == 2 and no inputs got read. It was due to the slave used the TI ESC that does't support legacy SOEM logic memory mapping.

What ESC do you use?

jakomoo commented 4 years ago

I use as Ethercat Slave controller a speedgoat (netX) very similar to the texas intrument real-time card. So if my ESC doesn't support SOEM mapping, the only way to read the inputs is with SDOs ?
Thanks again for your help,

much appreciated

nakarlsson commented 4 years ago

Either try using LRD/LWR or use the "overlapping API". See if that helps.

  1. LRD/LWR For LRD/LWR via flag after config_init '' for (int i = 1; i <= ec_slavecount; i++) { ec_slave[i].blockLRW = 1; } ''

  2. Overlap Look for config/send functions namned overlap , ex ecx_config_overlap_map_group

nakarlsson commented 4 years ago

Can this be closed

nakarlsson commented 4 years ago

Inactive

jakomoo commented 4 years ago

Hello @nakarlsson, I couldn't get back to work because of the Covid. The ec_slave[slave].blockLRW = 1 was already in my code. Do you have an other idea? I could try with the overlap functions but I'm not sure I understand. I saw that there was an ecx_send_overlap_processdata() function but I don't see an ecx_receive_overlap_processdata() function. I have no problem sending my data to the slave, the problem is when I want to receive them. I am only able to access the data sent accessing single SDO.

uint8_t read_Data(uint8_t sub_index){

int8_t in;
int rdl = sizeof(uint8_t);
int slave = 1;
int wkc;
wkc = ec_SDOread(slave, 0x3000 , sub_index, FALSE, &rdl, &in, EC_TIMEOUTRXM);

return in;

}

Can you help? Capture

jakomoo commented 4 years ago

When I use ec_receive_processdata_group(0,EC_TIMEOUTRET), I receive -1 (EC_NOFRAME).