[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