[etherlab-users] Beckhoff EL7031

Graeme Foot Graeme.Foot at touchcut.com
Tue Oct 11 00:31:44 CEST 2016


Sure.  Have also cc'ed the forum in case anyone has anything else to add.

Some general notes:
- We only use EL7041's in production so have done limited testing on EL7031's but they are very similar.

- Make sure you've got the latest firmware on the module.  Some of the earlier firmwares motion was a little rough.

- I use the steppers in position controller mode (8012:01 = 3).  In this mode you need to set the target position of the motor every cycle.  It is up to you to calculate your own position / velocity profile.  Steppers don't like sudden movement so you need to ramp up and down the velocity by an acceleration, and you might also want to apply some jerk smoothing.

- I don't use the modules in Distributed Clock mode.  Never been able to make it work and never had time to figure out why.  Not too much of a problem for my situation.  If you find out how to use it successfully then let us know.

- Values that I read from a config file and set per module are:
  Max Current           (8010:01) -> set to suit motor
  Reduced Current       (8010:02) -> generally I set this to 1/2 of max current
  Nominal Voltage       (8010:03) -> this module only allows 24V
  Motor Coil Resistance (8010:04) -> set to suit motor
  Motor Full Steps      (8010:06) -> ours are 200
  Max Speed Range       (8012:05) -> generally set to 3 (2400 RPM for a 200 step / rev motor)
  Reversed              (8012:09) -> if the motor goes the wrong direction set this value
I set these values before activating the master switching my app to realtime.

I'm using the following pdo setup:

ec_pdo_entry_info_t EL7031_pdoEntries[] = {
    // 0x1602, stepper control (0)
    {0x7010, 0x01, 1},    // Enable
    {0x7010, 0x02, 1},    // Reset 
    {0x7010, 0x03, 1},    // Reduce torque 
    {0x0000, 0x00, 5},    //   spacer 
    {0x0000, 0x00, 8},    //   spacer 
    // 0x1603, stepper pos (5)
    {0x7010, 0x11, 32},   // Target position

    // 0x1a03, stepper status (6)
    {0x6010, 0x01, 1},    // Ready to enable 
    {0x6010, 0x02, 1},    // Ready 
    {0x6010, 0x03, 1},    // Warning 
    {0x6010, 0x04, 1},    // Error 
    {0x6010, 0x05, 1},    // Moving positive 
    {0x6010, 0x06, 1},    // Moving negative 
    {0x6010, 0x07, 1},    // Torque reduced 
    {0x0000, 0x00, 1},    //   spacer 
    {0x0000, 0x00, 3},    //   spacer
    {0x6010, 0x0c, 1},    // Digital input 1 
    {0x6010, 0x0d, 1},    // Digital input 2 
    {0x1c32, 0x20, 1},    // Sync error 
    {0x0000, 0x00, 1},    //   spacer 
    {0x1803, 0x09, 1},    // *** unknown ***

ec_pdo_info_t EL7031_pdos[] = {
    {0x1602, 5, EL7031_pdoEntries + 0},
    {0x1603, 1, EL7031_pdoEntries + 5},
    {0x1a03, 14, EL7031_pdoEntries + 6},

ec_sync_info_t EL7031_syncs[] = {
    {2, EC_DIR_OUTPUT, 2, EL7031_pdos + 0, EC_WD_DISABLE},
    {3, EC_DIR_INPUT, 1, EL7031_pdos + 2, EC_WD_DISABLE},

To initialise each module I call (Note: error checking not included):

  dev->slaveConfig = ecrt_master_slave_config(ecMod->master, dev->alias, dev->position,
                                              dev->vendorID, dev->productCode);

  ecrt_slave_config_pdos(dev->slaveConfig, EC_END, EL7031_syncs);

  dev->m_sdoErrorCode = ecrt_slave_config_create_sdo_request(dev->slaveConfig, 0xA010, 0x00, sizeof(uint8_t));

Then I configure each of the pdo entries so my app can use them, for each entry I call:

  offset = ecrt_slave_config_reg_pdo_entry(dev->slaveConfig, EL7031_pdoEntries[_pdoIdx].index,
                                           pdoEntries [_pdoIdx].subindex,
                                           ecMod->domains[_domIdx].domain, &bitPos);

Just before going realtime I ensure the Enable (7010:01) value is set to zero.

To enable a motor I use a state machine that checks for faults and allows for external brakes to be turned on/off etc.  But essentially I do:

  If enable is requested by the app, reset any current faults:
    Set FaultReset (7010:02) for a time (I set it for 500ms) then reset
    If ReadyToEnable (6010:01) then Set Enable (7010:01)
      Wait until the Ready (6010:02) input is set before letting the app use the motor

  Monitor the Error (6010:04) status, if there's any error then reset the Enable (7010:01) output and wait for the app to register the fault. 

If there's any Warning (6010:03) or Error (6010:04) then I check the diagnostic information.  This information is not available via the PDO's so you need to read it via an SDO.  You can either read each A010:01 - A010:0A subindex individually (which I currently do in a state machine) or you can read them using a complete access function call (requiring one of the complete access patches on the dev forum).  Note: this uses dev->m_sdoErrorCode from above.

Every cycle, set the motors TargetPosition (7010:11), even if its stationary.  Note: this module uses 64-fold micro-stepping.  This means that if your motor is 200 steps per rev, you need to control the TargetPosition with 12800 counts per rev (200 * 64).

And that's pretty much it.  The hard bits are getting the correct parameters for the motor and providing your own motion profile.

Have fun,

-----Original Message-----
From: Ewan Houston [mailto:e.houston.1 at research.gla.ac.uk] 
Sent: Tuesday, 11 October 2016 5:02 a.m.
To: Graeme Foot
Subject: Beckhoff EL7031


I am a PhD student at the university of Glasgow. I pulled your name from an ether lab thread that is about the EL7031. I hope you don't mind me being so bold, but how have you got on with programming it? Would you be willing and able to share any of your experience on that front?


Ally Houston.

More information about the Etherlab-users mailing list