OpenEtherCATsociety / SOEM

Simple Open Source EtherCAT Master
Other
1.36k stars 688 forks source link

read and wrtie code - Wago 750-354 #272

Closed Tugev closed 5 years ago

Tugev commented 5 years ago

Hi,

I have Wago 750-354 etherCat and I would be grateful if someone can explain how to write and read it. It is one slave and in the manual it is written that the object 0x7000...0x73F0 contain output data for the I/O module and index results equation:

index = 0x7000 + (no of the I/O module - 1) . 0x0010

I just want some hints, I went through the simple_test and red_test examples but unfortunately, I could not figure out how to do it as I am totally new to this topic.

I understand that I should start with the following:

ec_init("enp4s0f1"); ec_config_init(0); char iomap[4096]; ec_config_map(&iomap);

// What should happen here ?

ec_send_processdata(); ec_receive_processdata(EC_TIMEOUTRET); ec_writestate(1));

Thanks.

Wago wireshark.pcapng.zip

ArthurKetels commented 5 years ago

Everything OK with the wireshark trace. So your slave is working as expected. To see what the mapping is use : slaveinfo enp4s0f1 -map Then follow the tutorial.txt. Is quite easy to understand I guess.

Tugev commented 5 years ago

Hi Arthur, Thanks for your reply. Is this what I suppose to get from the slaveinfo -map:

SOEM (Simple Open EtherCAT Master) Slaveinfo Starting slaveinfo ec_init on enp4s0f1 succeeded. wkc = 1 1 slaves found and configured. Calculated workcounter 3

Slave:1 Name:WAGO Series 750 Bus Coupler Output size: 48bits Input size: 48bits State: 4 Delay: 0[ns] Has DC: 1 DCParentport:0 Activeports:1.0.0.0 Configured address: 1001 Man: 00000021 ID: 07500354 Rev: 00000002 SM0 A:1000 L: 512 F:00010026 Type:1 SM1 A:1400 L: 512 F:00010022 Type:2 SM2 A:1800 L: 6 F:00010064 Type:3 SM3 A:2400 L: 6 F:00010000 Type:4 FMMU0 Ls:00000000 Ll: 6 Lsb:0 Leb:7 Ps:1800 Psb:0 Ty:02 Act:01 FMMU1 Ls:00000006 Ll: 6 Lsb:0 Leb:7 Ps:2400 Psb:0 Ty:01 Act:01 FMMUfunc 0:1 1:3 2:3 3:0 MBX length wr: 512 rd: 512 MBX protocols : 04 CoE details: 33 FoE details: 00 EoE details: 00 SoE details: 00 Ebus current: 0[mA] only LRD/LWR:0 End slaveinfo, close socket End program

And also what does it mean that the state is 4 ?

Thanks

ArthurKetels commented 5 years ago

Something went wrong with the -map parameter. I do not see the mapping displayed. Could you try again and if no change post the wireshark dump?

States: 1 - Init 2 - pre-OP 4 - safe-OP 8 - OP (operational)

For if you didn't know it : https://www.ethercat.org/download/documents/EtherCAT_Device_Protocol_Poster.pdf

Tugev commented 5 years ago

I got the same output. here is the wireshark file. slaveinfo.pcapng.zip

ArthurKetels commented 5 years ago

There is something wrong with your slaveinfo enp4s0f1 -map. You should either get a console message PDO mapping according to SII or PDO mapping according to CoE after only LRD/LWR:0.

Tugev commented 5 years ago

Do you think something is wrong with the connections ? is there anything can I do to fix this issue ?

ArthurKetels commented 5 years ago

Just debug slaveinfo. For some reason the 2nd parameter -map is not being recognized. If you look at the code you see it is a very simple string compare. So it should work, and I have never had any remark by others that it didn't work for them.

Tugev commented 5 years ago

Hey Arthur, I disconnected - reconnected everything and now I have the mapping output:

SOEM (Simple Open EtherCAT Master) Slaveinfo Starting slaveinfo ec_init on enp4s0f1 succeeded. wkc = 1 1 slaves found and configured. Calculated workcounter 3

Slave:1 Name:WAGO Series 750 Bus Coupler Output size: 48bits Input size: 48bits State: 4 Delay: 0[ns] Has DC: 1 DCParentport:0 Activeports:1.0.0.0 Configured address: 1001 Man: 00000021 ID: 07500354 Rev: 00000002 SM0 A:1000 L: 512 F:00010026 Type:1 SM1 A:1400 L: 512 F:00010022 Type:2 SM2 A:1800 L: 6 F:00010064 Type:3 SM3 A:2400 L: 6 F:00010000 Type:4 FMMU0 Ls:00000000 Ll: 6 Lsb:0 Leb:7 Ps:1800 Psb:0 Ty:02 Act:01 FMMU1 Ls:00000006 Ll: 6 Lsb:0 Leb:7 Ps:2400 Psb:0 Ty:01 Act:01 FMMUfunc 0:1 1:3 2:3 3:0 MBX length wr: 512 rd: 512 MBX protocols : 04 CoE details: 33 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] 0xF200:0x01 0x01 BOOLEAN K-Bus Cycle Overrun Flag Disable [0x0000.1] 0xF200:0x02 0x01 BOOLEAN Input Process Data Hold Request [0x0000.2] 0xF200:0x03 0x01 BOOLEAN Output Process Data Hold Request [0x0000.3] 0xF200:0x04 0x01 BOOLEAN Output Process Data Clear Request [0x0000.4] 0x0000:0x00 0x0C [0x0002.0] 0xF200:0x05 0x10 UNSIGNED16 Diagnostics Control Word [0x0004.0] 0x7010:0x01 0x01 BOOLEAN Channel 1 Data [0x0004.1] 0x7010:0x02 0x01 BOOLEAN Channel 2 Data [0x0004.2] 0x7010:0x03 0x01 BOOLEAN Channel 3 Data [0x0004.3] 0x7010:0x04 0x01 BOOLEAN Channel 4 Data [0x0004.4] 0x7010:0x05 0x01 BOOLEAN Channel 5 Data [0x0004.5] 0x7010:0x06 0x01 BOOLEAN Channel 6 Data [0x0004.6] 0x7010:0x07 0x01 BOOLEAN Channel 7 Data [0x0004.7] 0x7010:0x08 0x01 BOOLEAN Channel 8 Data [0x0005.0] 0x0000:0x00 0x08 SM3 inputs addr b index: sub bitl data_type name [0x0006.0] 0xF100:0x01 0x01 BOOLEAN K-Bus Cycle Overrun Flag [0x0006.1] 0xF100:0x02 0x01 BOOLEAN Input Process Data Hold Ack. [0x0006.2] 0xF100:0x03 0x01 BOOLEAN Output Process Data Hold Ack. [0x0006.3] 0xF100:0x04 0x01 BOOLEAN Output Process Data Clear Ack. [0x0006.4] 0x0000:0x00 0x0B [0x0007.7] 0x10F3:0x04 0x01 BOOLEAN New Message Available [0x0008.0] 0xF100:0x05 0x10 UNSIGNED16 Diagnostics Status Word [0x000A.0] 0x6000:0x01 0x01 BOOLEAN Channel 1 Data [0x000A.1] 0x6000:0x02 0x01 BOOLEAN Channel 2 Data [0x000A.2] 0x6000:0x03 0x01 BOOLEAN Channel 3 Data [0x000A.3] 0x6000:0x04 0x01 BOOLEAN Channel 4 Data [0x000A.4] 0x6000:0x05 0x01 BOOLEAN Channel 5 Data [0x000A.5] 0x6000:0x06 0x01 BOOLEAN Channel 6 Data [0x000A.6] 0x6000:0x07 0x01 BOOLEAN Channel 7 Data [0x000A.7] 0x6000:0x08 0x01 BOOLEAN Channel 8 Data [0x000B.0] 0x0000:0x00 0x08 End slaveinfo, close socket End program

Does it look OK ?

ArthurKetels commented 5 years ago

Looks OK now. The next step is following tutorial.txt in the doc folder.

Your structs could look like (just as example)

 typedef struct PACKED
{
        uint16         pdocontrol;
        uint16         diagcontrol;
        uint8           outdata;
        uint8           filler;
} out_WAGOt;

 typedef struct PACKED
{
        uint16         pdostatus;
        uint16         diagstatusl;
        uint8           indata;
        uint8           filler;
} in_WAGOt;

out_WAGOt       *out_WAGO;
in_WAGOt        *in_WAGO;

/* connect struct pointers to slave I/O pointers */
out_WAGO = (out_WAGOt*) ec_slave[1].outputs;
in_wago = (in_WAGOt*)ec_slave[1].inputs;
/* example to output bit pattern into PDO data, output is inverse from input */
out_WAGO->outdata = in_WAGO->indata ^ 0xff; 
Tugev commented 5 years ago

Hi Arthur, thx for your swift response. May I please ask you to check the following code if I understood correctly how to for example turn on one led in the output module:

#define SLAVE_NR 1

void set_output_int8 (uint16 slave_no, uint8 module_index, int8 value)
{
  uint8 *data_ptr;

  data_ptr = ec_slave[slave_no].outputs;
  /* Move pointer to correct module index*/
  //data_ptr += module_index * 8;
  /* Read value byte by byte since all targets can't handle misaligned addresses */
  *data_ptr++ = value;
}

void set_output_bit (uint16 slave_no, uint8 module_index, uint8 value)
{
   /* Get the the startbit position in slaves IO byte */
   uint8 startbit = ec_slave[slave_no].Ostartbit;
   /* Set or Clear bit */
   if (value == 0)
      *ec_slave[slave_no].outputs &= ~(1 << (module_index - 1 + startbit));
   else
      *ec_slave[slave_no].outputs |= (1 << (module_index - 1 + startbit));
}

char IOmap[4096];
volatile int wkc;

int main(int argc, char **argv)
{
  int chk;

 //initialise SOEM
 if (ec_init("enp4s0f1"))
 {

   if ( ec_config_init(FALSE) > 0 )
  {
     std::cout<<"slave found and configured"<<ec_slavecount<<std::endl;

     ec_config_map(&IOmap);

     ec_configdc();

     std::cout<<"Slave mapped, state to SAFE_OP"<<std::endl;

     /* wait for all slaves to reach SAFE_OP state */
     ec_statecheck(1, EC_STATE_SAFE_OP,  EC_TIMEOUTSTATE * 4);

     std::cout<<"Request operational state for the slave"<<std::endl;

     ec_slave[1].state = EC_STATE_OPERATIONAL;
     /* send one valid process data to make outputs in slaves happy*/
     ec_send_processdata();
     ec_receive_processdata(EC_TIMEOUTRET);
     /* request OP state for all slaves */
     ec_writestate(1);
     chk = 40;
     /* wait for all slaves to reach OP state */
     do
     {
        ec_send_processdata();
        ec_receive_processdata(EC_TIMEOUTRET);
        ec_statecheck(0, EC_STATE_OPERATIONAL, 50000);
     }
     while (chk-- && (ec_slave[1].state != EC_STATE_OPERATIONAL));
     if (ec_slave[1].state == EC_STATE_OPERATIONAL )
     {
        std::cout<<"Operational state reached for the slave"<<std::endl;
     }

     ec_slave[1].state = EC_STATE_INIT;
     /* request INIT state for all slaves */
     ec_writestate(0);
   }

  set_output_bit (SLAVE_NR, 2, 1);

  ec_send_processdata();
  ec_writestate(1);