OpenEtherCATsociety / SOEM

Simple Open Source EtherCAT Master
Other
1.34k stars 683 forks source link

Question about send/receive pdo #177

Closed tuanakv closed 6 years ago

tuanakv commented 6 years ago

I try to use SOEM to control a Omron 1SN servodrive, the protocol that the servo uses is CoE. At this time I can read/write SDO data from the servodrive . But I can not read/write PDO data. I run my program , and IOmaping done as below: 1 slaves found and configured. Slaves mapped, state to SAFE_OP. 0.000000 Request operational state for all slaves state is : 4 Found omron drive IO map size is : 40

Slave:1 Name:R88D-1SN02H-ECT Output size: 96bits Input size: 224bits State: 8 Delay: 0[ns] Has DC: 1 DCParentport:0 Activeports:1.0.0.0 Configured address: 1001 Man: 00000083 ID: 000000af Rev: 00010000 SM0 A:1800 L: 256 F:00010026 Type:1 SM1 A:1c00 L: 256 F:00010022 Type:2 SM2 A:1100 L: 12 F:00010064 Type:3 SM3 A:1200 L: 28 F:00010020 Type:4 FMMU0 Ls:00000000 Ll: 12 Lsb:0 Leb:7 Ps:1100 Psb:0 Ty:02 Act:01 FMMU1 Ls:0000000c Ll: 28 Lsb:0 Leb:7 Ps:1200 Psb:0 Ty:01 Act:01 FMMUfunc 0:1 1:2 2:3 3:0 MBX length wr: 256 rd: 256 MBX protocols : 04 CoE details: 2d FoE details: 00 EoE details: 00 SoE details: 00 Ebus current: 0[mA] only LRD/LWR:0 PDO mapping according to CoE : SM2 outputs addr b index: sub bitl data_type name [0x0000.0] 0x6040:0x00 0x10 [0x0002.0] 0x607A:0x00 0x20 [0x0006.0] 0x60B8:0x00 0x10 [0x0008.0] 0x60FE:0x01 0x20 SM3 inputs addr b index: sub bitl data_type name [0x000C.0] 0x603F:0x00 0x10 [0x000E.0] 0x6041:0x00 0x10 [0x0010.0] 0x6064:0x00 0x20 [0x0014.0] 0x6077:0x00 0x10 [0x0016.0] 0x60F4:0x00 0x20 [0x001A.0] 0x60B9:0x00 0x10 [0x001C.0] 0x60BA:0x00 0x20 [0x0020.0] 0x60BC:0x00 0x20 [0x0024.0] 0x60FD:0x00 0x20 End slaveinfo, close socket End program

for read PDO 0x6041:0x00 (Status word) and write PD0 0x6040:0x00. Can anyone show me example for reading PDO 0x6041:0x00 (Status word) and writing PD0 0x6040:0x00?

I tried code as issue 130: https://github.com/OpenEtherCATsociety/SOEM/issues/130 typedef struct PACKED { uint16 control_word; uint16 target_position; } out_EL4132t; out_EL4132t out_EL4132; typedef struct PACKED { uint16 status_word; int8 mode_op; } input_omron; input_omron in_omron; / writing/ / connect struct pointers to slave I/O pointers / out_EL4132 = (out_EL4132t)ec_slave[1].outputs; out_EL4132->control_word = 0x6040 * 14;

if (EcatError) printf("%s", ec_elist2string()); in_omron = (input_omron*)ec_slave[1].inputs;

ec_send_processdata(); ec_receive_processdata(EC_TIMEOUTRET);

I hope you can help me to solve this issue.

mheden commented 6 years ago

You probably want something like this:

typedef struct PACKED
{
   uint16_t value_6040;
   uint32_t value_607A;
   uint16_t value_60B8;
   uint32_t value_60FE;
} omron_outputs_t;

omron_outputs_t * ptr = (omron_outputs_t)ec_slave[1].outputs;
ptr->value_6040 = <your value>;

ec_send_processdata();
ec_receive_processdata(EC_TIMEOUTRET);
tuanakv commented 6 years ago

Hi, Thank you for your response. I will try as you guide. But i have question: I don't understand when setting ptr->value_6040 is meaning of set value of 0x6040 of servo driver? And can you show me example of reading 0x6041 pdo?

mheden commented 6 years ago

SOEM maps up all PDOs of the slavs into the IOmap. ec_slave[x].outputs and ec_slave[x].inputs are pointers to the correct location in the IOmap.

Your slaveinfo output shows the PDO-mapping and the position in the IO map. So, in your case, ec_slave[1].outputs points to &IOmap[0] and ec_slave[1].inputs points to &IOmap[0xC].

So, to read and write PDOs, you read/write to the IOmap. In my previous example, I map a structure to the correct memory location and use that instead to access the variables.

ptr->value_6040 = 0x1234 means that you will write the value 0x1234 to the 0x6040 pdo.

For reading, you can do the same. Create a structure and map it to ec_slave[1].inputs and access the members accordingly.

nakarlsson commented 6 years ago

Can we close this?

nakarlsson commented 6 years ago

I'll close for now

WangKaimeng commented 5 years ago

SOEM maps up all PDOs of the slavs into the IOmap. ec_slave[x].outputs and ec_slave[x].inputs are pointers to the correct location in the IOmap. Your slaveinfo output shows the PDO-mapping and the position in the IO map. So, in your case, ec_slave[1].outputs points to &IOmap[0] and ec_slave[1].inputs points to &IOmap[0xC]. So, to read and write PDOs, you read/write to the IOmap. In my previous example, I map a structure to the correct memory location and use that instead to access the variables. ptr->value_6040 = 0x1234 means that you will write the value 0x1234 to the 0x6040 pdo. For reading, you can do the same. Create a structure and map it to ec_slave[1].inputs and access the members accordingly.

I try it as your suggestion, the inputs is right, but the output is not what I want. my struct is as follow: typedef struct PACKED { uint16 Ctrlword_6040; uint32 TargetPos_607A; uint32 VelocityOffset_60B1; uint16 TorqueOffset_60B2;
} Copley_CyclicPos_outputs; and Ctrlword_6040 equals 0x0100, TargetPos_607A equals 0x00000005, VelocityOffset_60B1 equals 0x00000007, TorqueOffset_60B2 equals 0x0006 Therefore, the ec_slave[1].outputs that I want is 0001 0000 0500 0000 0700 0600 but the actual outputs for 10 times are
O: 05 01 00 00 05 00 00 00 07 00 00 00 O: 09 01 00 00 05 00 00 00 07 00 00 00 O: 0d 01 00 00 05 00 00 00 07 00 00 00 O: 12 01 00 00 05 00 00 00 07 00 00 00 O: 17 01 00 00 05 00 00 00 07 00 00 00 O: 1b 01 00 00 05 00 00 00 07 00 00 00 O: 20 01 00 00 05 00 00 00 07 00 00 00 O: 24 01 00 00 05 00 00 00 07 00 00 00 O: 29 01 00 00 05 00 00 00 07 00 00 00 It's so strange that the Ctrlword_6040 is always changed and TorqueOffset_60B2 is equal to zero but not 0x0006. Besides, this is my PDO map: PDO mapping according to CoE : SM2 outputs addr b index: sub bitl data_type name [0x0000.0] 0x6040:0x00 0x10 [0x0002.0] 0x607A:0x00 0x20 [0x0006.0] 0x60B1:0x00 0x20 [0x000A.0] 0x60B2:0x00 0x10 SM3 inputs addr b index: sub bitl data_type name [0x000C.0] 0x6061:0x00 0x08 [0x000D.0] 0x6061:0x00 0x08 [0x000E.0] 0x6041:0x00 0x10 [0x0010.0] 0x6064:0x00 0x20 [0x0014.0] 0x60F4:0x00 0x20 [0x0018.0] 0x606C:0x00 0x20 [0x001C.0] 0x6077:0x00 0x10

I hope to get your suggestion! Thanks!

yusufselimkaratas commented 5 years ago

You probably want something like this:

typedef struct PACKED
{
   uint16_t value_6040;
   uint32_t value_607A;
   uint16_t value_60B8;
   uint32_t value_60FE;
} omron_outputs_t;

omron_outputs_t * ptr = (omron_outputs_t)ec_slave[1].outputs;
ptr->value_6040 = <your value>;

ec_send_processdata();
ec_receive_processdata(EC_TIMEOUTRET);

Hi I want to use that but

omron_outputs_t * ptr = (omron_outputs_t)ec_slave[1].outputs;

this line gives me error that : cast tp type omron_outputs_t is not allowed.

What can I do? @mheden