OpenEtherCATsociety / SOEM

Simple Open Source EtherCAT Master
Other
1.37k stars 690 forks source link

Ethercat driver without rxpdo and txpdo assign? #419

Closed stevedanomodolor closed 4 years ago

stevedanomodolor commented 4 years ago

I am currently working with an ethercat driver that does not include the rxpdo and txpdo assign and mapping objects(on their manual): When I used the test slaveinfo -sdo, it showed there though. So i tried using this objects to remap the pdo but i keep getting the following error. Can someone help me please.

Also if I do not map the pdo, do I get all the full object list that it listed in their manual, it is an ingenia mc driver, the object list can be found in this link https://doc.ingeniamc.com/summit/manuals/summit-reference-manual/ethercat-canopen-registers

Thank you very much, Stevedan ogochukwu omodolor

Data read from ./slaveinfo -sdo(part of it )

..............................
        Value :0x0004 4
 Index: 1600 Datatype: 002a Objectcode: 09 Name: RxPDO Map 1
  Sub: 00 Datatype: 0005 Bitlength: 0008 Obj.access: 003f Name: SubIndex 000
          Value :0x04 4

....
Index: 1601 Datatype: 002a Objectcode: 09 Name: RxPDO Map 2
  Sub: 00 Datatype: 0005 Bitlength: 0008 Obj.access: 003f Name: SubIndex 000
          Value :0x02 2
  Sub: 01 Datatype: 0007 Bitlength: 0020 Obj.access: 003f Name: RxPDO Map 2 Element 1
          Value :0x60400010 1614807056
........
Index: 1a00 Datatype: 002a Objectcode: 09 Name: TxPDO Map 1
  Sub: 00 Datatype: 0005 Bitlength: 0008 Obj.access: 003f Name: SubIndex 000
          Value :0x04 4
  Sub: 01 Datatype: 0007 Bitlength: 0020 Obj.access: 003f Name: TxPDO Map 1 Element 1
          Value :0x60410010 1614872

......

        Value :0x03 3
 Index: 1c12 Datatype: 0006 Objectcode: 08 Name: RxPDO assign
  Sub: 00 Datatype: 0005 Bitlength: 0008 Obj.access: 000f Name: SubIndex 000
          Value :0x01 1
  Sub: 01 Datatype: 0006 Bitlength: 0010 Obj.access: 000f Name: SubIndex 001
          Value :0x1600 5632
 Index: 1c13 Datatype: 0006 Objectcode: 08 Name: TxPDO assign
  Sub: 00 Datatype: 0005 Bitlength: 0008 Obj.access: 000f Name: SubIndex 000
          Value :0x01 1
  Sub: 01 Datatype: 0006 Bitlength: 0010 Obj.access: 000f Name: SubIndex 001
          Value :0x1a00 6656
code for the pdo mapping 
            os = sizeof(ob2);
            ob2 = 0x1600; //RxPDO, check MAXPOS ESI
            //0x1c12 is Index of Sync Manager 2 PDO Assignment (output RxPDO), CA (Complete Access) must be TRUE
            int wkc_count = ec_SDOwrite(1, 0x1c12, 01, TRUE, os, &ob2, EC_TIMEOUTRXM); //change slave position (k+1) if needed

            if (wkc_count == 0)
            {
                printf("RxPDO assignment error\n");
                // return FALSE;
            }

            os = sizeof(ob2);
            ob2 = 0x1a00; //TxPDO, check MAXPOS ESI
            //0x1c13 is Index of Sync Manager 3 PDO Assignment (input TxPDO), CA (Complete Access) must be TRUE
            wkc_count = ec_SDOwrite(1, 0x1c13, 01, TRUE, os, &ob2, EC_TIMEOUTRXM); //change slave position (k+1) if needed
            if (wkc_count == 0)
            {
                printf("TxPDO assignment error\n");
                // return FALSE;
            }

            ec_config_map(&IOmap);

Result


OEM (Simple Open EtherCAT Master)
Slaveinfo
Starting slaveinfo
ec_init on eth2 succeeded.
Re mapping for MAXPOS...
RxPDO assignment error
TxPDO assignment error
Time:   16123.588 SDO slave:1 index:1c12.00 error:08000020 Data cannot be transferred or stored to the application
Time:   16123.590 SDO slave:1 index:1c13.00 error:08000020 Data cannot be transferred or stored to the application
1 slaves found and configured.
Calculated workcounter 3

Slave:1
 Name:Servo Drives
 Output size: 88bits
 Input size: 88bits
 State: 4
 Delay: 0[ns]
 Has DC: 1
 DCParentport:0
 Activeports:1.0.0.0
 Configured address: 1001
 Man: 0000029c ID: 02c30001 Rev: 00000003
 SM0 A:1000 L: 128 F:00010026 Type:1
 SM1 A:1400 L: 128 F:00010022 Type:2
 SM2 A:1800 L:  11 F:00010064 Type:4
 SM3 A:1c00 L:  11 F:00010020 Type:3
 FMMU0 Ls:00000000 Ll:  11 Lsb:0 Leb:7 Ps:1c00 Psb:0 Ty:02 Act:01
 FMMU1 Ls:0000000b Ll:  11 Lsb:0 Leb:7 Ps:1800 Psb:0 Ty:01 Act:01
 FMMU2 Ls:00000000 Ll:  11 Lsb:0 Leb:7 Ps:1c00 Psb:0 Ty:02 Act:01
 FMMU3 Ls:0000000b Ll:  11 Lsb:0 Leb:7 Ps:1800 Psb:0 Ty:01 Act:01
 FMMUfunc 0:1 1:2 2:3 3:0
 MBX length wr: 128 rd: 128 MBX protocols : 0e
 CoE details: 2f FoE details: 01 EoE details: 01 SoE details: 00
 Ebus current: 0[mA]
 only LRD/LWR:0
PDO mapping according to CoE :
  SM2 inputs
     addr b   index: sub bitl data_type    name
  [0x000B.0] 0x6040:0x00 0x10 UNSIGNED16   Control Word
  [0x000D.0] 0x607A:0x00 0x20 INTEGER32    Position set-point
  [0x0011.0] 0x60FF:0x00 0x20 INTEGER32    Velocity set-point
  [0x0015.0] 0x6060:0x00 0x08 INTEGER8     Operation mode
  SM3 outputs
     addr b   index: sub bitl data_type    name
  [0x0000.0] 0x6041:0x00 0x10 UNSIGNED16   Status Word
  [0x0002.0] 0x6064:0x00 0x20 INTEGER32    Actual position
  [0x0006.0] 0x606C:0x00 0x20 INTEGER32    Actual velocity
  [0x000A.0] 0x6061:0x00 0x08 INTEGER8     Operation mode display
End slaveinfo, close socket
End program
ArthurKetels commented 4 years ago

Some basic mistakes: a) change of mapping is only supported in pre-op b) mapping of slaves should be done in the SO2PO hook function provided by SOEM c) when using CA an array should be send to the slave with the proper length and 16bit aligned per subindex d) preferred to not use CA for mapping, this way it is easier to spot errors

Search for earlier posts for examples how to do this properly.

ArthurKetels commented 4 years ago

From the Ingenia website: https://doc.ingeniamc.com/summit/manuals/summit-reference-manual/tricks-and-tips/ethercat-pdo-mapping

stevedanomodolor commented 4 years ago

if i set the pdo using the twin, there wont be any need to do it again with the soem library right?

Also, what does Ca means and what SO2PO function?

ArthurKetels commented 4 years ago

Did you actually read the tutorial.txt in de doc map of SOEM?

stevedanomodolor commented 4 years ago

Yes I did, This was the first thing i tried but it did not seem to change the mapping atall, I also asked earlier about the ecx_sdo and ec_sdo but I was told that they should not be any difference,if I use the ec_sdowrite. I might be doing something wrong but I am not sure what so it is confusing, I am quite new to this topic, sorry for the inconvenience.

#define EC_TIMEOUTMON 500
#define SERVO_DRIVE_1 1
#define NUMBER_OF_SLAVES 1

char IOmap[4096];
OSAL_THREAD_HANDLE thread1;
int expectedWKC;
boolean needlf;
volatile int wkc;
boolean inOP;
uint8 currentgroup = 0;

uint32_t network_configuration(void)
{
   /* Do we got expected number of slaves from config*/
   if (ec_slavecount < NUMBER_OF_SLAVES)
      return 0;
   /*Verify slave by slave that it is correct*/

   if (strcmp(ec_slave[SERVO_DRIVE_1].name, "Servo Drives")) // TODO: Fix names
      return 0;

   return 1;
   //..... TODO: Add more drivers
}

// custom pdo configuration
int servo_drive1_PDO_MAP(uint16 slave)
{
   int retval;
   uint16 u16val;

   retval = 0;

   /* Map velocity PDO assignment via Complete Access*/
   uint16 map_1c12[4] = {0x0003, 0x1601, 0x1602, 0x1604};
   uint16 map_1c13[3] = {0x0002, 0x1a01, 0x1a03};
   retval += ec_SDOwrite(slave, 0x1c12, 0x00, TRUE, sizeof(map_1c12), &map_1c12, EC_TIMEOUTSAFE);
   retval += ec_SDOwrite(slave, 0x1c13, 0x00, TRUE, sizeof(map_1c13), &map_1c13, EC_TIMEOUTSAFE);
   printf("EL7031 slave %d set, retval = %d\n", slave, retval);
   return 1;
}

void simpletest(char *ifname)
{
   int i, j, oloop, iloop, chk;
   needlf = FALSE;
   inOP = FALSE;
   int usedmem;

   printf("Starting simple test\n");

   /* initialise SOEM, bind socket to ifname */
   if (ec_init(ifname))
   {
      printf("ec_init on %s succeeded.\n", ifname);
      /* find and auto-config slaves */

      if (ec_config_init(FALSE) > 0)
      {
         printf("%d slaves found and configured.\n", ec_slavecount);

         // Make sure that the we have the correct amount of ethercat slaves
         if (network_configuration())
         {

            //PDO mapping for each slaves from vendor ID and product code
            for (int slc = 1; i < ec_slavecount; i++)
            {
               // Printing drive info
               printf("%x\t%x\n", ec_slave[slc].eep_man, ec_slave[slc].eep_id);

               if ((ec_slave[slc].eep_man == 0x0000029c) && (ec_slave[slc].eep_id == 0x02c30001))
               {
                  printf("Found %s at position %d\n", ec_slave[slc].name, slc);
                  ec_slave[slc].PO2SOconfig = servo_drive1_PDO_MAP;
               }
            }
            // PDO mapping
            //TODO: Add escape statemate incase there is an error
 ec_config_map(&IOmap);
            // if(usedmem <= sizeof(IOmap)){
            //    printf("Error during PDO mapping\n");
            //    // return 0;
            // }

            ec_configdc();

            printf("Slaves mapped, state to SAFE_OP.\n");
            /* wait for all slaves to reach SAFE_OP state */
            ec_statecheck(0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE * 4);

            // Reading the pdo values
            // for(int slc = 0; i < ec_slavecount; i++ ) {
            //    si_map_sdo(slc);

            // }
stevedanomodolor commented 4 years ago

I was able to map the data directly with the twincat software, thank you very much thoguh, If there is any information that you think I am missing or any knowledge you think I should know, please let me know, i would really be gratefull to be honest

Thank you very much

ArthurKetels commented 4 years ago

Thanks for the info (if only again it is only part of it). As I mentioned above in the engenia link, they clearly state that only one mapping object (0x16xx or 0x1axx) can be assigned to a SM (0x1c12 or ox1c13). Your code above assigns 3 and 2. If you want multiple objects mapped then you have to rewrite an assign object (for example 0x1a01). And the order is also important, first the mapping object (0x1a01) then the SM assign (0x1c13).

Next time, first read the available documentation, then think and make a plan that is in agreement with the documentation, then try. If it still does not work post the -whole- test program and a wireshark trace. This saves hours (or days) of going in wrong directions.

stevedanomodolor commented 4 years ago

Thank you for the advice, new to programming in general, so it gets confusing sometimes.

stevedanomodolor commented 4 years ago

This is question might sound kind of stupid but I am a bit confused and I dont know why the data(the index number) does not match. The address that the Ingenia mc drivers stated is different from the one the soem library slaveinfo -map showed. Am I missing something?

[0x000B.0] 0x6040:0x00 0x10 UNSIGNED16 Control Word [0x000D.0] 0x607A:0x00 0x20 INTEGER32 Position set-point [0x0011.0] 0x60FF:0x00 0x20 INTEGER32 Velocity set-point [0x0015.0] 0x6060:0x00 0x08 INTEGER8 Operation mode SM3 outputs addr b index: sub bitl data_type name [0x0000.0] 0x6041:0x00 0x10 UNSIGNED16 Status Word [0x0002.0] 0x6064:0x00 0x20 INTEGER32 Actual position [0x0006.0] 0x606C:0x00 0x20 INTEGER32 Actual velocity [0x000A.0] 0x6061:0x00 0x08 INTEGER8 Operation mode display

The ingenia index and aub undex can be found here

https://doc.ingeniamc.com/summit/manuals/summit-reference-manual/ethercat-canopen-registers/0x2011-status-word

nakarlsson commented 4 years ago

Seems about right, https://doc.ingeniamc.com/summit/manuals/summit-reference-manual/ethercat-canopen-registers/0x6041-status-word

stevedanomodolor commented 4 years ago

Thank you jjajajajajajaj, how did you do that, when i load the same page, i get totally different data, it has something to do with the website, searching the objects gives the correct data but clicking on it, gives a different index