/** Creates a new SMC100Controller object.
  * \param[in] portName          The name of the asyn port that will be created for this driver
  * \param[in] SMC100PortName     The name of the drvAsynSerialPort that was created previously to connect to the SMC100 controller 
  * \param[in] numAxes           The number of axes that this controller supports 
  * \param[in] movingPollPeriod  The time between polls when any axis is moving 
  * \param[in] idlePollPeriod    The time between polls when no axis is moving 
  */
SMC100Controller::SMC100Controller(const char *portName, const char *SMC100PortName, int numAxes, 
                                 double movingPollPeriod, double idlePollPeriod, double stepSize)
  :  asynMotorController(portName, numAxes, NUM_SMC100_PARAMS, 
                         0, // No additional interfaces beyond those in base class
                         0, // No additional callback interfaces beyond those in base class
                         ASYN_CANBLOCK | ASYN_MULTIDEVICE, 
                         1, // autoconnect
                         0, 0)  // Default priority and stack size
{
  int axis;
  asynStatus status;
  SMC100Axis *pAxis;
  static const char *functionName = "SMC100Controller::SMC100Controller";
  
  /* Connect to SMC100 controller */
  status = pasynOctetSyncIO->connect(SMC100PortName, 0, &pasynUserController_, NULL);
  if (status) {
    asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, 
      "%s: cannot connect to SMC100 controller\n",
      functionName);
  }
  for (axis=0; axis<numAxes; axis++) {
  //for (axis=1; axis < (numAxes + 1); axis++) {
    pAxis = new SMC100Axis(this, axis, stepSize);
  }

  startPoller(movingPollPeriod, idlePollPeriod, 2);
}
Esempio n. 2
0
/** Creates a new MMC100Controller object.
  * \param[in] portName          The name of the asyn port that will be created for this driver
  * \param[in] MMC100PortName     The name of the drvAsynIPPPort that was created previously to connect to the MMC100 controller
  * \param[in] numAxes           The number of axes that this controller supports
  * \param[in] movingPollPeriod  The time between polls when any axis is moving
  * \param[in] idlePollPeriod    The time between polls when no axis is moving
  */
MMC100Controller::MMC100Controller(const char *portName, const char *MMC100PortName, int numAxes,
                             double movingPollPeriod, double idlePollPeriod)
  :  asynMotorController(portName, numAxes, NUM_MMC100_PARAMS,
                         asynInt32Mask | asynFloat64Mask | asynUInt32DigitalMask,
                         asynInt32Mask | asynFloat64Mask | asynUInt32DigitalMask,
                         ASYN_CANBLOCK | ASYN_MULTIDEVICE,
                         1, // autoconnect
                         0, 0)  // Default priority and stack size
{
  int axis;
  asynStatus status;
  MMC100Axis *pAxis;
  static const char *functionName = "MMC100Controller::MMC100Controller";

  unitScale_ = MMC100_UNIT_SCALE;
  if (!addToList(portName, this)) {
    printf("%s:%s: Init failed", driverName, portName);
    return;
  }

  printf("Idle: %f moving: %f\n", idlePollPeriod_, movingPollPeriod_);
  idlePollPeriod_ = idlePollPeriod;
  movingPollPeriod_ = movingPollPeriod;
  timeout_ = MMC100_TIMEOUT;
  homing_axis_ = false;

  /* Connect to MMC100 controller */
  status = pasynOctetSyncIO->connect(MMC100PortName, 0, &pasynUser_, NULL);
  if (status) {
    asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
      "%s:%s: cannot connect to MMC100 controller\n",
      driverName, functionName);
  }

  status = pasynOctetSyncIO->setInputEos(pasynUser_, "\n\r", 2);
  if (status) {
    asynPrint(pasynUser_, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
      "%s: Unable to set input EOS on %s: %s\n",
      functionName, MMC100PortName, pasynUser_->errorMessage);
  }

  status = pasynOctetSyncIO->setOutputEos(pasynUser_, "\n\r", 2);
  if (status) {
    asynPrint(pasynUser_, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
      "%s: Unable to set output EOS on %s: %s\n",
      functionName, MMC100PortName, pasynUser_->errorMessage);
  }

  // Create the axis objects
  for (axis=0; axis<numAxes; axis++) {
    pAxis = new MMC100Axis(this, axis);
    pAxis->check_error();
  }
  startPoller(movingPollPeriod/1000., idlePollPeriod/1000., 2);
}
////////////////////////////////////////////////////////
//! @ImsMDrivePlusMotorController()
//! Constructor
//! Driver assumes only 1 axis configured per controller for now...
//!
//! @param[in] motorPortName     Name assigned to the port created to communicate with the motor
//! @param[in] IOPortName        Name assigned to the asyn IO port, name that was assigned in drvAsynIPPortConfigure()
//! @param[in] devName           Name of device (DN) assigned to motor axis in MCode, the device name is prepended to the MCode command to support Party Mode (PY) multidrop communication setup
//!                              set to empty string "" if no device name needed/not using Party Mode
//! @param[in] movingPollPeriod  Moving polling period in milliseconds
//! @param[in] idlePollPeriod    Idle polling period in milliseconds
////////////////////////////////////////////////////////
ImsMDrivePlusMotorController::ImsMDrivePlusMotorController(const char *motorPortName, const char *IOPortName, const char *devName, double movingPollPeriod, double idlePollPeriod)
    : asynMotorController(motorPortName, NUM_AXES, NUM_IMS_PARAMS,
						  asynInt32Mask | asynFloat64Mask | asynUInt32DigitalMask,
						  asynInt32Mask | asynFloat64Mask | asynUInt32DigitalMask,
						  ASYN_CANBLOCK | ASYN_MULTIDEVICE,
						  1, // autoconnect
						  0, 0),  // Default priority and stack size
    pAsynUserIMS(0)
{
	static const char *functionName = "ImsMDrivePlusMotorController()";
	asynStatus status;
	ImsMDrivePlusMotorAxis *pAxis;
	// asynMotorController constructor calloc's memory for array of axis pointers
	pAxes_ = (ImsMDrivePlusMotorAxis **)(asynMotorController::pAxes_);

	// copy names
	strcpy(motorName, motorPortName);

	// setup communication
	status = pasynOctetSyncIO->connect(IOPortName, 0, &pAsynUserIMS, NULL);
	if (status != asynSuccess) {
		printf("\n\n%s:%s: ERROR connecting to Controller's IO port=%s\n\n", DRIVER_NAME, functionName, IOPortName);
		// TODO would be good to implement exceptions
		// TODO THROW_(SmarActMCSException(MCSConnectionError, "SmarActMCSController: unable to connect serial channel"));
	}

	// write version, cannot use asynPrint() in constructor since controller (motorPortName) hasn't been created yet
	printf("%s:%s: motorPortName=%s, IOPortName=%s, devName=%s \n", DRIVER_NAME, functionName, motorPortName, IOPortName, devName);


	// init
	pasynOctetSyncIO->setInputEos(pAsynUserIMS, "\n", 1);
	pasynOctetSyncIO->setOutputEos(pAsynUserIMS, "\r\n", 2); 

	// Create controller-specific parameters
	createParam(ImsMDrivePlusSaveToNVMControlString, asynParamInt32, &ImsMDrivePlusSaveToNVM_);
	createParam(ImsMDrivePlusLoadMCodeControlString, asynParamOctet, &this->ImsMDrivePlusLoadMCode_);
	createParam(ImsMDrivePlusClearMCodeControlString, asynParamOctet, &this->ImsMDrivePlusClearMCode_);

	// Check the validity of the arguments and init controller object
	initController(devName, movingPollPeriod, idlePollPeriod);

	// Create axis
	// Assuming single axis per controller the way drvAsynIPPortConfigure( "M06", "ts-b34-nw08:2101", 0, 0 0 ) is called in st.cmd script
	pAxis = new ImsMDrivePlusMotorAxis(this, 0);
	pAxis = NULL;  // asynMotorController constructor tracking array of axis pointers

	// read home and limit config from S1-S4
	readHomeAndLimitConfig();

	startPoller(movingPollPeriod, idlePollPeriod, 2);
}
/** Creates a new AG_CONEXController object.
  * \param[in] portName          The name of the asyn port that will be created for this driver
  * \param[in] serialPortName    The name of the drvAsynSerialPort that was created previously to connect to the CONEX controller 
  * \param[in] numAxes           The number of axes that this controller supports 
  * \param[in] movingPollPeriod  The time between polls when any axis is moving 
  * \param[in] idlePollPeriod    The time between polls when no axis is moving 
  */
AG_CONEXController::AG_CONEXController(const char *portName, const char *serialPortName, int controllerID, 
                                 double movingPollPeriod, double idlePollPeriod)
  :  asynMotorController(portName, 1, NUM_AG_CONEX_PARAMS, 
                         0, // No additional interfaces beyond those in base class
                         0, // No additional callback interfaces beyond those in base class
                         ASYN_CANBLOCK | ASYN_MULTIDEVICE, 
                         1, // autoconnect
                         0, 0),  // Default priority and stack size
   controllerID_(controllerID)
                    
{
  asynStatus status;
  static const char *functionName = "AG_CONEXController::AG_CONEXController";

  /* Connect to CONEX controller */
  status = pasynOctetSyncIO->connect(serialPortName, 0, &pasynUserController_, NULL);
  if (status) {
    asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, 
      "%s: cannot connect to CONEX controller\n",
      functionName);
    return;
  }
  
  // Flush any characters that controller has, read firmware version
  sprintf(outString_, "%dVE", controllerID_);
  status = writeReadController();
  if (status) {
    asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, 
      "%s: cannot read version information from AG_CONEX controller\n",
      functionName);
    return;
  }
  strcpy(controllerVersion_, &inString_[4]);

  // Create the axis object
  new AG_CONEXAxis(this);

  startPoller(movingPollPeriod, idlePollPeriod, 2);
}
Esempio n. 5
0
/** Creates a new C300Controller object.
  * \param[in] portName          The name of the asyn port that will be created for this driver
  * \param[in] C300PortName       The name of the drvAsynIPPPort that was created previously to connect to the C300 controller 
  * \param[in] numAxes           The number of axes that this controller supports 
  * \param[in] movingPollPeriod  The time between polls when any axis is moving 
  * \param[in] idlePollPeriod    The time between polls when no axis is moving 
  */
C300Controller::C300Controller(const char *portName, const char *C300PortName, int numAxes, 
                             double movingPollPeriod, double idlePollPeriod)
  :  asynMotorController(portName, numAxes, NUM_C300_PARAMS, 
                         asynUInt32DigitalMask, 
                         asynUInt32DigitalMask,
                         ASYN_CANBLOCK | ASYN_MULTIDEVICE, 
                         1, // autoconnect
                         0, 0)  // Default priority and stack size
{
  int axis;
  asynStatus status;
  C300Axis *pAxis;
  static const char *functionName = "C300Controller";

  /* Connect to C300 controller */
  status = pasynOctetSyncIO->connect(C300PortName, 0, &pasynUserC300_, NULL);
  if (status) {
    asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, 
      "%s:%s: cannot connect to C300 controller\n",
      driverName, functionName);
  }
  // Unlock the controller
  sprintf(outString_, "SYS:PASS:CEN \"nPoint\"");
  writeController();

  // get controller id, firmware version and range?

  // Wait a short while so that any responses to the above commands have time to arrive so we can flush
  // them in the next writeReadController()
  //epicsThreadSleep(0.5);

  // Create the axis objects
  for (axis=0; axis<numAxes; axis++) {
    pAxis = new C300Axis(this, axis);
  }

  startPoller(movingPollPeriod, idlePollPeriod, 2);
}
Esempio n. 6
0
/** Creates a new ddriveController object.
  * \param[in] portName          The name of the asyn port that will be created for this driver
  * \param[in] ddrivePortName     The name of the drvAsynIPPPort that was created previously to connect to the ddrive controller
  * \param[in] numAxes           The number of axes that this controller supports
  * \param[in] movingPollPeriod  The time between polls when any axis is moving
  * \param[in] idlePollPeriod    The time between polls when no axis is moving
  */
ddriveController::ddriveController(const char *portName, const char *ddrivePortName, int numAxes,
                             double movingPollPeriod, double idlePollPeriod)
  :  asynMotorController(portName, numAxes, NUM_DDRIVE_PARAMS,
                         asynInt32Mask | asynFloat64Mask | asynUInt32DigitalMask,
                         asynInt32Mask | asynFloat64Mask | asynUInt32DigitalMask,
                         ASYN_CANBLOCK | ASYN_MULTIDEVICE,
                         1, // autoconnect
                         0, 0)  // Default priority and stack size
{
  int axis;
  asynStatus status;
  //ddriveAxis *pAxis;

  queryRate_ = 1;

  position_move_timeout_ = DDRIVE_MOVE_TIMEOUT;
  dd_param_count_ = NUM_DDRIVE_CONTROLLER_PARAMS; 
  idlePollPeriod_ = idlePollPeriod;
  movingPollPeriod_ = movingPollPeriod;
  timeout_ = DDRIVE_TIMEOUT;

  ddparams_ = new DDParam[NUM_DDRIVE_CONTROLLER_PARAMS];

  // R+W parameters
  //            command to send,      asyn string,          type,               parameter index, poll, global, service mode)
  createDDParam(DD_PARAM_CMD_KTEMP,   DD_PARAM_STR_KTEMP,   asynParamFloat64,  &param_ktemp_);
  createDDParam(DD_PARAM_CMD_ROHM,    DD_PARAM_STR_ROHM,    asynParamInt32,    &param_rohm_);
  createDDParam(DD_PARAM_CMD_RGVER,   DD_PARAM_STR_RGVER,   asynParamInt32,    &param_rgver_);
  createDDParam(DD_PARAM_CMD_FENABLE, DD_PARAM_STR_FENABLE, asynParamInt32,    &param_fenable_);
  createDDParam(DD_PARAM_CMD_SR,      DD_PARAM_STR_SR,      asynParamFloat64,  &param_sr_);
  createDDParam(DD_PARAM_CMD_MODON,   DD_PARAM_STR_MODON,   asynParamInt32,    &param_modon_);
  createDDParam(DD_PARAM_CMD_KP,      DD_PARAM_STR_KP,      asynParamFloat64,  &param_kp_);
  createDDParam(DD_PARAM_CMD_KI,      DD_PARAM_STR_KI,      asynParamFloat64,  &param_ki_);
  createDDParam(DD_PARAM_CMD_KD,      DD_PARAM_STR_KD,      asynParamFloat64,  &param_kd_);
  createDDParam(DD_PARAM_CMD_NOTCHON, DD_PARAM_STR_NOTCHON, asynParamInt32,    &param_notchon_);
  createDDParam(DD_PARAM_CMD_NOTCHF,  DD_PARAM_STR_NOTCHF,  asynParamInt32,    &param_notchf_);
  createDDParam(DD_PARAM_CMD_NOTCHB,  DD_PARAM_STR_NOTCHB,  asynParamInt32,    &param_notchb_);
  createDDParam(DD_PARAM_CMD_LPON,    DD_PARAM_STR_LPON,    asynParamInt32,    &param_lpon_);
  createDDParam(DD_PARAM_CMD_LPF,     DD_PARAM_STR_LPF,     asynParamInt32,    &param_lpf_);
  createDDParam(DD_PARAM_CMD_GASIN,   DD_PARAM_STR_GASIN,   asynParamFloat64,  &param_gasin_);
  createDDParam(DD_PARAM_CMD_GOSIN,   DD_PARAM_STR_GOSIN,   asynParamFloat64,  &param_gosin_);
  createDDParam(DD_PARAM_CMD_GFSIN,   DD_PARAM_STR_GFSIN,   asynParamFloat64,  &param_gfsin_);
  createDDParam(DD_PARAM_CMD_GATRI,   DD_PARAM_STR_GATRI,   asynParamFloat64,  &param_gatri_);
  createDDParam(DD_PARAM_CMD_GOTRI,   DD_PARAM_STR_GOTRI,   asynParamFloat64,  &param_gotri_);
  createDDParam(DD_PARAM_CMD_GFTRI,   DD_PARAM_STR_GFTRI,   asynParamFloat64,  &param_gftri_);
  createDDParam(DD_PARAM_CMD_GSTRI,   DD_PARAM_STR_GSTRI,   asynParamFloat64,  &param_gstri_);
  createDDParam(DD_PARAM_CMD_GAREC,   DD_PARAM_STR_GAREC,   asynParamFloat64,  &param_garec_);
  createDDParam(DD_PARAM_CMD_GOREC,   DD_PARAM_STR_GOREC,   asynParamFloat64,  &param_gorec_);
  createDDParam(DD_PARAM_CMD_GFREC,   DD_PARAM_STR_GFREC,   asynParamFloat64,  &param_gfrec_);
  createDDParam(DD_PARAM_CMD_GSREC,   DD_PARAM_STR_GSREC,   asynParamFloat64,  &param_gsrec_);
  createDDParam(DD_PARAM_CMD_GANOI,   DD_PARAM_STR_GANOI,   asynParamFloat64,  &param_ganoi_);
  createDDParam(DD_PARAM_CMD_GONOI,   DD_PARAM_STR_GONOI,   asynParamFloat64,  &param_gonoi_);
  createDDParam(DD_PARAM_CMD_GASWE,   DD_PARAM_STR_GASWE,   asynParamFloat64,  &param_gaswe_);
  createDDParam(DD_PARAM_CMD_GOSWE,   DD_PARAM_STR_GOSWE,   asynParamFloat64,  &param_goswe_);
  createDDParam(DD_PARAM_CMD_GTSWE,   DD_PARAM_STR_GTSWE,   asynParamFloat64,  &param_gtswe_);
  createDDParam(DD_PARAM_CMD_TRGSS,   DD_PARAM_STR_TRGSS,   asynParamFloat64,  &param_trgss_);
  createDDParam(DD_PARAM_CMD_TRGSE,   DD_PARAM_STR_TRGSE,   asynParamFloat64,  &param_trgse_);
  createDDParam(DD_PARAM_CMD_TRGSI,   DD_PARAM_STR_TRGSI,   asynParamFloat64,  &param_trgsi_);
  createDDParam(DD_PARAM_CMD_TRGLEN,  DD_PARAM_STR_TRGLEN,  asynParamInt32,    &param_trglen_);

  // MBBIO parameters
  createDDParam(DD_PARAM_CMD_MONSRC,  DD_PARAM_STR_MONSRC,  asynParamUInt32Digital, &param_monsrc_);
  createDDParam(DD_PARAM_CMD_GFKT,    DD_PARAM_STR_GFKT,    asynParamUInt32Digital, &param_gfkt_);
  createDDParam(DD_PARAM_CMD_SCT,     DD_PARAM_STR_SCT,     asynParamUInt32Digital, &param_sct_); // sometimes has issues reading back?
  createDDParam(DD_PARAM_CMD_TRGEDGE, DD_PARAM_STR_TRGEDGE, asynParamUInt32Digital, &param_trgedge_);

  // Global parameters                                                                                        
  createDDParam(DD_PARAM_CMD_BRIGHT,  DD_PARAM_STR_BRIGHT,  asynParamInt32,    &param_bright_,   true,  true);
                                                                                                              
  // Write-only                                                                                               
  createDDParam(DD_PARAM_CMD_SSTD,    DD_PARAM_STR_SSTD,      asynParamInt32,  &param_sstd_,    false, false); // set default values
  createDDParam(DD_PARAM_CMD_CL,      DD_PARAM_STR_CL,        asynParamInt32,  &param_cl_,      false, false); // open/closed loop
  createDDParam(DD_PARAM_CMD_FBREAK,  DD_PARAM_STR_FBREAK,    asynParamInt32,  &param_fbreak_,  false, false); // abort soft start
  // start scan sometimes doesn't readback... let's just not query it
  createDDParam(DD_PARAM_CMD_SS,      DD_PARAM_STR_SS,      asynParamInt32,    &param_ss_,      false, false);
  
  // Special handling:
  createDDParam(DD_PARAM_CMD_WRMB,      DD_PARAM_STR_ENC_RATE, asynParamInt32,   &param_enc_rate_, false, false, true, DD_PARAM_SVC_ENC_RATE);
  // Last of queryable-DDrive parameters
  
  // Read-only (updated when status changes)
  createParam(DD_PARAM_STR_PLUGGED,               asynParamInt32,    &param_plugged_);
  createParam(DD_PARAM_STR_CLOSED_SYS,            asynParamInt32,    &param_closed_sys_);
  createParam(DD_PARAM_STR_VOLTAGE_ON,            asynParamInt32,    &param_voltage_on_);
  createParam(DD_PARAM_STR_MEAS_SYS,      asynParamUInt32Digital,    &param_meas_sys_);

  // Read-write
  createParam(DD_PARAM_STR_MOVE_TIMEOUT,  asynParamFloat64,  &param_move_timeout_);

  if (!addToList(portName, this)) {
    printf("%s:%s: Init failed", driverName, portName);
    return;
  }

  setIntegerParam(motorStatusHasEncoder_, 1);

  /* Connect to ddrive controller */
  status = pasynOctetSyncIO->connect(ddrivePortName, 0, &pasynUser_, NULL);
  if (status) {
    asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
      "%s:%s: cannot connect to ddrive controller\n",
      driverName, __func__);
  }

  status = pasynOctetSyncIO->setInputEos(pasynUser_, "\r", 1);
  if (status) {
    asynPrint(pasynUser_, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
      "%s: Unable to set input EOS on %s: %s\n",
      __func__, ddrivePortName, pasynUser_->errorMessage);
  }

  status = pasynOctetSyncIO->setOutputEos(pasynUser_, "\r", 1);
  if (status) {
    asynPrint(pasynUser_, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
      "%s: Unable to set output EOS on %s: %s\n",
      __func__, ddrivePortName, pasynUser_->errorMessage);
  }

  // Create the axis objects
  for (axis=0; axis<numAxes; axis++) {
    //pAxis = 
    new ddriveAxis(this, axis);
  }
  startPoller(movingPollPeriod/1000., idlePollPeriod/1000., 2);
}
Esempio n. 7
0
/** Creates a new HXPController object.
  * \param[in] portName          The name of the asyn port that will be created for this driver
  * \param[in] IPAddress         The Newport hexapod controller's ip address
  * \param[in] IPPort            TCP/IP port used to communicate with the hexapod controller 
  * \param[in] movingPollPeriod  The time between polls when any axis is moving 
  * \param[in] idlePollPeriod    The time between polls when no axis is moving 
  */
HXPController::HXPController(const char *portName, const char *IPAddress, int IPPort,
                                 double movingPollPeriod, double idlePollPeriod)
  :  asynMotorController(portName, NUM_AXES, NUM_HXP_PARAMS, 
                         0, // No additional interfaces beyond those in base class
                         0, // No additional callback interfaces beyond those in base class
                         ASYN_CANBLOCK | ASYN_MULTIDEVICE, 
                         1, // autoconnect
                         0, 0)  // Default priority and stack size
{
  int axis;
  HXPAxis *pAxis;
  static const char *functionName = "HXPController::HXPController";

  axisNames_ = epicsStrDup("XYZUVW");

  IPAddress_ = epicsStrDup(IPAddress);
  IPPort_ = IPPort;

  createParam(HXPMoveCoordSysString,          asynParamInt32,   &HXPMoveCoordSys_);
  createParam(HXPStatusString,                asynParamInt32,   &HXPStatus_);
  createParam(HXPErrorString,                 asynParamInt32,   &HXPError_);
  createParam(HXPErrorDescString,             asynParamOctet,   &HXPErrorDesc_);
  createParam(HXPMoveAllString,               asynParamInt32,   &HXPMoveAll_);
  createParam(HXPMoveAllTargetXString,        asynParamFloat64, &HXPMoveAllTargetX_);
  createParam(HXPMoveAllTargetYString,        asynParamFloat64, &HXPMoveAllTargetY_);
  createParam(HXPMoveAllTargetZString,        asynParamFloat64, &HXPMoveAllTargetZ_);
  createParam(HXPMoveAllTargetUString,        asynParamFloat64, &HXPMoveAllTargetU_);
  createParam(HXPMoveAllTargetVString,        asynParamFloat64, &HXPMoveAllTargetV_);
  createParam(HXPMoveAllTargetWString,        asynParamFloat64, &HXPMoveAllTargetW_);
  createParam(HXPCoordSysReadAllString,       asynParamInt32,   &HXPCoordSysReadAll_);
  createParam(HXPCoordSysToolXString,         asynParamFloat64, &HXPCoordSysToolX_);
  createParam(HXPCoordSysToolYString,         asynParamFloat64, &HXPCoordSysToolY_); 
  createParam(HXPCoordSysToolZString,         asynParamFloat64, &HXPCoordSysToolZ_); 
  createParam(HXPCoordSysToolUString,         asynParamFloat64, &HXPCoordSysToolU_); 
  createParam(HXPCoordSysToolVString,         asynParamFloat64, &HXPCoordSysToolV_); 
  createParam(HXPCoordSysToolWString,         asynParamFloat64, &HXPCoordSysToolW_); 
  createParam(HXPCoordSysWorkXString,         asynParamFloat64, &HXPCoordSysWorkX_); 
  createParam(HXPCoordSysWorkYString,         asynParamFloat64, &HXPCoordSysWorkY_);
  createParam(HXPCoordSysWorkZString,         asynParamFloat64, &HXPCoordSysWorkZ_);
  createParam(HXPCoordSysWorkUString,         asynParamFloat64, &HXPCoordSysWorkU_);
  createParam(HXPCoordSysWorkVString,         asynParamFloat64, &HXPCoordSysWorkV_);
  createParam(HXPCoordSysWorkWString,         asynParamFloat64, &HXPCoordSysWorkW_);
  createParam(HXPCoordSysBaseXString,         asynParamFloat64, &HXPCoordSysBaseX_);
  createParam(HXPCoordSysBaseYString,         asynParamFloat64, &HXPCoordSysBaseY_);
  createParam(HXPCoordSysBaseZString,         asynParamFloat64, &HXPCoordSysBaseZ_);
  createParam(HXPCoordSysBaseUString,         asynParamFloat64, &HXPCoordSysBaseU_);
  createParam(HXPCoordSysBaseVString,         asynParamFloat64, &HXPCoordSysBaseV_);
  createParam(HXPCoordSysBaseWString,         asynParamFloat64, &HXPCoordSysBaseW_);
  createParam(HXPCoordSysSetString,           asynParamInt32,   &HXPCoordSysSet_);
  createParam(HXPCoordSysToSetString,         asynParamInt32,   &HXPCoordSysToSet_);
  createParam(HXPCoordSysSetXString,          asynParamFloat64, &HXPCoordSysSetX_);
  createParam(HXPCoordSysSetYString,          asynParamFloat64, &HXPCoordSysSetY_);
  createParam(HXPCoordSysSetZString,          asynParamFloat64, &HXPCoordSysSetZ_);
  createParam(HXPCoordSysSetUString,          asynParamFloat64, &HXPCoordSysSetU_);
  createParam(HXPCoordSysSetVString,          asynParamFloat64, &HXPCoordSysSetV_);
  createParam(HXPCoordSysSetWString,          asynParamFloat64, &HXPCoordSysSetW_);

  // This socket is used for polling by the controller and all axes
  pollSocket_ = HXPTCP_ConnectToServer((char *)IPAddress, IPPort, HXP_POLL_TIMEOUT);
  if (pollSocket_ < 0) {
    printf("%s:%s: error calling TCP_ConnectToServer for pollSocket\n",
           driverName, functionName);
  }
  
  HXPFirmwareVersionGet(pollSocket_, firmwareVersion_);

  for (axis=0; axis<NUM_AXES; axis++) {
    pAxis = new HXPAxis(this, axis);
  }

  startPoller(movingPollPeriod, idlePollPeriod, 2);

}