Hello EPICS-community,
I'm trying to write an EPICS-motor device support for the PEGASUS Rotation- and Linear-Stages from Micos. I'm using the Hydra and Corvus motor-support
from the main EPICS-motor module as a template.
I have the following problem when writing the homing sequence for the Rotation-stages: after sending the homing-command string
sprintf(pC_->outString_, "1 0 %i setsw 1 1 %i setsw 1 0 %i sncal", (axisNo_ + 1), (axisNo_ + 1), (axisNo_ + 1));
pC_->writeController();
I need to wait until reference-drive finished aka. the motor stopped, so I can switch off the Limit-switches with the following command:
sprintf(pC_->outString_, "2 0 %i setsw 2 1 %i setsw", (axisNo_ + 1), (axisNo_ + 1));
pC_->writeController();
So far I could resolve this problem by implementing a while loop with an epicsThreadSleep(1.) asking the controller about its moving bit and once it
set to 1 (done), execute the desired command. Here is my complete code of the homing function:
asynStatus SMCpegasusAxis::home(double baseVelocity, double slewVelocity, double acceleration, int forwards)
{
asynStatus status;
int done = 0;
int axisStatus = -1;
double position = 0.0;
// static const char *functionName = "SMCpegasusAxis::home";
status = sendAccelAndVelocity(acceleration, slewVelocity);
if (forwards) {
sprintf(pC_->outString_, "1 0 %i setsw 1 1 %i setsw 1 0 %i sncal", (axisNo_ + 1), (axisNo_ + 1), (axisNo_ + 1));
pC_->writeController();
// Read the status of this motor
sprintf(pC_->outString_, "%i nst", (axisNo_ + 1));
pC_->writeReadController();
// The response string is an int
axisStatus = atoi( (char *) &pC_->inString_);
do
{
// Read the current motor position
sprintf(pC_->outString_, "%i np", (axisNo_ + 1));
pC_->writeReadController();
// The response string is a double
position = atof( (char *) &pC_->inString_);
setDoubleParam(pC_->motorPosition_, (position / axisRes_) );
setDoubleParam(pC_->motorEncoderPosition_, (position / axisRes_) );
// Read the status of this motor
sprintf(pC_->outString_, "%i nst", (axisNo_ + 1));
pC_->writeReadController();
// The response string is an int
axisStatus = atoi( (char *) &pC_->inString_);
// Check the moving bit
done = !(axisStatus & 0x1);
setIntegerParam(pC_->motorStatusDone_, done);
setIntegerParam(pC_->motorStatusMoving_, !done);
epicsThreadSleep(1.);
} while (done == 0);
//epicsThreadSleep(3.);
sprintf(pC_->outString_, "2 0 %i setsw 2 1 %i setsw", (axisNo_ + 1), (axisNo_ + 1));
} else {
//still ToDo the Home Run backward
}
status = pC_->writeController();
return status;
}
Having a while-loop with an threadSleep is kind of bad coding I think, so I'm wondering if someone knows a better solution?
PS: I'm also trying to update the motor position during the while-loop (it is the "// Read the current motor position" passage). I see the correct position
in the asyn communication but the .RBV value of the motor record won't update. I guess, this can only be done from the poll-function?
Best regards
Michael
Michael Sintschuk
Bundesanstalt für Materialforschung und –prüfung (BAM)
8.5 Mikro-ZfP
Unter den Eichen 87
12205 Berlin
GERMANY
P: +49 30 8062-15063 (BESSY, Adlershof)
P: +49 30 8104-4065 (BAM, Steglitz)
michael.sintschuk at bam.de