OpenEtherCATsociety / SOEM

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

Problems with adding more than three objects to PDO #237

Closed urban-eriksson closed 5 years ago

urban-eriksson commented 5 years ago

I have a problem that the servo is not working when I define 4 objects in the Rx PDO. Three objects is ok. I made a double check using codesys and then it works with 4 objects. Any idea what can be the reason?

Not working: ... ec_statecheck(0, EC_STATE_PRE_OP, EC_TIMEOUTSTATE);

        // The write32 function for info:
        // static int write32(uint16 slave, uint16 index, uint8 subindex, uint32 value)
        // {
        //    int wck;
        //    wck = ec_SDOwrite (slave, index, subindex, FALSE, sizeof(value), &value, EC_TIMEOUTRXM);
        //    printf("Write32 => Slave: %u, Index: 0x%4.4x Subindex: %u, Size %lu, Value:  0x%4.4x , wck %i\n", slave, index, subindex, sizeof(value),value, wck);
        //    if (wck==0) {
        //        printf("WARNING: wck equal to zero.\n");
        //    }
        //    return wck;
        // }

        int wsum = 0;

        wsum += write8(1,0x6060,0,10); // Set mode of operation to CST

        wsum += write8 (1, 0x1C12, 0, 0);
        wsum += write8 (1, 0x1600, 0, 0);
        wsum += write32(1, 0x1600, 1, 0x60400010); // Control word
        wsum += write32(1, 0x1600, 2, 0x60710010); // Target torque
        wsum += write8 (1, 0x1600, 0, 2);
        wsum += write16(1, 0x1C12, 1, 0x1600);
        wsum += write8 (1, 0x1C12, 0, 1);

        wsum += write8 (1, 0x1C13, 0, 0);
        wsum += write8 (1, 0x1A00, 0, 0);
        wsum += write32(1, 0x1A00, 1, 0x60410010); // Status word
        wsum += write32(1, 0x1A00, 2, 0x60640020); // Position actual value
        wsum += write32(1, 0x1A00, 3, 0x606C0020); // Velocity actual value
        wsum += write32(1, 0x1A00, 4, 0x60770010); // Torque actual value
        wsum += write8 (1, 0x1A00, 0, 4);
        wsum += write16(1, 0x1C13, 1, 0x1A00);
        wsum += write8 (1, 0x1C13, 0, 1);

...

Working:

... ec_statecheck(0, EC_STATE_PRE_OP, EC_TIMEOUTSTATE);

        int wsum = 0;

        wsum += write8(1,0x6060,0,10); // Set mode of operation to CST

        wsum += write8 (1, 0x1C12, 0, 0);
        wsum += write8 (1, 0x1600, 0, 0);
        wsum += write32(1, 0x1600, 1, 0x60400010); // Control word
        wsum += write32(1, 0x1600, 2, 0x60710010); // Target torque
        wsum += write8 (1, 0x1600, 0, 2);
        wsum += write16(1, 0x1C12, 1, 0x1600);
        wsum += write8 (1, 0x1C12, 0, 1);

        wsum += write8 (1, 0x1C13, 0, 0);
        wsum += write8 (1, 0x1A00, 0, 0);
        wsum += write32(1, 0x1A00, 1, 0x60410010); // Status word
        wsum += write32(1, 0x1A00, 2, 0x60640020); // Position actual value
        wsum += write32(1, 0x1A00, 3, 0x606C0020); // Velocity actual value
        //wsum += write32(1, 0x1A00, 4, 0x60770010); // Torque actual value
        wsum += write8 (1, 0x1A00, 0, 3);
        wsum += write16(1, 0x1C13, 1, 0x1A00);
        wsum += write8 (1, 0x1C13, 0, 1);

...

Attached are the wireshark files for the two above cases and also for the control run using codesys.

Best regards,

Urban

wireshark_PDOassignment_issue.zip

ArthurKetels commented 5 years ago

Actually it is strange the 3 RxPDO case does work. The issue is that you start transmitting LRW command (process data exchange) 107ms after you set the slave to OP. The common time-out on most slaves is 100ms. And with the 4 RxPDO you trigger this time-out. So my guess is that there are some internal slave delay's that make this case sometimes work and sometimes not.

The solution is to start your process data task when transitioning from pre-op to safe-op. This is the recommended master behavior.

The RxPDO mapping works fine in both cases. The slave transitions from pre-op to safe-op without any error. This indicates that the mapping is accepted on the slave.

urban-eriksson commented 5 years ago

Thanks for the feedback Arthur! Unfortunately this 100ms was in one of my testscripts, but it seems like my HIWIN servo is quite patient, removing this delay did not change any behaviour. I have done some further investigations today. The error does not depend on the number of objects used. I could change so that I had two 16-bit objects instead of one 32-bit and it works fine even when the total number of objects if four. I also checked that the SOEM reports the correct number of bits for output and input when setting up the IOmap, e.g. when Osize:32 and Isize:96 there is an error, while for Osize:32 and Isize:80 there is no error. The servo manual says output and input could be up to 20 bytes each so it should not be a problem I think. Furthermore the error is appearing when I do the ec_send_processdata() the first time. I can notice that by a red blinking LED on the servo amplifier. I have then tried to find the source of the inconsistency, after all the same setup of PDO:s work on the codesys software. One thing I tried to do was to break up the LRW in the send process data to one LRD and one LWR, but that did not have any effect. Please let me know if you need any more details.

ArthurKetels commented 5 years ago

When your slave goes into error state please print the ALstatuscode. You can use this code snippet from simple_test.c :

                ec_readstate();
                for(i = 1; i<=ec_slavecount ; i++)
                {
                    if(ec_slave[i].state != EC_STATE_OPERATIONAL)
                    {
                        printf("Slave %d State=0x%2.2x StatusCode=0x%4.4x : %s\n",
                            i, ec_slave[i].state, ec_slave[i].ALstatuscode, ec_ALstatuscode2string(ec_slave[i].ALstatuscode));
                    }
                }

I hope this slave will give a reason why it refuses to stay in OP.

urban-eriksson commented 5 years ago

When everything is ok:

Slave 1 State=0x08 StatusCode=0x0000 : No error

When error:

Slave 1 State=0x12 StatusCode=0x001d : Invalid output configuration

The "slaveinfo -map" looks like this when run after I have done the configuration that does not work:

SOEM (Simple Open EtherCAT Master)
Slaveinfo
Starting slaveinfo
ec_init on enp0s31f6 succeeded.
  CoE Osize:32 Isize:96
1 slaves found and configured.
Calculated workcounter 3

Slave:1
 Name:D2 CoE Drive
 Output size: 32bits
 Input size: 96bits
 State: 4
 Delay: 0[ns]
 Has DC: 1
 DCParentport:0
 Activeports:0.1.0.0
 Configured address: 1001
 Man: 0000aaaa ID: 00000003 Rev: 00000004
 SM0 A:1800 L:  20 F:00010026 Type:1
 SM1 A:18f6 L:  20 F:00010022 Type:2
 SM2 A:1000 L:   4 F:00010064 Type:3
 SM3 A:1100 L:  12 F:00010020 Type:4
 FMMU0 Ls:00000000 Ll:   4 Lsb:0 Leb:7 Ps:1000 Psb:0 Ty:02 Act:01
 FMMU1 Ls:00000004 Ll:  12 Lsb:0 Leb:7 Ps:1100 Psb:0 Ty:01 Act:01
 FMMUfunc 0:1 1:2 2:3 3:0
 MBX length wr: 20 rd: 20 MBX protocols : 04
 CoE details: 0d 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] 0x6071:0x00 0x10
  SM3 inputs
     addr b   index: sub bitl data_type    name
  [0x0004.0] 0x6041:0x00 0x10
  [0x0006.0] 0x6064:0x00 0x20
  [0x000A.0] 0x606C:0x00 0x20
  [0x000E.0] 0x6077:0x00 0x10
End slaveinfo, close socket
End program
ArthurKetels commented 5 years ago

Could you post the ESI xml file of the drive? I could not find it on the Hiwin website. But from their EtherCAT manual I saw that there is no object 6077:00 defined. Could you try with 6078:00?

Statuscode 0x0012 signals that your PDO mapping is incorrect.

urban-eriksson commented 5 years ago

Here is the ESI file. For some reason you need to register with Hiwin and login to access that. D2COE_20160711.zip The actual torque is for sure the 6077 object, it responds to manual input on the servo axis (I tried also with 6078 also but no interesting results). It's strange because I get a similar error "Invalid input configuration" when I exceed 80 bits for the for the PDO input region also. I tried to go through and compare with the codesys wireshark dump, but I can't see any relevant difference in the mailbox communication. I don't know if there are other ways of configuration which are harder to spot.

ArthurKetels commented 5 years ago

I did find one important configuration item. In the ESI file there is the 6060:00 object that need to be set at pre-op to safe-op transition. The codesys does this object download (follows ESI directions) but in SOEM you have to do that manually. In line 31543 of the codesys wireshark capture it set the object to value 0x0a. This value is CST mode. See Hiwin EtherCAT manual.

It could be the slave checks the PDO mapping with the drive mode and complains if it does not match.

urban-eriksson commented 5 years ago

I am setting the 6060:00 object to CST (=0x0a) with SOEM also, so it should not be any difference there. I mean otherwise it would not be possible to operate with the torque mode at all, but it works fine. It is just that I want to be able to read out the actual value of the position, velocity and torque at the same time. Maybe the next step is to go through the wireshark logs in detail, but it will probably take some while to do it. I will look into that the coming week. Let me know if you have any suggestions what to look for.

nakarlsson commented 5 years ago

Can we close this?

urban-eriksson commented 5 years ago

Yes, I will not work any more on this. Never found any solution though.