Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

E-727 and Closed Loop Control commands #10

Merged
merged 2 commits into from
Aug 11, 2022

Conversation

AugustoHorita
Copy link

I am working with the PIE727 module and couldn't find support for gains and notch configuration.
I implemented this code which works for us. I created a new class for PIE727 and also a header file with Closed Loop parameters and necessary structures. Included functions to set the CL parameters, and put the read function for these parameters in the poll thread.

There is a bug though, which I noticed also previously (also without this modification). If I use the asynRecord communication with the PI module, the poll thread starts to get timeouts for getting RAM parameters ("SPA?" commands) and position ("POS" commands) as soon as I set the ".OEOS" field in the asynRecord. I was thinking of maybe implementing a semaphore for this communication. (not yet done)

@kmpeters
Copy link
Contributor

I am working with the PIE727 module and couldn't find support for gains and notch configuration.
I implemented this code which works for us. I created a new class for PIE727 and also a header file with Closed Loop parameters and necessary structures. Included functions to set the CL parameters, and put the read function for these parameters in the poll thread.

@JensKappPI and @PI-SRau, should Augusto's changes be E-727-specific or would they also apply to the other piezo controllers support by motorPIGCS2?:

else if ( strstr(szIDN, "E-753") != NULL
|| strstr(szIDN, "E-754") != NULL
|| strstr(szIDN, "E-709") != NULL
|| strstr(szIDN, "E-712") != NULL
|| strstr(szIDN, "E-725") != NULL
|| strstr(szIDN, "E-727") != NULL
)
{
return new PIGCSPiezoController(pInterface, szIDN);

@kmpeters
Copy link
Contributor

kmpeters commented Aug 10, 2022

There is a bug though, which I noticed also previously (also without this modification). If I use the asynRecord communication with the PI module, the poll thread starts to get timeouts for getting RAM parameters ("SPA?" commands) and position ("POS" commands) as soon as I set the ".OEOS" field in the asynRecord. I was thinking of maybe implementing a semaphore for this communication. (not yet done)

This problem is due to design decisions for handling both single-character commands that don't have a terminator and multi-character commands that require a terminator.

The driver sets the asyn records output end-of-string to an empty string in PIasynController.cpp and expects that to not change:

status = pasynOctetSyncIO->setOutputEos(pAsynCom, "", 0);
if (status) {
asynPrint(pAsynCom, ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
"echoHandler: unable to set output EOS on %s: %s\n",
asynPort, pAsynCom->errorMessage);
return;
}

The sendAndReceive method of the PIInterface class is overloaded. If sendAndReceive is passed a C string, like when the version string is queried:

status = pInterface->sendAndReceive("*IDN?", inputBuff, 255, pAsynCom);

Then the sendAndReceive method that is called adds a new line character:

status = pasynOctetSyncIO->writeRead(m_pAsynInterface,
"\n", 1,
inputBuff, inputSize,
TIMEOUT, &nWrite, &nRead, &eomReason);

If sendAndReceive is passed a char instead, like when the moving status is polled:

asynStatus status = m_pInterface->sendAndReceive(char(5), buf, 99);;

Then the sendAndReceive method that is called does NOT add any end-of-string characters:

asynStatus PIInterface::sendAndReceive(char c, char *inputBuff, int inputSize, asynUser* logSink)
{
size_t nWrite, nRead;
int eomReason;
asynStatus status;
size_t pos = 0;
asynPrint(logSink, ASYN_TRACEIO_DRIVER,
"PIInterface::sendAndReceive() sending \"#%d\"\n", int(c));
//printf("PIInterface::sendAndReceive() sending \"#%d\"\n", int(c));
status = pasynOctetSyncIO->writeRead(m_pAsynInterface,
&c, 1,
inputBuff, inputSize,
TIMEOUT, &nWrite, &nRead, &eomReason);
if (nWrite != 1)
status = asynError;
if (status != asynSuccess)
{
asynPrint(logSink, ASYN_TRACE_ERROR|ASYN_TRACEIO_DRIVER,
"PIInterface::sendAndReceive error calling writeRead, output=%d status=%d, error=%s\n",
int(c), status, m_pAsynInterface->errorMessage);
//printf("PIInterface::sendAndReceive error calling writeRead, output=%d status=%d, error=%s\n", int(c), status, pInterface->errorMessage);
}
while(inputBuff[strlen(inputBuff)-1] == ' ')
{
pos += nRead;
status = pasynOctetSyncIO->writeRead(m_pAsynInterface,
&c, 1,
inputBuff+pos, inputSize-pos,
TIMEOUT, &nWrite, &nRead, &eomReason);
//printf("PIInterface::sendAndReceive(char) in while loop. inputBuff: \"%s\"\n", inputBuff);
}
asynPrint(logSink, ASYN_TRACEIO_DRIVER,
"PIInterface::sendAndReceive() received \"%s\"\n", inputBuff);
//printf("PIInterface::sendAndReceive() received \"%s\" - (0x%02X)\n", inputBuff, int(inputBuff[0]));
return(status);
}

@kmpeters
Copy link
Contributor

kmpeters commented Aug 10, 2022

There is a bug though, which I noticed also previously (also without this modification). If I use the asynRecord communication with the PI module, the poll thread starts to get timeouts for getting RAM parameters ("SPA?" commands) and position ("POS" commands) as soon as I set the ".OEOS" field in the asynRecord. I was thinking of maybe implementing a semaphore for this communication. (not yet done)

@AugustoHorita, are you able to send commands like SPA? to the controller from the asyn record without causing driver errors by leaving the OEOS blank and instead adding a \n to the end of command in the AOUT field? Sending SPA?\n is much less intuitive, but if it works that could eliminate the need to change the driver further (and possibly introduce new bugs).

@AugustoHorita
Copy link
Author

There is a bug though, which I noticed also previously (also without this modification). If I use the asynRecord communication with the PI module, the poll thread starts to get timeouts for getting RAM parameters ("SPA?" commands) and position ("POS" commands) as soon as I set the ".OEOS" field in the asynRecord. I was thinking of maybe implementing a semaphore for this communication. (not yet done)

@AugustoHorita, are you able to send commands like SPA? to the controller from the asyn record without causing driver errors by leaving the OEOS blank and instead adding a \n to the end of command in the AOUT field? Sending SPA?\n is much less intuitive, but if it works that could eliminate the need to change the driver further (and possibly introduce new bugs).

First of all, @kmpeters: thanks for your feedback and detailed explanation.
I will try to send the command like you suggested and get back here to inform.

@AugustoHorita
Copy link
Author

@kmpeters...Sending the commands like you suggested worked fine! Thanks one more time for your help.

@kmpeters
Copy link
Contributor

Jens responded by email with info about the other piezo controllers:

"In general these change are valid for all piezo controllers, but there is one exception. The E-709 controller does not support the parameter 0x07030600."

Applying these features to most of the piezo controllers is outside the scope of this pull request. I'll create an issue for that.

@kmpeters
Copy link
Contributor

kmpeters commented Aug 11, 2022

Applying these features to most of the piezo controllers is outside the scope of this pull request. I'll create an issue for that.

The issue has been created: #11

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants