IGH(ethercat)命令行不能进入OP原因

     问题:在使用IGH操作清能德创伺服的时候,使用命名行ethercat states OP,该命令不能使从站进入OP模式,还会报错。

IGH(ethercat)命令行不能进入OP原因_第1张图片

 原因:经过反复测试后,发现是在第二步ethercat config中没有使主站获得伺服配置。

步骤1:需要编辑一个小程序,是主站获得伺服配置

   sc_cooldrive=ecrt_master_slave_config(master,CoolDrivePos0,CoolDrive); 使主站获得伺服0配置
    sc_cooldrive=ecrt_master_slave_config(master,CoolDrivePos1,CoolDrive);       ; 使主站获得伺服1配置
    //check_slave_config_states();
    printf("master_reset,Retry configuring slaves.\n");
    ecrt_master_reset(master); 重启主站
    check_slave_config_states();

/** Retry configuring slaves.
 *重试配置从站
 * Via this method, the application can tell the master to bring all slaves to
 * OP state. In general, this is not necessary, because it is automatically
 * done by the master. But with special slaves, that can be reconfigured by
 * the vendor during runtime, it can be useful.
 *通过这个方法,应用程序可以告诉主站将所有从站设置为OP状态。一般来说,
 *这是不必要的,因为它是由主程序自动完成的。但是对于特殊的从站(可以由供应商
 *在运行时重新配置),它可能很有用。
 */

//$CC test_noPDO.c -o ectest_noPDO -L /home/lee/igh-mc -lethercat
//scp ectest_noPDO [email protected]:/home/mc
#include "config_qn.h"

void check_master_state(void)
{
    ec_master_state_t ms;

    ecrt_master_state(master, &ms);

    if (ms.slaves_responding != master_state.slaves_responding) {
        printf("found %u slave(s).\n", ms.slaves_responding);
    }
    if (ms.al_states != master_state.al_states) {
        printf("AL states: 0x%02X.\n", ms.al_states);
    }
    if (ms.link_up != master_state.link_up) {
        printf("Link is %s.\n", ms.link_up ? "up" : "down");
    }

    master_state = ms;
}

/*****************************************************************************/

void check_slave_config_states(void)
{
    ec_slave_config_state_t s;

    ecrt_slave_config_state(sc_cooldrive, &s);

    if (s.al_state != sc_cooldrive_state.al_state) {
        printf("CoolDrive: State 0x%02X.\n", s.al_state);
    }
    if (s.online != sc_cooldrive_state.online) {
        printf("CoolDrive: %s.\n", s.online ? "online" : "offline");
    }
    if (s.operational != sc_cooldrive_state.operational) {
        printf("CoolDrive: %soperational.\n", s.operational ? "yes" : "Not ");
    }

    sc_cooldrive_state = s;
}

/*****************************************************************************/

void check_domain1_state(void)
{
    ec_domain_state_t ds;

    ecrt_domain_state(domainServoInput, &ds);

    if (ds.working_counter != domainServoInput_state.working_counter) {
        printf("Domain1: WC %u.\n", ds.working_counter);
    }
    if (ds.wc_state != domainServoInput_state.wc_state) {
        printf("Domain1: State %u.\n", ds.wc_state);
    }

    domainServoInput_state = ds;
}

/*****************************************************************************/


int main(void)
{
    
    master = ecrt_request_master(0);
    if (!master) {
        return -1;
    }
    printf("request_master sucess\n");
    check_master_state();
    
    //printf("config PDO\n");
    sc_cooldrive=ecrt_master_slave_config(master,CoolDrivePos0,CoolDrive); 
    sc_cooldrive=ecrt_master_slave_config(master,CoolDrivePos1,CoolDrive);       
    //check_slave_config_states();
    printf("master_reset,Retry configuring slaves.\n");
    ecrt_master_reset(master); 
    check_slave_config_states();
    pause();
    printf("release_master\n");
    ecrt_release_master(master);
    
    return 0;
}

步骤2:交叉编译并传送到开发板

//$CC test_noPDO.c -o ectest_noPDO -L /home/lee/igh-mc -lethercat
//scp ectest_noPDO [email protected]:/home/mc

 

IGH(ethercat)命令行不能进入OP原因_第2张图片

步骤3:登录开发板运行

ssh [email protected]

cd /home/mc

./ectest_noPDO

IGH(ethercat)命令行不能进入OP原因_第3张图片

步骤4:在开发板再登录一个窗口测试命令行

IGH(ethercat)命令行不能进入OP原因_第4张图片

发现可以自由切换伺服从站的操作状态。

如果关掉ectest_noPDO,则ethercat config 命令没有内容。不能使用命令行ethercat states切换主站状态。

另外,config_qn.h中定义的变量可以参考igh1.5.2官方给的例子自己补充。 类似如下:

 

#include
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include  /* clock_gettime() */
#include  /* mlockall() */
#include  /* sched_setscheduler() */

#include"ecrt.h"

/****************************************************************************/

/** Task period in ns. */
#define PERIOD_NS   (1000000)

#define MAX_SAFE_STACK (8 * 1024) /* The maximum stack size which is
                                     guranteed safe to access without
                                     faulting */

/****************************************************************************/

/* Constants */
#define NSEC_PER_SEC (1000000000)
#define FREQUENCY (NSEC_PER_SEC / PERIOD_NS)

/****************************************************************************/

// EtherCAT
static ec_master_t *master = NULL;
static ec_master_state_t master_state = {};

static ec_domain_t *domainServoInput = NULL;
static ec_domain_state_t domainServoInput_state = {};
static ec_domain_t *domainServoOutput = NULL;
static ec_domain_state_t domainServoOutput_state = {};

static uint8_t *domainOutput_pd = NULL;
static uint8_t *domainInput_pd = NULL;

static ec_slave_config_t *sc_cooldrive = NULL;
static ec_slave_config_state_t sc_cooldrive_state = {};

/****************************************************************************/

// process data
#define CoolDrivePos0  1, 0
#define CoolDrivePos1  2, 1

#define CoolDrive 0x00000748, 0x0000000a


// offsets for PDO entries
static unsigned int  cntlwd1,cntlwd2,cntlwd3,cntlwd4;
static unsigned int  tarpos1,tarpos2,tarpos3,tarpos4;
static unsigned int  modper1,modper2,modper3,modper4;
static unsigned int  DB1_1,DB1_2,DB1_3,DB1_4;
static unsigned int  status1,status2,status3,status4;
static unsigned int  actpos1,actpos2,actpos3,actpos4;
static unsigned int  acttor1,acttor2,acttor3,acttor4;
static unsigned int  moddis1,moddis2,moddis3,moddis4;
static unsigned int  DB2_1,DB2_2,DB2_3,DB2_4;
static unsigned int  errcode1,errcode2,errcode3,errcode4;
static unsigned int  errflo1,errflo2,errflo3,errflo4;

static int cur_status;
static int cur_mode;
// process data
ec_pdo_entry_reg_t domainServoOutput_regs[] = {
    {CoolDrivePos0, CoolDrive, 0x6040, 0x00, &cntlwd1, NULL},
    {CoolDrivePos0, CoolDrive, 0x607a, 0x00, &tarpos1, NULL},
    {CoolDrivePos0, CoolDrive, 0x6060, 0x00, &modper1, NULL},
    {CoolDrivePos0, CoolDrive, 0x27fe, 0x00, &DB1_1, NULL},
    {CoolDrivePos0, CoolDrive, 0x6840, 0x00, &cntlwd2, NULL},
    {CoolDrivePos0, CoolDrive, 0x687a, 0x00, &tarpos2, NULL},
    {CoolDrivePos0, CoolDrive, 0x6860, 0x00, &modper2, NULL},
    {CoolDrivePos0, CoolDrive, 0x2ffe, 0x00, &DB1_2, NULL},
    {CoolDrivePos1, CoolDrive, 0x6040, 0x00, &cntlwd3, NULL},
    {CoolDrivePos1, CoolDrive, 0x607a, 0x00, &tarpos3, NULL},
    {CoolDrivePos1, CoolDrive, 0x6060, 0x00, &modper3, NULL},
    {CoolDrivePos1, CoolDrive, 0x27fe, 0x00, &DB1_3, NULL},
    {CoolDrivePos1, CoolDrive, 0x6840, 0x00, &cntlwd4, NULL},
    {CoolDrivePos1, CoolDrive, 0x687a, 0x00, &tarpos4, NULL},
    {CoolDrivePos1, CoolDrive, 0x6860, 0x00, &modper4, NULL},
    {CoolDrivePos1, CoolDrive, 0x2ffe, 0x00, &DB1_4, NULL},
    {}
};
ec_pdo_entry_reg_t domainServoInput_regs[] = {
    {CoolDrivePos0, CoolDrive, 0x6041, 0x00, &status1, NULL},
    {CoolDrivePos0, CoolDrive, 0x6064, 0x00, &actpos1, NULL},
    {CoolDrivePos0, CoolDrive, 0x6077, 0x00, &acttor1, NULL},    
    {CoolDrivePos0, CoolDrive, 0x6061, 0x00, &moddis1, NULL},
    {CoolDrivePos0, CoolDrive, 0x27ff, 0x00, &DB2_1, NULL},
    {CoolDrivePos0, CoolDrive, 0x603f, 0x00, &errcode1, NULL},
    {CoolDrivePos0, CoolDrive, 0x60f4, 0x00, &errflo1, NULL},
    {CoolDrivePos0, CoolDrive, 0x6841, 0x00, &status2, NULL},
    {CoolDrivePos0, CoolDrive, 0x6864, 0x00, &actpos2, NULL},
    {CoolDrivePos0, CoolDrive, 0x6877, 0x00, &acttor2, NULL},    
    {CoolDrivePos0, CoolDrive, 0x6861, 0x00, &moddis2, NULL},
    {CoolDrivePos0, CoolDrive, 0x2fff, 0x00, &DB2_2, NULL},
    {CoolDrivePos0, CoolDrive, 0x683f, 0x00, &errcode2, NULL},
    {CoolDrivePos0, CoolDrive, 0x68f4, 0x00, &errflo2, NULL},
    {CoolDrivePos1, CoolDrive, 0x6041, 0x00, &status3, NULL},
    {CoolDrivePos1, CoolDrive, 0x6064, 0x00, &actpos3, NULL},
    {CoolDrivePos1, CoolDrive, 0x6077, 0x00, &acttor3, NULL},    
    {CoolDrivePos1, CoolDrive, 0x6061, 0x00, &moddis3, NULL},
    {CoolDrivePos1, CoolDrive, 0x27ff, 0x00, &DB2_3, NULL},
    {CoolDrivePos1, CoolDrive, 0x603f, 0x00, &errcode3, NULL},
    {CoolDrivePos1, CoolDrive, 0x60f4, 0x00, &errflo3, NULL},
    {CoolDrivePos1, CoolDrive, 0x6841, 0x00, &status4, NULL},
    {CoolDrivePos1, CoolDrive, 0x6864, 0x00, &actpos4, NULL},
    {CoolDrivePos1, CoolDrive, 0x6877, 0x00, &acttor4, NULL},    
    {CoolDrivePos1, CoolDrive, 0x6861, 0x00, &moddis4, NULL},
    {CoolDrivePos1, CoolDrive, 0x2fff, 0x00, &DB2_4, NULL},
    {CoolDrivePos1, CoolDrive, 0x683f, 0x00, &errcode4, NULL},
    {CoolDrivePos1, CoolDrive, 0x68f4, 0x00, &errflo4, NULL},
    {}
};


/* Master 0, Slave 0, "CoolDrive RD"
 * Vendor ID:       0x00000748
 * Product code:    0x0000000a
 * Revision number: 0x00000002
 */

ec_pdo_entry_info_t slave_0_pdo_entries[] = {
    {0x6040, 0x00, 16},
    {0x607a, 0x00, 32},
    {0x6060, 0x00, 8},
    {0x27fe, 0x00, 8},
    {0x6840, 0x00, 16},
    {0x687a, 0x00, 32},
    {0x6860, 0x00, 8},
    {0x2ffe, 0x00, 8},
    {0x6041, 0x00, 16},
    {0x6064, 0x00, 32},
    {0x6077, 0x00, 16},
    {0x6061, 0x00, 8},
    {0x27ff, 0x00, 8},
    {0x603f, 0x00, 16},
    {0x60f4, 0x00, 32},
    {0x6841, 0x00, 16},
    {0x6864, 0x00, 32},
    {0x6877, 0x00, 16},
    {0x6861, 0x00, 8},
    {0x2fff, 0x00, 8},
    {0x683f, 0x00, 16},
    {0x68f4, 0x00, 32},
};

ec_pdo_info_t slave_0_pdos[] = {
    {0x1600, 4, slave_0_pdo_entries + 0},
    {0x1610, 4, slave_0_pdo_entries + 4},
    {0x1a00, 7, slave_0_pdo_entries + 8},
    {0x1a10, 7, slave_0_pdo_entries + 15},
};

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, 2, slave_0_pdos + 0, EC_WD_ENABLE},
    {3, EC_DIR_INPUT, 2, slave_0_pdos + 2, EC_WD_DISABLE},
    {0xff}
};

/* Master 0, Slave 1, "CoolDrive RD"
 * Vendor ID:       0x00000748
 * Product code:    0x0000000a
 * Revision number: 0x00000002
 */

ec_pdo_entry_info_t slave_1_pdo_entries[] = {
    {0x6040, 0x00, 16},
    {0x607a, 0x00, 32},
    {0x6060, 0x00, 8},
    {0x27fe, 0x00, 8},
    {0x6840, 0x00, 16},
    {0x687a, 0x00, 32},
    {0x6860, 0x00, 8},
    {0x2ffe, 0x00, 8},
    {0x6041, 0x00, 16},
    {0x6064, 0x00, 32},
    {0x6077, 0x00, 16},
    {0x6061, 0x00, 8},
    {0x27ff, 0x00, 8},
    {0x603f, 0x00, 16},
    {0x60f4, 0x00, 32},
    {0x6841, 0x00, 16},
    {0x6864, 0x00, 32},
    {0x6877, 0x00, 16},
    {0x6861, 0x00, 8},
    {0x2fff, 0x00, 8},
    {0x683f, 0x00, 16},
    {0x68f4, 0x00, 32},
};

ec_pdo_info_t slave_1_pdos[] = {
    {0x1600, 4, slave_1_pdo_entries + 0},
    {0x1610, 4, slave_1_pdo_entries + 4},
    {0x1a00, 7, slave_1_pdo_entries + 8},
    {0x1a10, 7, slave_1_pdo_entries + 15},
};

ec_sync_info_t slave_1_syncs[] = {
    {0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
    {1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
    {2, EC_DIR_OUTPUT, 2, slave_1_pdos + 0, EC_WD_ENABLE},
    {3, EC_DIR_INPUT, 2, slave_1_pdos + 2, EC_WD_DISABLE},
    {0xff}
};


/****************************************************************************/



/****************************************************************************/
/* Master 0, Slave 0, "ESTUN ProNet"
 * Vendor ID:       0x0000060a
 * Product code:    0x00000001
 * Revision number: 0x00000001
 */

ec_pdo_entry_info_t estun_pdo_entries[] = {
    //CoE CSP Mode (RX)
    {0x6040, 0x00, 16}, /* Controlword */
    {0x607a, 0x00, 32}, /* Target Position */
    {0x6060, 0x00, 8},  /*modes of operation*/
    {0x6098, 0x00, 8},  /*Homing method*/
    {0x6099, 0x01, 32},  /*Speed during search for switch*/
    {0x6099, 0x02, 32},  /*Speed during search for zero*/
    {0x609a, 0x00, 32},  /*homing_acceleration*/
    {0x607c, 0x00, 32},  /*home_offset*/
    //CoE CSP Mode (TX)
    {0x6041, 0x00, 16}, /* Statusword */
    {0x6064, 0x00, 32}, /* Position actual value */
    {0x6061, 0x00, 8},  /*modes of operation display*/
};

ec_pdo_info_t estun_pdos[] = {
    {0x1600, 8, estun_pdo_entries + 0}, /* CoE CSP Mode (RX) */
    {0x1a00, 3, estun_pdo_entries + 8}, /* CoE CSP Mode (TX) */
};

ec_sync_info_t estun_syncs[] = {
    {0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
    {1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
    {2, EC_DIR_OUTPUT, 1, estun_pdos + 0, EC_WD_ENABLE},
    {3, EC_DIR_INPUT, 1, estun_pdos + 1, EC_WD_DISABLE},
    {0xff}
};

/****************************************************************************/

// Analog in --------------------------

static ec_pdo_entry_info_t el3102_pdo_entries[] = {
    {0x3101, 1,  8}, // channel 1 status
    {0x3101, 2, 16}, // channel 1 value
    {0x3102, 1,  8}, // channel 2 status
    {0x3102, 2, 16}, // channel 2 value
    {0x6401, 1, 16}, // channel 1 value (alt.)
    {0x6401, 2, 16}  // channel 2 value (alt.)
};

static ec_pdo_info_t el3102_pdos[] = {
    {0x1A00, 2, el3102_pdo_entries},
    {0x1A01, 2, el3102_pdo_entries + 2}
};

static ec_sync_info_t el3102_syncs[] = {
    {2, EC_DIR_OUTPUT},
    {3, EC_DIR_INPUT, 2, el3102_pdos},
    {0xff}
};

// Analog out -------------------------

static ec_pdo_entry_info_t el4102_pdo_entries[] = {
    {0x3001, 1, 16}, // channel 1 value
    {0x3002, 1, 16}, // channel 2 value
};

static ec_pdo_info_t el4102_pdos[] = {
    {0x1600, 1, el4102_pdo_entries},
    {0x1601, 1, el4102_pdo_entries + 1}
};

static ec_sync_info_t el4102_syncs[] = {
    {2, EC_DIR_OUTPUT, 2, el4102_pdos},
    {3, EC_DIR_INPUT},
    {0xff}
};

// Digital out ------------------------

static ec_pdo_entry_info_t el2004_channels[] = {
    {0x3001, 1, 1}, // Value 1
    {0x3001, 2, 1}, // Value 2
    {0x3001, 3, 1}, // Value 3
    {0x3001, 4, 1}  // Value 4
};

static ec_pdo_info_t el2004_pdos[] = {
    {0x1600, 1, &el2004_channels[0]},
    {0x1601, 1, &el2004_channels[1]},
    {0x1602, 1, &el2004_channels[2]},
    {0x1603, 1, &el2004_channels[3]}
};

static ec_sync_info_t el2004_syncs[] = {
    {0, EC_DIR_OUTPUT, 4, el2004_pdos},
    {1, EC_DIR_INPUT},
    {0xff}
};

/*****************************************************************************/


你可能感兴趣的:(ethercat,开源主站IGH使用,p2p,linq,gnu)