#include "siutils.h"
#include <limits.h>
Functions | |
int | SCLOpenPort (char *devname) |
Open a connection to an Si microstep drive comm port. | |
void | SCLClosePort (int portFD) |
Close an open Si microstep drive comm port. | |
int | SCLReadPort (int portFD, char *reply, long timeout) |
Read data from the Si microstep drive comm port. | |
int | SCLSendQuery (int portFD, char *sclCmd, char *sclVal, long timeout) |
Query the Si microstep drive for the value of a parameter. | |
int | SCLSendCommand (int portFD, char *sclCmd, char *errstr) |
Send a command to the Si microstep drive. | |
int | SCLReqStatus (int portFD, char *errstr, long timeout) |
Query the Si microstep drive for the request status. | |
int | SCLGetPos (int portFD, char *errstr, long timeout) |
Query the Si microstep drive for the immediate absolute position (IP ). | |
int | SCLGetDist (int portFD, char *errstr, long timeout) |
Query the Si microstep drive for the immediate distance (ID ). | |
int | SCLInStatus (int portFD, char *bitstr, long timeout) |
Query the Si microstep drive for the Input Status (IS ). | |
int | SCLReadStatus (char *bitstr, int *inbits, int ndata, char *ismask) |
Read and interpret a controller Input Status (IS) bit string. | |
void | SCLAbort (int portFD) |
Abort a move (Stop/Kill). | |
int | SCLGetParams (int portFD, si_drivepars_t *dpars, char *reply, long timeout) |
Query the Si microstep drive for all drive parameters. | |
int | SCLHexToInt (char *hexstr) |
Convert Hexadecimal output from an Si microstep drive to decimal. | |
char * | SCLStatus (int status) |
Convert SCL mechanism status codes into text. | |
int | SCLSleep (long msec) |
Pause execution for a certain number of milliseconds. | |
double | SCLTimeStamp (void) |
Create a numerical timestamp by reading the system clock. | |
void | SCLUpper (char *str) |
Convert all characters in a string to uppercase. |
These functions handle basic serial port communications, creation and parsing of valid SCL command strings, reply handling, and basic low-level functions useful for working with the Applied Motion Product Si family of microstep stepper-motor controllers.
Designed to be self-contained, without dependences on any other OSU (or other) libraries.
The actual motion routines are the MechXXX functions, implemented in mechanism.c. They use a common mechanism configuration struct, si_mechanism. A very large number of possible mechanism configurations are encapsulated within this struct and set of functions.
|
Open a connection to an Si microstep drive comm port.
/dev/ttyXX# = regular serial port (tty port) host:port = network serial port server address (IP and port #).The former is for a microstep drive connected to a direct serial port, or to a virtual serial port (e.g., on a remote terminal server like a Comtrol DeviceMaster RTS using a virtual serial port device driver). The latter is for a direct network socket connection to a remote serial port server (e.g., a Comtrol RTS configured as a socket server). For socket communications with a network serial port server, we use INET streams (SOCK_STREAM) with a persistent client connection. This is pretty much standard for most devices on the market. For a regular serial port, we set the attributes to 9600 baud, 8 data bits, 1 stop bit, and no parity as required by the Si microstep drive's serial port.
|
|
Close an open Si microstep drive comm port.
|
|
Read data from the Si microstep drive comm port.
|
|
Query the Si microstep drive for the value of a parameter.
|
|
Send a command to the Si microstep drive.
In general, an application would send a command, then send a query to check up on it. We don't place that burder on this routine since not all commands have query versions (i.e., they do not generate a response from the microstep drive when sent with no arguments).
|
|
Query the Si microstep drive for the request status.
RS (Request Status) command to ask what it is doing right now. The RS command returns one of 5 responses: R = microstep drive ready (to receive commands) M = move in progress W = wait input (WI) command executing T = wait time (WT) command executing (aka, a sleep) E = servo positioning fault, requires power cycling to clear (bad)These are translated into integer codes, defined in siutils.h as follows:
RS is different from all other SCL queries in that it does not return an keyword=value pair, but just the value, hence it requires a separate handler. This function is provided to help applications monitor the progress of long moves. It would be called in a polling loop to monitor progress in a simple way (i.e., moving/not). |
|
Query the Si microstep drive for the immediate absolute position (
IP (Immediate Position) query. This returns the immediate position as a hexadecimal-coded string. This function converts this string into an integer to return to the calling application using SCLHexToInt(). This function is useful for monitoring the progress of a move.
|
|
Query the Si microstep drive for the immediate distance (
ID (Immediate Distance) query. This returns the immediate distance as a hexadecimal-coded string. This function converts this string into an integer to return to the calling application using SCLHexToInt(). This function is useful for monitoring the progress of a move.
|
|
Query the Si microstep drive for the Input Status (
IS (Input Status) query. This returns a string in bitstr with 1s and 0s. The order of the bits returned is the same as that received from the controller: IS=10000001 |||||||| |||||||+- IN1 ||||||+-- IN2 |||||+--- IN3 ||||+---- IN4 |||+----- IN5 (or cw jog if enabled) ||+------ IN6 (or ccw jog if enabled) |+------- IN7 (cw limit - RESERVED) +-------- IN8 (ccw limit - RESERVED)The SCLReadStatus() function is provided to parse this string into an integer array of 0/1 flags making it more useful for applications. Unless the calling application is simply interested in displaying the raw input bit pattern, a call to SCLInStatus() is usually followed by a call to SCLReadStatus().
|
|
Read and interpret a controller Input Status (IS) bit string.
IS (Input Status) command, for example as returned by a call to SCLInStatus(). For example: IS=11111001 |||||||| |||||||+- IN1 ||||||+-- IN2 |||||+--- IN3 ||||+---- IN4 |||+----- IN5 (or cw jog if enabled) ||+------ IN6 (or ccw jog if enabled) |+------- IN7 (cw limit - RESERVED) +-------- IN8 (ccw limit - RESERVED) This function traverses bitstr and creates an inbits[] array of integers containing 1 if the input is asserted, 0 if the input is not asserted. The Si series of microstep controllers gives INi=0 when current is flowing through the sensor ("closed"), and INi=1 if no current is flowing ("open"). It is considered a "good practice" to connect device inputs (e.g., position encoder sensors) starting with IN1 in the order IN1=LSB ... IN(ndata)=MSB, where "ndata" is the number of data bits passed to this routine by the ndata variable. If ndata>0, the bits inbit[0] through inbit[ndata-1] are converted into a decimal integer and returned by the function, assuming IN1 = LSB and IN<ndata> = MSB for the conversion.
0 means the input is asserted (true) when INi=0 (closed) 1 means the input is asserted (true) when INi=1 (open)Beware: the order of bits in ismask is identical to the order of bits in the raw IS input string above (i.e., IN8..IN1).
ismask=00001111;IN1..IN4 is 1 if there is a hole under the proximity sensor (binary 1 = "asserted"), and 0 if there is metal under the sensor (binary 0 = "deasserted"). We mask IN5..IN8 as 0 so that they always be deasserted 0 since they are unused. The result of using this mask on the above IS string is as follows: bitstr = 11111001 ismask = 00001111 result = 00001001The final output mask makes it easy to see that only IN1 (position 1s bit) and IN4 (the in-position bit) are asserted. This means the filter wheel is in position "1". The resulting 1s and 0s are loaded into inbits[0..7] for return to the calling routine for subsequent use. Because ndata=3, the function returns 1. bitstr is replaced by the "result" string when the function returns. Without input masks we'd have to interpret each bit depending on detailed mechanism configuration in the code, greatly complicating coding. In practice, a device input mask is usually provided for the application by way of an external runtime configuration file. This obviates the need to hardcode the input mask (and thus obviating the need to recompile to make changes to the mask).
|
|
Abort a move (Stop/Kill).
SK (Stop/Kill) command. This will abort the motion in progress and clear any pending move commands from the command buffer. This is a simple wrapper for the SK command. It uses a low-level write() call to the specified file descriptor. No return reply is serviced.
Note that it is harmless to send an |
|
Query the Si microstep drive for all drive parameters.
This function makes 20 queries of the drive (note that IP and SP are redundant, so only IP is called via SCLGetPos()). Since typical queries require ~40-50msec to work through the serial communications, this function takes approximately 1 second to execute.
|
|
Convert Hexadecimal output from an Si microstep drive to decimal.
IP ), the immediate distance moved (ID ), and the immediate encoder value (IE ). Because conversion from hex to an integer would tax the Si microstep drive's CPU during a move, it instead delivers a raw hexadecimal value and expects (rightly) that the calling application can do the conversion trivially.Well, not so trivial, there is a sign offset that must be dealt with. This function handles that conversion transparently. It requires that the limits.h header be included.
This function assumes that hexstr is raw SCL format hex output of the form This function is used internally by the SCLGetPos() and SCLGetDist() functions. |
|
Convert SCL mechanism status codes into text.
|
|
Pause execution for a certain number of milliseconds.
See "man 2 nanosleep" for details on the nanosleep() function. |
|
Create a numerical timestamp by reading the system clock.
Note that while the precision is in microseconds, accuracy is quite a different question... |
|
Convert all characters in a string to uppercase.
|