Updated the Phytron driver to use MsgTxt

Updated the Phytron driver to use a selector in order to support the use case of multiple phytrons on one channel
The chnages still need to be tested
This commit is contained in:
2019-01-08 09:41:34 +01:00
parent 460030e410
commit f909c41a2b
4 changed files with 67 additions and 34 deletions

View File

@ -5,3 +5,11 @@ pattern
{KM36:phytron:, 1, "m$(N)", "asynMotor", phy, 1, "m1", mm, Pos, 2.0, 0.1, .2, 0, 1, .2, .001, 3, 100, -100, "1"} {KM36:phytron:, 1, "m$(N)", "asynMotor", phy, 1, "m1", mm, Pos, 2.0, 0.1, .2, 0, 1, .2, .001, 3, 100, -100, "1"}
{KM36:phytron:, 2, "m$(N)", "asynMotor", phy, 2, "m2", mm, Pos, 2.0, 0.1, .2, 0, 1, .2, .001, 3, 100, -100, "10"} {KM36:phytron:, 2, "m$(N)", "asynMotor", phy, 2, "m2", mm, Pos, 2.0, 0.1, .2, 0, 1, .2, .001, 3, 100, -100, "10"}
} }
file "$(SINQ)/Db/motorMessage.db"
{
pattern
{P,N, M,PORT}
{KM36:phytron:, 1, "m$(N)",phy}
{KM36:phytron:, 2, "m$(N)",phy}
}

View File

@ -30,7 +30,7 @@ sinqEPICS_registerRecordDeviceDriver pdbbase
#drvAsynIPPortConfigure("serial1", "narziss-ts:3002",0,0,0) #drvAsynIPPortConfigure("serial1", "narziss-ts:3002",0,0,0)
#drvAsynIPPortConfigure("serial1", "localhost:5050",0,0,0) #drvAsynIPPortConfigure("serial1", "localhost:5050",0,0,0)
drvAsynIPPortConfigure("serial1", "localhost:8080",0,0,0) drvAsynIPPortConfigure("serial1", "localhost:8080",0,0,0)
PhytronCreateController("phy","serial1",1,1); PhytronCreateController("phy","serial1","0",1,1);
### Motors ### Motors

View File

@ -23,6 +23,12 @@ Though this driver has been written in 2016, the MCC-2 version used is probably
Mark Koennecke Mark Koennecke
September 2016 September 2016
Updated to use the new MsgTxt field through SINQAxis
Added a selector to support multiple phytrons on a connection
Mark Koennecke
January 2019
*/ */
@ -49,19 +55,17 @@ September 2016
* \param[in] PhytronPortName The name of the drvAsynSerialPort that was created previously to connect to the Phytron controller * \param[in] PhytronPortName The name of the drvAsynSerialPort that was created previously to connect to the Phytron controller
* \param[in] numAxes The number of axes that this controller supports * \param[in] numAxes The number of axes that this controller supports
*/ */
PhytronController::PhytronController(const char *portName, const char *PhytronPortName, int encX, int encY) PhytronController::PhytronController(const char *portName, const char *PhytronPortName, const char *sel ,
: asynMotorController(portName, 3, 0, int encX, int encY)
0, // No additional interfaces beyond those in base class : SINQController(portName, PhytronPortName,2)
0, // No additional callback interfaces beyond those in base class
ASYN_CANBLOCK | ASYN_MULTIDEVICE,
1, // autoconnect
0, 0) // Default priority and stack size
{ {
asynStatus status; asynStatus status;
PhytronAxis *pAxis; PhytronAxis *pAxis;
static const char *functionName = "PhytronController::PhytronController"; static const char *functionName = "PhytronController::PhytronController";
char etx[2]; char etx[2];
selector = strdup(sel);
/* Connect to Phytron controller */ /* Connect to Phytron controller */
status = pasynOctetSyncIO->connect(PhytronPortName, 0, &pasynUserController_, NULL); status = pasynOctetSyncIO->connect(PhytronPortName, 0, &pasynUserController_, NULL);
if (status) { if (status) {
@ -87,10 +91,11 @@ PhytronController::PhytronController(const char *portName, const char *PhytronPo
* \param[in] PhytronPortName The name of the drvAsynIPPPort that was created previously to connect to the Phytron controller * \param[in] PhytronPortName The name of the drvAsynIPPPort that was created previously to connect to the Phytron controller
* \param[in] numAxes The number of axes that this controller supports * \param[in] numAxes The number of axes that this controller supports
*/ */
extern "C" int PhytronCreateController(const char *portName, const char *PhytronPortName, int encX, int encY) extern "C" int PhytronCreateController(const char *portName, const char *PhytronPortName, const char *selector,
int encX, int encY)
{ {
PhytronController *pPhytronController PhytronController *pPhytronController
= new PhytronController(portName, PhytronPortName, encX, encY); = new PhytronController(portName, PhytronPortName,selector, encX, encY);
pPhytronController = NULL; pPhytronController = NULL;
return(asynSuccess); return(asynSuccess);
} }
@ -176,7 +181,7 @@ asynStatus PhytronController::transactController(char command[COMLEN], char repl
I may need to replace the ETX. But I am not sure if asyn did I may need to replace the ETX. But I am not sure if asyn did
not remove it for me. not remove it for me.
*/ */
strncat(reply,pPtr,sizeof(reply)); strncat(reply,pPtr,COMLEN-1);
return status; return status;
@ -191,7 +196,7 @@ asynStatus PhytronController::transactController(char command[COMLEN], char repl
* Initializes register numbers, etc. * Initializes register numbers, etc.
*/ */
PhytronAxis::PhytronAxis(PhytronController *pC, int axisNo, int enc) PhytronAxis::PhytronAxis(PhytronController *pC, int axisNo, int enc)
: asynMotorAxis(pC, axisNo), : SINQAxis(pC, axisNo),
pC_(pC) pC_(pC)
{ {
encoder = enc; encoder = enc;
@ -229,15 +234,17 @@ asynStatus PhytronAxis::move(double position, int relative, double minVelocity,
//static const char *functionName = "PhytronAxis::move"; //static const char *functionName = "PhytronAxis::move";
char command[COMLEN], reply[COMLEN]; char command[COMLEN], reply[COMLEN];
updateMsgTxtFromDriver("");
if (relative) { if (relative) {
position += this->position; position += this->position;
} }
homing = 0; homing = 0;
sprintf(command, "0%cA%f", phytronChar,position/1000.); sprintf(command, "%s%cA%f", pC_->selector,phytronChar,position/1000.);
status = pC_->transactController(command,reply); status = pC_->transactController(command,reply);
if(strstr(reply,"NACK") != NULL){ if(strstr(reply,"NACK") != NULL){
errlogSevPrintf(errlogMajor, "Drive command not acknowledged on %d", axisNo_); errlogSevPrintf(errlogMajor, "Drive command not acknowledged on %d", axisNo_);
updateMsgTxtFromDriver("Drive command not acknowledged");
setIntegerParam(pC_->motorStatusProblem_, true); setIntegerParam(pC_->motorStatusProblem_, true);
return asynError; return asynError;
} }
@ -251,13 +258,16 @@ asynStatus PhytronAxis::home(double minVelocity, double maxVelocity, double acce
//static const char *functionName = "PhytronAxis::home"; //static const char *functionName = "PhytronAxis::home";
char command[COMLEN], reply[COMLEN]; char command[COMLEN], reply[COMLEN];
sprintf(command, "0%cO-",phytronChar); updateMsgTxtFromDriver("");
sprintf(command, "%s%cO-",pC_->selector,phytronChar);
homing = 1; homing = 1;
next_poll= -1; next_poll= -1;
status = pC_->transactController(command,reply); status = pC_->transactController(command,reply);
if(strstr(reply,"NACK") != NULL){ if(strstr(reply,"NACK") != NULL){
errlogSevPrintf(errlogMajor, "Home command not acknowledged on %d", axisNo_); errlogSevPrintf(errlogMajor, "Home command not acknowledged on %d", axisNo_);
setIntegerParam(pC_->motorStatusProblem_, true); setIntegerParam(pC_->motorStatusProblem_, true);
updateMsgTxtFromDriver("Home command not acknowledged");
return asynError; return asynError;
} }
return status; return status;
@ -274,6 +284,7 @@ asynStatus PhytronAxis::moveVelocity(double minVelocity, double maxVelocity, dou
// "%s: minVelocity=%f, maxVelocity=%f, acceleration=%f\n", // "%s: minVelocity=%f, maxVelocity=%f, acceleration=%f\n",
// functionName, minVelocity, maxVelocity, acceleration); // functionName, minVelocity, maxVelocity, acceleration);
updateMsgTxtFromDriver("");
if (maxVelocity > 0.) { if (maxVelocity > 0.) {
@ -294,9 +305,10 @@ asynStatus PhytronAxis::stop(double acceleration )
//static const char *functionName = "PhytronAxis::stop"; //static const char *functionName = "PhytronAxis::stop";
char command[COMLEN], reply[COMLEN]; char command[COMLEN], reply[COMLEN];
sprintf(command, "0%cSN", phytronChar); sprintf(command, "%s%cSN", pC_->selector,phytronChar);
status = pC_->transactController(command,reply); status = pC_->transactController(command,reply);
errlogPrintf("Sent STOP on Axis %d\n", axisNo_); errlogPrintf("Sent STOP on Axis %d\n", axisNo_);
updateMsgTxtFromDriver("Axis interrupted");
return status; return status;
} }
@ -307,9 +319,9 @@ asynStatus PhytronAxis::setPosition(double position)
//static const char *functionName = "PhytronAxis::setPosition"; //static const char *functionName = "PhytronAxis::setPosition";
char command[COMLEN], reply[COMLEN]; char command[COMLEN], reply[COMLEN];
sprintf(command, "0%cP22S%f", phytronChar, position/1000.); sprintf(command, "%s%cP22S%f", pC_->selector,phytronChar, position/1000.);
status = pC_->transactController(command,reply); status = pC_->transactController(command,reply);
sprintf(command, "0%cP20S%f", phytronChar, position/1000.); sprintf(command, "%s%cP20S%f", pC_->selector,phytronChar, position/1000.);
status = pC_->transactController(command,reply); status = pC_->transactController(command,reply);
next_poll = -1; next_poll = -1;
@ -349,9 +361,9 @@ asynStatus PhytronAxis::poll(bool *moving)
// Read the current motor position // Read the current motor position
if(encoder) { if(encoder) {
sprintf(command,"0%cP22R",phytronChar); sprintf(command,"%s%cP22R",pC_->selector,phytronChar);
} else { } else {
sprintf(command,"0%cP20R",phytronChar); sprintf(command,"%s%cP20R",pC_->selector,phytronChar);
} }
comStatus = pC_->transactController(command,reply); comStatus = pC_->transactController(command,reply);
@ -360,7 +372,8 @@ asynStatus PhytronAxis::poll(bool *moving)
if(strstr(reply,"NACK") != NULL){ if(strstr(reply,"NACK") != NULL){
setIntegerParam(pC_->motorStatusProblem_, true); setIntegerParam(pC_->motorStatusProblem_, true);
errlogSevPrintf(errlogMajor, "Bad reply for position on %d", axisNo_); errlogSevPrintf(errlogMajor, "Bad reply for position on %d", axisNo_);
goto skip; updateMsgTxtFromDriver("Bad reply reading position");
goto skip;
} }
/* /*
read over the ACK read over the ACK
@ -372,7 +385,7 @@ asynStatus PhytronAxis::poll(bool *moving)
// Read the moving status of this motor // Read the moving status of this motor
sprintf(command,"0%c=H",phytronChar); sprintf(command,"%s%c=H",pC_->selector,phytronChar);
comStatus = pC_->transactController(command,reply); comStatus = pC_->transactController(command,reply);
if(comStatus) goto skip; if(comStatus) goto skip;
/* errlogPrintf("Axis %d, status reply %s, position %lf\n", axisNo_, reply, position); */ /* errlogPrintf("Axis %d, status reply %s, position %lf\n", axisNo_, reply, position); */
@ -396,11 +409,12 @@ asynStatus PhytronAxis::poll(bool *moving)
/* /*
check limits and errors, upper check limits and errors, upper
*/ */
sprintf(command,"0%c=I+",phytronChar); sprintf(command,"%s%c=I+",pC_->selector,phytronChar);
comStatus = pC_->transactController(command,reply); comStatus = pC_->transactController(command,reply);
if(comStatus) goto skip; if(comStatus) goto skip;
if(strstr(reply,"ACKE") != NULL){ if(strstr(reply,"ACKE") != NULL){
setIntegerParam(pC_->motorStatusHighLimit_, true); setIntegerParam(pC_->motorStatusHighLimit_, true);
updateMsgTxtFromDriver("High Limit Hit");
} else { } else {
setIntegerParam(pC_->motorStatusHighLimit_, false); setIntegerParam(pC_->motorStatusHighLimit_, false);
} }
@ -408,11 +422,12 @@ asynStatus PhytronAxis::poll(bool *moving)
/* /*
lower limit lower limit
*/ */
sprintf(command,"0%c=I-",phytronChar); sprintf(command,"%s%c=I-",pC_->selector,phytronChar);
comStatus = pC_->transactController(command,reply); comStatus = pC_->transactController(command,reply);
if(comStatus) goto skip; if(comStatus) goto skip;
if(strstr(reply,"ACKE") != NULL){ if(strstr(reply,"ACKE") != NULL){
setIntegerParam(pC_->motorStatusLowLimit_, true); setIntegerParam(pC_->motorStatusLowLimit_, true);
updateMsgTxtFromDriver("Low Limit Hit");
} else { } else {
setIntegerParam(pC_->motorStatusLowLimit_, false); setIntegerParam(pC_->motorStatusLowLimit_, false);
} }
@ -420,12 +435,13 @@ asynStatus PhytronAxis::poll(bool *moving)
/* /*
error error
*/ */
sprintf(command,"0%c=E",phytronChar); sprintf(command,"%s%c=E",pC_->selector,phytronChar);
comStatus = pC_->transactController(command,reply); comStatus = pC_->transactController(command,reply);
if(comStatus) goto skip; if(comStatus) goto skip;
if(strstr(reply,"ACKE") != NULL){ if(strstr(reply,"ACKE") != NULL){
setIntegerParam(pC_->motorStatusProblem_, true); setIntegerParam(pC_->motorStatusProblem_, true);
errlogSevPrintf(errlogMajor, "Electronics on %d", axisNo_); errlogSevPrintf(errlogMajor, "Electronics on %d", axisNo_);
updateMsgTxtFromDriver("Electronics error");
} else { } else {
setIntegerParam(pC_->motorStatusProblem_, false); setIntegerParam(pC_->motorStatusProblem_, false);
} }
@ -442,16 +458,18 @@ asynStatus PhytronAxis::poll(bool *moving)
/** Code for iocsh registration */ /** Code for iocsh registration */
static const iocshArg PhytronCreateControllerArg0 = {"Port name", iocshArgString}; static const iocshArg PhytronCreateControllerArg0 = {"Port name", iocshArgString};
static const iocshArg PhytronCreateControllerArg1 = {"Phytron port name", iocshArgString}; static const iocshArg PhytronCreateControllerArg1 = {"Phytron port name", iocshArgString};
static const iocshArg PhytronCreateControllerArg2 = {"EnoderX", iocshArgInt}; static const iocshArg PhytronCreateControllerArg2 = {"Phytron Selector", iocshArgString};
static const iocshArg PhytronCreateControllerArg3 = {"EnoderY", iocshArgInt}; static const iocshArg PhytronCreateControllerArg3 = {"EnoderX", iocshArgInt};
static const iocshArg PhytronCreateControllerArg4 = {"EnoderY", iocshArgInt};
static const iocshArg * const PhytronCreateControllerArgs[] = {&PhytronCreateControllerArg0, static const iocshArg * const PhytronCreateControllerArgs[] = {&PhytronCreateControllerArg0,
&PhytronCreateControllerArg1, &PhytronCreateControllerArg1,
&PhytronCreateControllerArg2, &PhytronCreateControllerArg2,
&PhytronCreateControllerArg3}; &PhytronCreateControllerArg3,
static const iocshFuncDef PhytronCreateControllerDef = {"PhytronCreateController", 4, PhytronCreateControllerArgs}; &PhytronCreateControllerArg4};
static const iocshFuncDef PhytronCreateControllerDef = {"PhytronCreateController", 5, PhytronCreateControllerArgs};
static void PhytronCreateContollerCallFunc(const iocshArgBuf *args) static void PhytronCreateContollerCallFunc(const iocshArgBuf *args)
{ {
PhytronCreateController(args[0].sval, args[1].sval, args[2].ival,args[3].ival); PhytronCreateController(args[0].sval, args[1].sval, args[2].sval, args[3].ival,args[4].ival);
} }
static void PhytronRegister(void) static void PhytronRegister(void)

View File

@ -5,14 +5,19 @@ USAGE... Motor driver support for the Phytron MCC-2 motor controller.
Mark Koennecke Mark Koennecke
September 2016 September 2016
Updated to go through SINQAxis for -MsgTxt support
Added a selector to support multiple phytrons on a connection
Mark Koennecke, January 2019
*/ */
#include "asynMotorController.h" #include "SINQController.h"
#include "asynMotorAxis.h" #include "SINQAxis.h"
#define COMLEN 80 #define COMLEN 80
class PhytronAxis : public asynMotorAxis class PhytronAxis : public SINQAxis
{ {
public: public:
/* These are the methods we override from the base class */ /* These are the methods we override from the base class */
@ -38,9 +43,10 @@ private:
friend class PhytronController; friend class PhytronController;
}; };
class PhytronController : public asynMotorController { class PhytronController : public SINQController {
public: public:
PhytronController(const char *portName, const char *PhytronPortName, int encX, int encY); PhytronController(const char *portName, const char *PhytronPortName, const char *selector,
int encX, int encY);
void report(FILE *fp, int level); void report(FILE *fp, int level);
PhytronAxis* getAxis(asynUser *pasynUser); PhytronAxis* getAxis(asynUser *pasynUser);
@ -52,5 +58,6 @@ friend class PhytronAxis;
asynStatus transactController(char command[COMLEN], char reply[COMLEN]); asynStatus transactController(char command[COMLEN], char reply[COMLEN]);
const char *selector;
}; };