This seems to be a common issue on this list. :)
I'm using Sebastien Blanchet's mini example he posted in 2012 as a base; in
my application, I want to run the drive in velocity mode and just set/query
the velocity values and the digital input status, along with the command
word and status word.
The issue is that the registration of the last PDO comes up unmapped. The
output from dmesg is:
[ 6271.226521] EtherCAT: Requesting master 0...
[ 6271.226525] EtherCAT: Successfully requested master 0.
[ 6271.226584] EtherCAT ERROR 0 0:0: PDO entry 0x6041:00 is not mapped.
[ 6271.226641] EtherCAT 0: Releasing master...
[ 6271.226643] EtherCAT 0: Released.
The application runs (although with a funny issue with the digital input
value varying wildly) when I don't include that particular PDO by not
configuring it in the 0x1A01 object.
The error messages when the code is running is:
<stderr>: Failed to register PDO entry: No such file or directory
<stderr>: PDO entry registration failed!
<stdout>: Configuring AKD with free PDO...
<stdout>: Configuring PDOs...
So clearly the error happens when ecrt_domain_reg_pdo_entry_list() gets
called. I'm really unsure why this would happen, I don't see what mistake
there must be in there, so it's time to get help from the experts...and
thanks in advance!
BTW, I did supply the PDO list with a call to ecrt_slave_config_pdos(), so
I *think* the PDOs got configured, but then I get the unmapped PDO error...
Listing is attached...
Dusty Clark
/*
* test2.c
*
* Created on: Jan 4, 2014
* Author: dclark
*
* This is based on the mini example from the Etherlab.org mailing list supplied by
* Sebastien Blanchet who wrote:
*
* Mini example of PDO mapping with drive AKD Kollmorgen
* The program maps some PDOs to monitor actual values of the drive
*
* In this version, we'll be mapping a few different variables and trying to actually monitor
* some real values (e.g. status, velocity, digital inputs).
*
*
*
*/
/* System includes */
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include "ecrt.h"
// Application parameters
#define FREQUENCY 100
/* EtherCAT */
static ec_master_t *master = NULL;
static ec_domain_t *domain1 = NULL;
static uint8_t *domain1_pd = NULL;
static ec_slave_config_t *sc_akd = NULL;
// Slave ring position and alias
#define AkdSlavePos 0,0
#define Kollmorgen_AKD 0x0000006a, 0x00414b44
/* Offsets for PDO entries */
/* RX by slave from master */
static unsigned int off_akd_ctrlword;
static unsigned int off_akd_velocity_command;
/* TX to master from slave */
static unsigned int off_akd_act_velocity;
static unsigned int off_akd_digital_in;
static unsigned int off_akd_status;
/* Variables to map into the cyclic data exchange domain */
const static ec_pdo_entry_reg_t domain1_regs[] = {
{AkdSlavePos, Kollmorgen_AKD, 0x6040, 0, &off_akd_ctrlword},
{AkdSlavePos, Kollmorgen_AKD, 0x60FF, 0, &off_akd_velocity_command},
{AkdSlavePos, Kollmorgen_AKD, 0x606C, 0, &off_akd_act_velocity},
{AkdSlavePos, Kollmorgen_AKD, 0x60FD, 0, &off_akd_digital_in},
{AkdSlavePos, Kollmorgen_AKD, 0x6041, 0, &off_akd_status},
{}
};
/* AKD entries to map to the PDO dictionary*/
ec_pdo_entry_info_t akd_pdo_entries[] = {
/* RxPdo 0x1600 */
{0x6040, 0x00, 16}, /* control word */
{0x60FF, 0x00, 32}, /* velocity command */
/* TxPDO 0x1a00 */
{0x606C, 0x00, 32}, /* actual velocity*/
{0x60FD, 0x00, 32}, /* digital in */
/* TxPDO 0x1a01 */
{0x6041, 0x00, 16}, /* status word */
};
ec_pdo_info_t akd_pdos[] = {
{0x1600, 2, akd_pdo_entries + 0},
{0x1a00, 2, akd_pdo_entries + 2},
{0x1a01, 1, akd_pdo_entries + 4}
};
ec_sync_info_t akd_syncs[] = {
{0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
{1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
{2, EC_DIR_OUTPUT, 1, akd_pdos + 0, EC_WD_DISABLE},
{3, EC_DIR_INPUT, 1, akd_pdos + 1, EC_WD_DISABLE},
{0xff}
};
/* Function declaration for display of data*/
void cyclic_task();
/*********************************************************************************************************************/
int main(int argc, char **argv)
{
int j;
master = ecrt_request_master(0);
if (!master)
return -1;
domain1 = ecrt_master_create_domain(master);
if (!domain1)
return -1;
if (!(sc_akd = ecrt_master_slave_config(
master, AkdSlavePos, Kollmorgen_AKD))) {
fprintf(stderr, "Failed to get slave configuration for AKD.\n");
return -1;
}
/* Configure AKD free PDO */
printf("Configuring AKD with free PDO...\n");
/* Clear RxPdo */
ecrt_slave_config_sdo8( sc_akd, 0x1C12, 0, 0 ); /* clear sm pdo 0x1c12 */
ecrt_slave_config_sdo8( sc_akd, 0x1600, 0, 0 ); /* clear RxPdo 0x1600 */
ecrt_slave_config_sdo8( sc_akd, 0x1601, 0, 0 ); /* clear RxPdo 0x1601 */
ecrt_slave_config_sdo8( sc_akd, 0x1602, 0, 0 ); /* clear RxPdo 0x1602 */
ecrt_slave_config_sdo8( sc_akd, 0x1603, 0, 0 ); /* clear RxPdo 0x1603 */
/* Define RxPdo */
ecrt_slave_config_sdo32( sc_akd, 0x1600, 1, 0x60400010 ); /* 0x6040:0/16bits, control word */
ecrt_slave_config_sdo32( sc_akd, 0x1600, 2, 0x60FF0020 ); /* 0x60FF:1/32bits, velocity command */
ecrt_slave_config_sdo8( sc_akd, 0x1600, 0, 2 ); /* set number of PDO entries for 0x1600, totals 6 bytes*/
ecrt_slave_config_sdo16( sc_akd, 0x1C12, 1, 0x1600 ); /* list all RxPdo in 0x1C12:1-4 */
ecrt_slave_config_sdo8( sc_akd, 0x1C12, 0, 1 ); /* set number of RxPDO */
/* Clear TxPdo */
ecrt_slave_config_sdo8( sc_akd, 0x1C13, 0, 0 ); /* clear sm pdo 0x1c13 */
ecrt_slave_config_sdo8( sc_akd, 0x1A00, 0, 0 ); /* clear TxPdo 0x1A00 */
ecrt_slave_config_sdo8( sc_akd, 0x1A01, 0, 0 ); /* clear TxPdo 0x1A01 */
ecrt_slave_config_sdo8( sc_akd, 0x1A02, 0, 0 ); /* clear TxPdo 0x1A02 */
ecrt_slave_config_sdo8( sc_akd, 0x1A03, 0, 0 ); /* clear TxPdo 0x1A03 */
/* Define TxPdo */
ecrt_slave_config_sdo32( sc_akd, 0x1A00, 1, 0x606C0020 ); /* 0x606C:0/32bits, actual velocity */
ecrt_slave_config_sdo32( sc_akd, 0x1A00, 2, 0x60FD0020 ); /* 0x60FD:0/32bits, digital inputs */
ecrt_slave_config_sdo8( sc_akd, 0x1A00, 0, 2 ); /* set number of PDO entries for 0x1A00, totals 8 bytes */
ecrt_slave_config_sdo32( sc_akd, 0x1A01, 1, 0x60410010 ); /* 0x6041:0/16bits, status word */
ecrt_slave_config_sdo8( sc_akd, 0x1A01, 0, 1 ); /* set number of PDO entries for 0x1A01, totals 2 bytes*/
ecrt_slave_config_sdo16( sc_akd, 0x1C13, 1, 0x1A00 ); /* list all TxPdo in 0x1C13:1-4 */
ecrt_slave_config_sdo16( sc_akd, 0x1C13, 2, 0x1A01 ); /* list all TxPdo in 0x1C13:1-4 */
ecrt_slave_config_sdo8( sc_akd, 0x1C13, 0, 2 ); /* set number of TxPDO */
printf("Configuring PDOs...\n");
if (ecrt_slave_config_pdos(sc_akd, EC_END, akd_syncs)) {
fprintf(stderr, "Failed to configure AKD PDOs.\n");
return -1;
}
//here is the error!
if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) {
fprintf(stderr, "PDO entry registration failed!\n" );
return -1;
}
printf("Activating master...\n");
if (ecrt_master_activate(master))
return -1;
if (!(domain1_pd = ecrt_domain_data(domain1))) {
return -1;
}
printf("Started.\n");
while (1) {
usleep( 1000000 / FREQUENCY );
cyclic_task();
}
return 0;
}
/******************************************************************************************************/
void cyclic_task()
{
static unsigned int counter = 0;
/* receive process data */
ecrt_master_receive(master);
ecrt_domain_process(domain1);
if (counter) {
counter--;
} else { /* do this at 1 Hz */
counter = FREQUENCY;
/* read process data */
printf("AKD act_velocity = %8.3f rpm, digital in = %x\n",
EC_READ_S32(domain1_pd + off_akd_act_velocity),
EC_READ_U32(domain1_pd + off_akd_digital_in)
);
printf("AKD status is: %x\n", EC_READ_U16(domain1_pd + off_akd_status));
}
/* send process data */
ecrt_domain_queue(domain1);
ecrt_master_send(master);
}
_______________________________________________
etherlab-users mailing list
[email protected]
http://lists.etherlab.org/mailman/listinfo/etherlab-users