[etherlab-users] Trouble getting Parker Hannifin Drive to work

Montgomery-Smith, Stephen stephen at missouri.edu
Sun Apr 15 02:01:14 CEST 2018


I have a Parker Hannifin P-Series drive, described here:
https://www.parkermotion.com/products/Servo_Drives__7319__30_32_80_567_29.html. 
I am able to make it work using the software package EC-Master by
Acontis, but I would prefer to use open source software

I have tried both etherlab and SOEM without any success.  I am attaching
the program I wrote for etherlab (also cutting and pasting it below in
case the attachment is removed).  Actually, running this program can
cause the computer to freeze.  I am using ubuntu-16.10 with linux kernel
4.10.  Any help or hints would be greatly appreciated.

The program enters the loop, and outputs values saying where the move
should be moving to.  But the motor simply doesn't move.  The lights on
the drive, and the output of "etherlab config" suggest the drive is
still in the SAFE_OP state.  My guess is that there are some other
initialization commands the drive needs, and if I understood how to
properly read ENI files (the one used and generated by the Acontis
software), that perhaps both this program, and the one I wrote in SOEM,
would work.

I am using the generic etherlab module.  Unfortunately the e1000e module
doesn't work on any linux kernel greater than 3.4, and I am having a
really hard time getting sufficiently old versions of linux to work.

Also, does anyone know a good help forum for SOEM, so I can ask similar
questions there about the SOEM program I wrote?

Thanks, Stephen



#include <ecrt.h>
#include <pthread.h>
#include <sys/time.h>
#include <signal.h>
#include <math.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>

#define NSEC_PER_SEC (1000000000L)
#define TIMESPEC2NS(T) ((uint64_t) (T).tv_sec * NSEC_PER_SEC + (T).tv_nsec)

pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t do_loop_cond = PTHREAD_MUTEX_INITIALIZER;

struct timespec abstime;

ec_master_t *master;
ec_slave_config_t *slave0;
ec_domain_t *domain, *domain;

void exit_all(int exit_code) {
  printf("Exit %d\n", exit_code);
  ecrt_release_master(master);
  printf("Release master\n");
  exit(exit_code);
}

void handler(int code) {
  exit_all(1);
}

int main() {
  int ret_val;


  if (SIG_ERR == signal(SIGINT, handler)) {
    printf("Unable to reassign SIGINT\n");
    exit(1);
  }

  if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
    perror("mlockall failed");
    exit(1);
  }

  if ((master = ecrt_open_master(0)) == NULL) {
    printf("Unable to request master\n");
    exit(1);
  }

  if ((ret_val = ecrt_master_reserve(master)) < 0) {
    printf("Unable to reserve master %d\n", ret_val);
    exit(1);
  }

  if ((domain = ecrt_master_create_domain(master)) == NULL) {
    printf("Unable to create domain\n");
  }

  if ((slave0 = ecrt_master_slave_config(master, 0, 0, 0x9000089,
0x10001)) == NULL) {
    printf("Unable to request slave0\n");
    exit(1);
  }

#define SYNC_OUT    2
#define SYNC_IN        3

  ec_pdo_entry_info_t pdo_entries_out[] = {{0x6040, 0, 16},
                                           {0x6071, 0, 16},
                                           {0x607a, 0, 32},
                                           {0x6060, 0, 8},
                                           {0x60b8, 0, 16}};
  ec_pdo_info_t pdos_out[] = {{0x1600, 5, pdo_entries_out}};
  ec_sync_info_t syncs_out[] = {{SYNC_OUT, EC_DIR_OUTPUT, 1, pdos_out,
EC_WD_DEFAULT}};
  if ((ret_val = ecrt_slave_config_pdos(slave0, 1, syncs_out)) < 0) {
    printf("Unable to configure output pdos %d\n", ret_val);
    exit(1);
  }

  ec_pdo_entry_info_t pdo_entries_in[] = {{0x6041, 0, 16},
                                          {0x6077, 0, 16},
                                          {0x6064, 0, 32},
                                          {0x60f4, 0, 32},
                                          {0x60fd, 0, 32},
                                          {0x6061, 0, 8},
                                          {0x2601, 0, 16},
                                          {0x2600, 0, 16},
                                          {0x60b9, 0, 16},
                                          {0x60ba, 0, 32}};
  ec_pdo_info_t pdos_in[] = {{0x1a00, 10, pdo_entries_in}};
  ec_sync_info_t syncs_in[] = {{SYNC_IN, EC_DIR_INPUT, 1, pdos_in,
EC_WD_DEFAULT}};
  if ((ret_val = ecrt_slave_config_pdos(slave0, 1, syncs_in)) < 0) {
    printf("Unable to configure input pdos %d\n", ret_val);
    exit(1);
  }

  uint off_ctlword, off_tgt_torque, off_tgt_pos, off_op_mode,
off_t_probe_fn,
       off_stword, off_act_torque, off_act_pos, off_act_pos_err,
off_dig_input,
       off_op_mode_disp, off_comm_speed, off_op_speed, off_t_probe_st,
off_t_probe_pos_pos_val;

  ec_pdo_entry_reg_t pdo_entry_regs[] = {
    {0, 0, 0x9000089, 0x10001, 0x6040, 0, &off_ctlword, NULL},
    {0, 0, 0x9000089, 0x10001, 0x6071, 0, &off_tgt_torque, NULL},
    {0, 0, 0x9000089, 0x10001, 0x607a, 0, &off_tgt_pos, NULL},
    {0, 0, 0x9000089, 0x10001, 0x6060, 0, &off_op_mode, NULL},
    {0, 0, 0x9000089, 0x10001, 0x60b8, 0, &off_t_probe_fn, NULL},
    {0, 0, 0x9000089, 0x10001, 0x6041, 0, &off_stword, NULL},
    {0, 0, 0x9000089, 0x10001, 0x6077, 0, &off_act_torque, NULL},
    {0, 0, 0x9000089, 0x10001, 0x6064, 0, &off_act_pos, NULL},
    {0, 0, 0x9000089, 0x10001, 0x60f4, 0, &off_act_pos_err, NULL},
    {0, 0, 0x9000089, 0x10001, 0x60fd, 0, &off_dig_input, NULL},
    {0, 0, 0x9000089, 0x10001, 0x6061, 0, &off_op_mode_disp, NULL},
    {0, 0, 0x9000089, 0x10001, 0x2601, 0, &off_comm_speed, NULL},
    {0, 0, 0x9000089, 0x10001, 0x2600, 0, &off_op_speed, NULL},
    {0, 0, 0x9000089, 0x10001, 0x60b9, 0, &off_t_probe_st, NULL},
    {0, 0, 0x9000089, 0x10001, 0x60ba, 0, &off_t_probe_pos_pos_val, NULL},
    {0, 0, 0, 0, 0, 0, 0, 0}};

  if ((ret_val = ecrt_domain_reg_pdo_entry_list(domain, pdo_entry_regs))
!= 0) {
    printf("Unable to register pdos %d\n", ret_val);
    exit(1);
  }

  ecrt_slave_config_dc(slave0, 0, 0, 0, 0, 0);

  if ((ret_val = ecrt_master_activate(master)) < 0) {
    printf("Unable to activate master %d\n", ret_val);
    exit(1);
  }

  uint8_t *data_pointer;

  if ((data_pointer = ecrt_domain_data(domain)) == NULL) {
    printf("Unable to get data pointer to domain\n");
    exit(1);
  }

  printf("Starting\n");

  clock_gettime(CLOCK_REALTIME, &abstime);

  data_pointer[off_ctlword] = 0xf;
  data_pointer[off_op_mode] = 8;

  int start_position;
  start_position = EC_READ_S32(data_pointer + off_act_pos);

  int position = 0;
  double t = 0;
  int velocity;

  struct timespec time;

  while(1) {
    printf("In loop %g %d\n",t, position);

    // Transfer data
    ecrt_master_receive(master);
    ecrt_domain_process(domain);

    position = - 200000*(1-cos(t));
    data_pointer[off_op_mode] = 8;
    EC_WRITE_S32(data_pointer+off_tgt_pos, position);
    t += 1000000/1000000000.0;

    ecrt_domain_queue(domain);
    ecrt_master_send(master);

    clock_gettime(CLOCK_REALTIME, &time);
    ecrt_master_application_time(master, TIMESPEC2NS(time));

    // Wait 1000us
    abstime.tv_nsec += 1000000; // Advance 1000us from prior time.
    while (abstime.tv_nsec >= 1000000000) {
      abstime.tv_nsec -= 1000000000;
      abstime.tv_sec += 1;
    }
    pthread_mutex_lock(&cond_mutex);
    ret_val = pthread_cond_timedwait(&do_loop_cond, &cond_mutex, &abstime);
    pthread_mutex_unlock(&cond_mutex);

  }
}


-------------- next part --------------
A non-text attachment was scrubbed...
Name: test_ec.c
Type: text/x-csrc
Size: 6030 bytes
Desc: test_ec.c
URL: <http://lists.etherlab.org/pipermail/etherlab-users/attachments/20180415/98ab312c/attachment-0003.c>


More information about the Etherlab-users mailing list