[etherlab-users] Problem With Maxon EPOS3

Henry Bausley hbausley at deltatau.com
Tue Oct 8 22:24:12 CEST 2013


Perhaps the slave doesn't work with LRW.  Issue ethercat slave -p0  -v
and see if Enable notLRW: yes.  If this is the case try using seperate
domains for the output and input so that LRD and LWR are used instead.  


ie.

    domainOutput = ecrt_master_create_domain(master);
    domainInput  = ecrt_master_create_domain(master);


    ecrt_domain_reg_pdo_entry_list(domainOutput domainOutput_regs)
    ecrt_domain_reg_pdo_entry_list(domainInput domainInput_regs)



On Tue, 2013-10-08 at 15:09 +0000, Laurent B. wrote:
> Hi,
> i would like to test an EPOS3 Drive from maxon with EtherCAT Master.
> I have a ubuntu 12.04 with 3.2 Kernel patches with RT_PREEMPT.
> I conenct the EPOS3 on ethernet port, and I got the following PDO structure 
> 
> 
> /* Master 0, Slave 0, "EPOS3"
>  * Vendor ID:       0x000000fb
>  * Product code:    0x64400000
>  * Revision number: 0x22100000
>  */
> 
> ec_pdo_entry_info_t slave_0_pdo_entries[] = {
>     {0x6040, 0x00, 16}, /* 0x6040:00 */
>     {0x607a, 0x00, 32}, /* 0x607A:00 */
>     {0x60b0, 0x00, 32}, /* 0x60B0:00 */
>     {0x60b1, 0x00, 32}, /* 0x60B1:00 */
>     {0x60b2, 0x00, 16}, /* 0x60B2:00 */
>     {0x6060, 0x00, 8}, /* 0x6060:00 */
>     {0x2078, 0x01, 16}, /* 0x2078:01 */
>     {0x60b8, 0x00, 16}, /* 0x60B8:00 */
>     {0x6041, 0x00, 16}, /* 0x6041:00 */
>     {0x6064, 0x00, 32}, /* 0x6064:00 */
>     {0x606c, 0x00, 32}, /* 0x606C:00 */
>     {0x6077, 0x00, 16}, /* 0x6077:00 */
>     {0x6061, 0x00, 8}, /* 0x6061:00 */
>     {0x2071, 0x01, 16}, /* 0x2071:01 */
>     {0x60b9, 0x00, 16}, /* 0x60B9:00 */
>     {0x60ba, 0x00, 32}, /* 0x60BA:00 */
>     {0x60bb, 0x00, 32}, /* 0x60BB:00 */
> };
> 
> ec_pdo_info_t slave_0_pdos[] = {
>     {0x1600, 8, slave_0_pdo_entries + 0}, /* 1st receive PDO Mapping */
>     {0x1a00, 9, slave_0_pdo_entries + 8}, /* 1st transmit PDO Mapping */
> };
> 
> ec_sync_info_t slave_0_syncs[] = {
>     {0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
>     {1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
>     {2, EC_DIR_OUTPUT, 1, slave_0_pdos + 0, EC_WD_ENABLE},
>     {3, EC_DIR_INPUT, 1, slave_0_pdos + 1, EC_WD_DISABLE},
>     {0xff}
> };
> 
> 
> after i wrote a simple program in C (user space) only to Enable the drive,
> but I can read PDO but I can not write to PDO.
> 
> Here after my program
> #include <sys/io.h>
> #include <errno.h>
> #include <signal.h>
> #include <stdio.h>
> #include <string.h>
> #include <sys/resource.h>
> #include <sys/time.h>
> #include <sys/types.h>
> #include <unistd.h>
> #include <time.h>
> #include <sys/mman.h>
> #include <malloc.h>
> 
> /****************************************************************************/
> 
> #include "ecrt.h"
> 
> /****************************************************************************/
> 
> // Application parameters
> #define FREQUENCY 1000
> #define CLOCK_TO_USE CLOCK_REALTIME
> #define MEASURE_TIMING 0
> 
> /****************************************************************************/
> 
> #define NSEC_PER_SEC (1000000000L)
> #define PERIOD_NS (NSEC_PER_SEC / FREQUENCY)
> 
> #define DIFF_NS(A, B) (((B).tv_sec - (A).tv_sec) * NSEC_PER_SEC + \
>     (B).tv_nsec - (A).tv_nsec)
> 
> #define TIMESPEC2NS(T) ((uint64_t) (T).tv_sec * NSEC_PER_SEC + (T).tv_nsec)
> 
> /****************************************************************************/
> 
> // EtherCAT
> static ec_master_t *master = NULL;
> static ec_master_state_t master_state = {};
> 
> static ec_domain_t *domain1 = NULL;
> static ec_domain_state_t domain1_state = {};
> 
> /****************************************************************************/
> 
> // process data
> static uint8_t *domain1_pd = NULL;
> 
> #define EPOS3_SlavePos  0, 0
> #define Maxon_EPOS3     0x000000fb, 0x64400000
> 
> // offsets for PDO entries
> static int EPOS3_0_Control_Word;
> static int EPOS3_0_Target_Position;
> static int EPOS3_0_Position_Offset;
> 
> static int EPOS3_0_Velocity_Offset;
> static int EPOS3_0_Torque_Offset;
> static int EPOS3_0_Operation_Mode;
> static int EPOS3_0_Digital_Output_funct;
> static int EPOS3_0_Touch_Probe_funct;
> 
> 
> static int EPOS3_0_Status_Word;
> static int EPOS3_0_Position_Actual;
> static int EPOS3_0_Velocity_Actual;
> static int EPOS3_0_Torque_Actual;
> static int EPOS3_0_Operation_Display_Mode;
> static int EPOS3_0_Digital_Input_funct;
> static int EPOS3_0_Touch_Probe_Status;
> static int EPOS3_0_Touch_Probe_Pos_pos;
> static int EPOS3_0_Touch_Probe_Pos_neg;
> const static ec_pdo_entry_reg_t domain1_regs[] =
> {
>     //RX_PDO
>     {EPOS3_SlavePos,Maxon_EPOS3,0x6040,0,&EPOS3_0_Control_Word},
> //Control_Word RW U16bit
>     {EPOS3_SlavePos,Maxon_EPOS3,0x607a,0,&EPOS3_0_Target_Position}, //Target
> Position RW I32bit
>     {EPOS3_SlavePos,Maxon_EPOS3,0x60b0,0,&EPOS3_0_Position_Offset}, //Torque
> Offset RW I32bit
>     {EPOS3_SlavePos,Maxon_EPOS3,0x60b1,0,&EPOS3_0_Velocity_Offset}, //Torque
> Offset RW I32bit
>     {EPOS3_SlavePos,Maxon_EPOS3,0x60b2,0,&EPOS3_0_Torque_Offset}, //Torque
> Offset RW I16bit
>     {EPOS3_SlavePos,Maxon_EPOS3,0x6060,0,&EPOS3_0_Operation_Mode}, //Modes
> of operation RW I8bit
>     {EPOS3_SlavePos,Maxon_EPOS3,0x2078,1,&EPOS3_0_Digital_Output_funct},
> //Digital output functionalities RW U16bit
>     {EPOS3_SlavePos,Maxon_EPOS3,0x60B8,0,&EPOS3_0_Touch_Probe_funct},
>     //TX_PDO
>     {EPOS3_SlavePos,Maxon_EPOS3,0x6041,0,&EPOS3_0_Status_Word}, //Status
> word RO U16bit
>     {EPOS3_SlavePos,Maxon_EPOS3,0x6064,0,&EPOS3_0_Position_Actual},
> //Position actual value RO I32bit
>     {EPOS3_SlavePos,Maxon_EPOS3,0x606c,0,&EPOS3_0_Velocity_Actual},
> //Velocity actual value RO I32bit
>     {EPOS3_SlavePos,Maxon_EPOS3,0x6077,0,&EPOS3_0_Torque_Actual}, //Torque
> actual value RO I16bit
>     {EPOS3_SlavePos,Maxon_EPOS3,0x6061,0,&EPOS3_0_Operation_Display_Mode},
> //Modes of operation display RO I8bit
>     {EPOS3_SlavePos,Maxon_EPOS3,0x2071,1,&EPOS3_0_Digital_Input_funct},
> //Digital Input functionalities RO record
>     {EPOS3_SlavePos,Maxon_EPOS3,0x60B9,0,&EPOS3_0_Touch_Probe_Status},
>     {EPOS3_SlavePos,Maxon_EPOS3,0x60BA,0,&EPOS3_0_Touch_Probe_Pos_pos},
>     {EPOS3_SlavePos,Maxon_EPOS3,0x60BB,0,&EPOS3_0_Touch_Probe_Pos_neg},
>     {}
> };
> /* Master 0, Slave 0, "EPOS3"
>  * Vendor ID:       0x000000fb
>  * Product code:    0x64400000
>  * Revision number: 0x22100000
>  */
> 
> ec_pdo_entry_info_t EPOS3_0_pdo_entries[] = {
>     {0x6040, 0x00, 16}, /* 0x6040:00 */ // control word 16
>     {0x607a, 0x00, 32}, /* 0x607A:00 */ // Target position 32
>     {0x60b0, 0x00, 32}, /* 0x60B0:00 */ //position offset 32
>     {0x60b1, 0x00, 32}, /* 0x60B1:00 */ //velocity offset 32
>     {0x60b2, 0x00, 16}, /* 0x60B2:00 */ // torque offset 16
>     {0x6060, 0x00, 8}, /* 0x6060:00 */ // modes of operations 8
>     {0x2078, 0x01, 16}, /* 0x2078:01 */ //digital output functionnalities
> state 16
>     {0x60b8, 0x00, 16}, /* 0x60B8:00 */ //16
>     {0x6041, 0x00, 16}, /* 0x6041:00 */ // Status word 16
>     {0x6064, 0x00, 32}, /* 0x6064:00 */ // position actual value 32
>     {0x606c, 0x00, 32}, /* 0x606C:00 */ // velocity actual value 32
>     {0x6077, 0x00, 16}, /* 0x6077:00 */ // torque actual value 16
>     {0x6061, 0x00, 8}, /* 0x6061:00 */  // 8
>     {0x2071, 0x01, 16}, /* 0x2071:01 */ // digital input functionalities
> state 16
>     {0x60b9, 0x00, 16}, /* 0x60B9:00 */ // 16
>     {0x60ba, 0x00, 32}, /* 0x60BA:00 */ //
>     {0x60bb, 0x00, 32}, /* 0x60BB:00 */
> };
> 
> ec_pdo_info_t EPOS3_0_pdos[] = {
>     {0x1600, 8, EPOS3_0_pdo_entries + 0}, /* 1st receive PDO Mapping */
>     {0x1a00, 9, EPOS3_0_pdo_entries + 8}, /* 1st transmit PDO Mapping */
> };
> 
> ec_sync_info_t EPOS3_0_syncs[] = {
>     {0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
>     {1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
>     {2, EC_DIR_OUTPUT, 1, EPOS3_0_pdos + 0, EC_WD_ENABLE},
>     {3, EC_DIR_INPUT, 1, EPOS3_0_pdos + 1, EC_WD_DISABLE},
>     {0xff}
> };
> 
> static unsigned int counter = 0;
> static unsigned int blink = 0;
> static unsigned int sync_ref_counter = 0;
> const struct timespec cycletime = {0, PERIOD_NS};
> 
> /*****************************************************************************/
> 
> struct timespec timespec_add(struct timespec time1, struct timespec time2)
> {
>     struct timespec result;
> 
>     if ((time1.tv_nsec + time2.tv_nsec) >= NSEC_PER_SEC) {
>         result.tv_sec = time1.tv_sec + time2.tv_sec + 1;
>         result.tv_nsec = time1.tv_nsec + time2.tv_nsec - NSEC_PER_SEC;
>     } else {
>         result.tv_sec = time1.tv_sec + time2.tv_sec;
>         result.tv_nsec = time1.tv_nsec + time2.tv_nsec;
>     }
> 
>     return result;
> }
> 
> /*****************************************************************************/
> 
> void check_domain1_state(void)
> {
>     ec_domain_state_t ds;
> 
>     ecrt_domain_state(domain1, &ds);
> 
>     if (ds.working_counter != domain1_state.working_counter)
>         printf("Domain1: WC %u.\n", ds.working_counter);
>     if (ds.wc_state != domain1_state.wc_state)
>         printf("Domain1: State %u.\n", ds.wc_state);
> 
>     domain1_state = ds;
> }
> 
> /*****************************************************************************/
> 
> void check_master_state(void)
> {
>     ec_master_state_t ms;
> 
>     ecrt_master_state(master,&ms);
> 
>     if (ms.slaves_responding != master_state.slaves_responding)
>         printf("master state=> %u slave(s). \n", ms.slaves_responding);
> 
>     if(ms.al_states != master_state.al_states)
>     {
>         switch(ms.al_states)
>         {
>         case EC_AL_STATE_INIT:
>             printf("master state is INIT.\n");
>             break;
>         case EC_AL_STATE_PREOP:
>             printf("master state is PREOP.\n");
>             break;
>         case EC_AL_STATE_SAFEOP:
>             printf("master state is SAFEOP.\n");
>             break;
>         case EC_AL_STATE_OP:
>             printf("master state is OP now.\n");
>             break;
>         default:
>             printf("master state unknown.\n");
>             break;
>         }
>     }
>     if(ms.link_up != master_state.link_up)
>         printf("master state=>Link is %s .\n", ms.link_up ? "up" : "down");
> 
>     master_state = ms;
> }
> 
> /****************************************************************************/
> 
> void cyclic_task()
> {
>     struct timespec wakeupTime, time;
>     uint16_t status, mode =0;
>     // get current time
>     clock_gettime(CLOCK_TO_USE, &wakeupTime);
> 
>     while(1) {
>         wakeupTime = timespec_add(wakeupTime, cycletime);
>         clock_nanosleep(CLOCK_TO_USE, TIMER_ABSTIME, &wakeupTime, NULL);
> 
>         ecrt_master_receive(master);
>         // receive process data
>         ecrt_domain_process(domain1);
> 
>         // check process data state (optional)
>         check_domain1_state();
> 
>         if (counter)
>         {
>             counter--;
>         }
>         else
>         { // do this at 1 Hz
>             counter = FREQUENCY;
> 
>             // check for master state (optional)
>             check_master_state();
> 
> 
>             // calculate new process data
>             blink = !blink;
>         }
> 
> 
>         // write process data
>         switch(master_state.al_states)
>         {
>         case EC_AL_STATE_INIT:
> 
>             break;
>         case EC_AL_STATE_PREOP:
> 
>             break;
>         case EC_AL_STATE_SAFEOP:
> 
>             break;
>         case EC_AL_STATE_OP:
>             status = EC_READ_U16(domain1_pd + EPOS3_0_Status_Word);
>             switch(mode)
>             {
>             case 0:
>                 if (status == 0x0140 )
>                 {
>                     printf("EPOS3_0 Status Word = %d \n",status);
>                     EC_WRITE_U16(domain1_pd+EPOS3_0_Control_Word, 0x0006);
>                     mode = 1;
>                 }
>                 break;
>             case 1:
>                 if ( status == 0x0121)
>                 {
>                     printf("EPOS3_0 Status Word = %d \n",status);
>                     EC_WRITE_U16(domain1_pd+EPOS3_0_Control_Word, 0x000F);
>                     mode = 2;
>                 }
> 
>                 break;
>             default:
>                 break;
>             }
>             break;
>         }
> 
>         // write application time to master
>         clock_gettime(CLOCK_TO_USE, &time);
>         ecrt_master_application_time(master, TIMESPEC2NS(time));
> 
>         if (sync_ref_counter)
>         {
>             sync_ref_counter--;
>         }
>         else
>         {
>             sync_ref_counter = 1; // sync every cycle
>             ecrt_master_sync_reference_clock(master);
>         }
>         ecrt_master_sync_slave_clocks(master);
>         // send process data
>         ecrt_domain_queue(domain1);
>         ecrt_master_send(master);
> 
> 
>     }
> }
> 
> /****************************************************************************/
> 
> int main(void)
> {
>     ec_slave_config_t *sc;
> 
>     if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1)
>     {
>         perror("mlockall failed");
>         return -1;
>     }
>     iopl(3);
>     master = ecrt_request_master(0);
>     if (!master)
>         return -1;
> 
>     domain1 = ecrt_master_create_domain(master);
>     if (!domain1)
>         return -1;
> 
>     // Create configuration for bus coupler
> 
>     if (!(sc = ecrt_master_slave_config(master,
>                                         EPOS3_SlavePos,
>                                         Maxon_EPOS3)))
>     {
>         fprintf(stderr, "Failed to get slave configuration.\n");
>         return -1;
>     }
>     sc = ecrt_master_slave_config(master, EPOS3_SlavePos, Maxon_EPOS3);
>     if(!sc)
>     {
>         printf("Failed to get EPOS3_0 slave configuration... \n");
>         return -1;
>     }
> 
>     if(ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs))
>     {
>         printf("Failed to register PDO entries.\n");
>         return -1;
>     }
> 
>     printf("Activating master...\n");
>     if (ecrt_master_activate(master))
>         return -1;
> 
>     if (!(domain1_pd = ecrt_domain_data(domain1)))
>     {
>         return -1;
>     }
> 
>     pid_t pid = getpid();
>     if (setpriority(PRIO_PROCESS, pid, -19))
>         fprintf(stderr, "Warning: Failed to set priority: %s\n",
>                 strerror(errno));
>     printf("Starting cyclic function.\n");
>     cyclic_task();
> 
>     return 0;
> }
> 
> I check dmesg :
> [609034.495106] EtherCAT 0: Link state of ecm0 changed to UP.
> [609034.499351] EtherCAT 0: 1 slave(s) responding on main device.
> [609034.499355] EtherCAT 0: Slave states on main device: INIT.
> [609034.499462] EtherCAT 0: Scanning bus.
> [609034.535463] EtherCAT 0: Bus scanning completed in 36 ms.
> [609034.535468] EtherCAT 0: Using slave 0 as DC reference clock.
> [609034.539485] EtherCAT 0: Slave states on main device: PREOP.
> [609034.615408] EtherCAT: Requesting master 0...
> [609034.615413] EtherCAT: Successfully requested master 0.
> [609034.615498] EtherCAT 0: Domain0: Logical address 0x00000000, 46 byte,
> expected working counter 3.
> [609034.615502] EtherCAT 0:   Datagram domain0-0-main: Logical offset
> 0x00000000, 46 byte, type LRW.
> [609034.619179] EtherCAT 0: Master thread exited.
> [609034.619186] EtherCAT 0: Starting EtherCAT-OP thread.
> [609034.619332] EtherCAT WARNING 0: 122 datagrams TIMED OUT!
> [609034.724335] EtherCAT ERROR 0-0: SDO download 0x1600:03 (4 bytes) aborted.
> [609034.724342] EtherCAT ERROR 0-0: SDO abort message 0x08000021: "Data
> cannot be transferred or stored to the application because of local control".
> [609034.724347] EtherCAT WARNING 0-0: Failed to map PDO entry 0x60B0:00 (32
> bit) to position 3.
> [609034.724349] EtherCAT WARNING 0-0: Currently mapped PDO entries:
> 0x6040:00/16 0x607A:00/32 0x60B0:00/32 0x60B1:00/32 0x60B2:00/16 0x6060:00/8
> 0x2078:01/16 0x60B8:00/16. Entries to map: 0x6040:00/16 0x607A:00/32
> 0x60B0:00/32 0x60B1:00/32 0x60B2:00/16 0x6060:00/8 0x2078:01/16 0x60B8:00/16
> [609034.724381] EtherCAT WARNING 0-0: Failed to configure mapping of PDO 0x1600.
> [609034.833512] EtherCAT ERROR 0-0: SDO download 0x1A00:05 (4 bytes) aborted.
> [609034.833518] EtherCAT ERROR 0-0: SDO abort message 0x08000021: "Data
> cannot be transferred or stored to the application because of local control".
> [609034.833523] EtherCAT WARNING 0-0: Failed to map PDO entry 0x6061:00 (8
> bit) to position 5.
> [609034.833525] EtherCAT WARNING 0-0: Currently mapped PDO entries:
> 0x6041:00/16 0x6064:00/32 0x606C:00/32 0x6077:00/16 0x6061:00/8 0x2071:01/16
> 0x60B9:00/16 0x60BA:00/32 0x60BB:00/32. Entries to map: 0x6041:00/16
> 0x6064:00/32 0x606C:00/32 0x6077:00/16 0x6061:00/8 0x2071:01/16 0x60B9:00/16
> 0x60BA:00/32 0x60BB:00/32
> [609034.833560] EtherCAT WARNING 0-0: Failed to configure mapping of PDO 0x1A00.
> [609034.883167] EtherCAT 0: Domain 0: Working counter changed to 3/3.
> [609034.898343] EtherCAT 0: Slave states on main device: OP.
> [609036.844657] EtherCAT 0: Releasing master...
> [609036.847192] EtherCAT 0: Master thread exited.
> [609036.847210] EtherCAT 0: Starting EtherCAT-IDLE thread.
> [609036.847337] EtherCAT 0: Released.
> [609036.847373] EtherCAT 0: 0 slave(s) responding on main device.
> [609036.851441] EtherCAT 0: 1 slave(s) responding on main device.
> [609036.851445] EtherCAT 0: Slave states on main device: OP.
> [609036.851552] EtherCAT 0: Scanning bus.
> [609036.886690] EtherCAT 0: Bus scanning completed in 36 ms.
> [609036.886695] EtherCAT 0: Using slave 0 as DC reference clock.
> [609036.905371] EtherCAT 0: Slave states on main device: PREOP.
> [609037.285909] EtherCAT WARNING: Datagram ffff8800a253c678 (master-fsm) was
> SKIPPED 1 time.
> 
> Probably i do something wrong during configuration, but I don't known ?
> Anybody could help me ?
> 
> 
> _______________________________________________
> etherlab-users mailing list
> etherlab-users at etherlab.org
> http://lists.etherlab.org/mailman/listinfo/etherlab-users





Outbound scan for Spam or Virus by Barracuda at Delta Tau




More information about the Etherlab-users mailing list