The following is from the "ServoDoc.pdf" provided by Sitech in support of their controller, and from and correspondence wth Dan Gray. USB to Serial ============= The chip is an FTDI IC that makes the controller appear as a serial port on the host computer. The default baud rate is 19.2kb between the controller and the USB-to-Serial converter. Code snippet for motor rates ============================ internal static double DegsPerSec2MotorSpeed(double dps, double TicksPerRev) { return Math.Round(TicksPerRev * dps * 0.09321272116971); } internal static double MotorSpeed2DegsPerSec(double Speed, double TicksPerRev) { if (TicksPerRev == 0.0) TicksPerRev= 1.0; return Speed/TicksPerRev*10.7281494140625; } internal const double SiderealConstant = 0.00038942519; internal static double TicksPerRev2SiderealRate(double TicksPerRev) { return Math.Round(TicksPerRev * SiderealConstant); } The serial port routine in the controller takes a "snapshot" of all 4 encoders, at a single moment, so the information you have with the binary protocol is for a single moment in time. You have to do whatever you need to do to cascade the motor location to make the scope encoder location accurate. Look below for information about XXS XXR YXR Controller communication protocol ================================= The following is the ASCII protocol documented on the Sitech website. The binary protocol is described at the end of this file. List of ASCII commands (all get terminated with an ). Note in Sitech's document they refer to CR as . However, CR is 0dh, decimal 13, or "\r" in a C string so take care not to be confused by this in the following. CR is the requisit terminator for most ASCII controller commands. We use here to represent this return. Be sure to use upper case. For the Azimuth or Right Ascension servo, use 'Y' instead of 'X' The # symbol means there is a number required. The X servo is the Altitude or Declination. The Y servo is the Azimuth or Right Ascension. If you change the Address of the controller AD1, AD3, or AD5, the controller will respond differently. If the address is 3, then all beginning X's should be T's, and beginning Y's should be U's. If you've changed your address to Address 5, then use V and W for X and Y. To change the address of a controller from the default (1) to (2), send the byte sequence: AD2 (Make sure any other controllers are not connected to the serial port first). If you want to make this permanent, you will have to write to the flash ROM. This would normally be the XW command, but since the controller address is 2 now, you would issue the command TW. If the controller is Address 1, and if you send an with nothing before it, the controller responds with a lot of useful information as follows: X# Y# XZ# YZ# XC# YC# V# T# X(A or M) Y(A or M) K# Where: X# is the location of the Altitude/Dec Axis in MOTOR encoder ticks Y# is the location of the Azimuth/RA Axis in MOTOR encoder ticks XZ# is the location of the Altitude/Dec Axis in SCOPE encoder ticks YZ# is the location of the Azimuth/RA Axis in SCOPE encoder ticks XC# is the Altitude/Dec motor current * 100.0 YC# is the Azimuth/RA motor current * 100.0 V# is the controller power supply voltage * 10.0 T# is the controller CPU temperature (Deg's F ) XA (or XM) is the Altitude/Dec Motor status, if XA, it's in Auto (normal) if XM, it's in manual. YA (or YM) is the Azimuth/RA Motor status, if YA, it's in Auto (normal) if YM, it's in manual. K# is the handpad Status. (Version 1.5 and later). ASCII Commands: SB# Set Baud Rate (1 = 9600, 2 = 19200) Changes all controllers on serial bus. (1.5 or later) X# Move Servo (-2147483648 to +2147483647) You can tag a speed command at the end. Example: X-2345S1000000 X Returns the X position of the servo XF# Forces the X position to be equal to the number (-2147483648 to +2147483647) (This stops the controller if moving) XS# Velocity of X Servo (0-2147483647) XS Returns the X velocity of the servo (what it would be if it was currently moving at fully accelerated speed, this may not be what it acually is at the moment). XR# Ramping speed or Acceleration of X servo (0-3900) XR Returns the Ramp speed. XP# Proportional Band of X servo (0-32767) XP Returns the Proportional band XI# X Integral (0-32767) XI Returns the Integral XD# X Derivative (0-32767) XD Returns the Integral XE# Maximum position error limit before servo turns off (0-32767) XEL Returns position error limit. XE Returns the position error of the servo XO# X Output limit (0-255) XO Returns the PWM output of the servo (0-255) XC# X Current Limit (0-240 = 0-2.40 amps) XC Returns the X motor current * 100 (240 MAX) XM# X to manual mode, the number is the PWM value, -255 to +255 XA X to Auto mode XN X Normal Stop (ramps down, then stops. Automatically clears when new position is given) XNT Just like XN, except when it slows down enough, it starts tracking in the DragNTrack or SlewNTrack mode XG X Emergency stop (stops immediately) XL# Set Integral Limit (0-24000) XL Returns Integral Limit XB# Number sets the servo bits like direction, etc. (0-255) XB Returns current X Bits Value XZ# Forces the scope encoder position to be equal to the number (-2147483648 to +2147483647) XZ Returns the scope encoder position The following commands don't have a 'Y' command, only X. They affect both servos XK Returns the handpad info in Decimal XH Returns the temperature of the CPU chip (in deg's F) XV Returns the firmware version * 10 XJ Returns the motor power supply voltage * 10 (please divide returned number by 10) XQ Resets the servo system (both) XU Programs factory defaults into the flash ROM XW Writes the configuration of both the x and y parameters from working RAM to the flash ROM XT Reads the configuration from the Flash Rom into the working RAM FC Flash Configure, Send 128 more bytes, then 2 bytes of checksum (Simple Addition of all data bytes sent), and it will write the new data to configuration. It also reads the new data into the working RAM SC Send Configuration, The controller Sends 128 bytes, followed by two bytes of checksum. This data is what is in the flash, not necessarily what is in the working RAM. All of the following XX extended commands have a corresponding read command as an example, if you type "XXL" it responds with the latitude. XXL# Store the latitude to the controller (4500 = 45 deg's north, -4500 = 45 deg's south) XXZ# Store the azimuth encoder ticks per full circle XXT# Store the altitude encoder ticks per full circle XXU# Store the number of encoder ticks for the Altitude Motor Encoder to the controller XXV# Store the number of encoder ticks for the Azimuth Motor Encoder to the controller XXA# Stores the Altitude Slew Rate to the controller XXB# Stores the Azimuth Slew Rate to the controller XXC# Stores the Altitude Pan Rate to the controller XXD# Stores the Azimuth Pan Rate to the controller XXE# Stores the Platform tracking rate to the controller XXF# Stores the Platform up/down adjuster to the controller XXG# Stores the Platform Goal to the controller XXH# Stores the Altitude Guide Rate to the controller XXI# Stores the Azimuth Guide Rate to the controller XXJ# Stores the PicServo Timeout Value to the controller (Seconds). XXQ# Turns off or on the digital outputs of the Radio Handpad Reciever XXN# A zero turns off the Argo Navis\u2122 mode. A one turns it on. When the controller receives a 'Q' as the first character in a line, it responds emulating the Tangent Q protocol. The encoder resolution is always 18000 (the controller uses the configured values for encoder ticks per revolution for the Scope Encoders, and converts it to 18000). If you are using servo firmware version 1.6 or later, the following commands have been added: XXK# Local Search Radius in arc Minutes XXM# Local Search Speed in arc seconds per second. XXO# Altitude Backlash XXP# Azimuth Backlash New commands in version 1.7: XXW# Backlash Motor Speed (Speed while in the backlash area) Should be 200,000 to 500,000. XXX# Altitude in deg's times 100. The altitude should be sent to the controller by the host computer (ScopeII, the Ascom driver, etc) after initialization. Then the Local searches will be round, and the Pan and Guide speeds will be linear in relation to the sky (version 1.7 or later). XXY# Sets the Azimuth/RA in the controller. Not useful until version 1.8. 0AAh Puts the servo into the PicServo Emulation mode (no CR required). See http://www.jrkerr.com/psdata.pdf for a description. There are some items different, all motion control is the same. The differences are descibed below. The following two ASCII commands with Binary data are for reading and controlling the servo controller in a very efficient manner. They have been added at version 1.5 of the controller firmware. (See below for more information about the binary commands in the A200HR mount controller.) XXS The controller responds with four long ints of position, then other bytes for keypad status, X and Y Bits, and other bits as follows: Byte 0-3 Current Altitude/Dec Motor Position (most to least significant) Byte 4-7 Current Azimuth/RA Motor Position. Byte 8-11 Current Altitude/Dec Scope Encoder Position Byte 12-15 Current Azimuth/RA Scope Encoder Position. Byte 16 is Keypad Status (see the top of this section for a description of bits) Byte 17 is XBits Byte 18 is YBits Byte 19 is Extra bits Bit 0 - Set if Altitude/Dec motor is stopped Bit 1 - Set if Altitude/Dec motor is in manual Bit 2 - future Bit 3 - future Bit 4 - Set if Azimuth/RA motor is stopped Bit 5 - Set if Azimuth/RA motor is in manual Bit 6 - future Bit 7 - future Byte 20 is a 1 byte checksum of the previous 19 bytes (simple addition). XXR The controller now waits for an additional 20 bytes from a host as follows: Byte 0-3 New Altitude/Dec Motor Position Goal (least significant byte first) Byte 4-7 New Azimuth/RA Motor Position Goal. Byte 8-11 New Altitude/Dec Motor Speed Byte 12-15 New Azimuth/RA Motor Speed Byte 16 Various bits Bit 0 If '0', the following new XBit and YBit values are ignored. If '1', the new XBit and YBit values are used. Bit 1 -7 future Byte 17 New XBits value (must have previous bit 0 set) Byte 18 New YBits value (must have previous bit 0 set) Byte 19 Checksum of all above data bits (simple 8 bit addition) If you use the above binary command to control the servo controller, be sure to have a restart communication if the command gets out of sync by a communication fault. If you receive a bad checksum, you should resync communication by sending a few of XXS commands. The flash RAM values are loaded from the flash ROM to RAM on reset. Both the X and Y parameters are stored to the flash ROM. Use X and Y for module address 1. If the module address is 3, use 'T' and 'U', for address 5, it's 'V' and 'W'. Description of the bits for the XBits and YBits: 0 if 1, the motor encoder is incremented the other direction 1 if 1, the motor polarity is reversed 2 if 1, the azimuth (or altitude) encoder is reversed 3 if 1, (x only) we're in the computerless drag and track mode 3 if 1, (y only) we're in the computerless slew and track mode (no clutches, must use handpad to slew) (must be in drag and track too) 4 if 1, (x only) we're in the tracking platform mode 5 if 1, (x only) we enable the hand paddle 6 if 1, (x only) hand paddle is compatible with New Hand Paddle (allows slewing in two directions, and guiding) 7 if 1, (x only) we're in the guide mode. The pan rate is added or subtracted from the current tracking rate. Note about the Guide Mode: If PC software puts the controller in the guide mode, and you are controlling an Equatorial mount, you must give the declination motor a destination, even if you want it to be stopped. If you want the declination axis to be normally stopped, give the declination a far far away goal, and set the speed to zero. This is because the controller adds or subtracts from the current speed and direction, and the controller gets confused if the axis is at its destination. This is changed inf servo version 1.6, and this is automatically done for you in the controller. The Y_Bits bits 4-7 are the digital input status for the 4 digital inputs from the radio handpad reciever. This is only available if you're using servo version 1.6 and also if you have a handpad reciever connected. PicServo Mode Differences: If you intend to write a telescope driver for the SiTech controller, we recommend you use the new binary protocol mentioned above, as it is simpler and faster. If you have exsisting software for the PicServo chips, you can use the PicServo protocol, but there are a few differences as described here: The controller address must be set beforehand, and saved to flash ROM. The PicServo address commands are ignored with the SiTech controller. When the controller is set for address 1, the altitude motor will be addressed with address 1, and the azimuth with address 2. You can set address using the ASCII command AD1, AD3, or AD5. You then save the address to flash ROM using the following ASCII commands. \u201cXW\u201d for address 1, \u201cTW\u201d for address2, and \u201cVW\u201d for address 3. This must be done with only 1 controller connected at a time. You can also set the address of the controller using the ServoConfig software. When the Define Status specifies the Home position for return, the \u201cHOME\u201d position returnes the location of the telescope encoder location, instead of the HOME position. When the Define Status specifies the A/D to be returned, it returns the motor current times 10 instead. Bit 6 of the Define Status must be clear. When you set bit 6 of the Define Status, the motor voltage will be returned in the A/D location if it is an odd address for the controller. When you set bit 6 of the Define Status, the CPU temperature will be returned in the A/D location if it is an even address for the controller. The ReadVersion bit of the Define Status returns the handpad status instead of the version. The handpad bits are as follows: The handpad number is an 8 bit number where each bit represents a push button. Bit 0 Left Bit 1 Right Bit 2 Up Bit 3 Down Bit 4 Speed (this is a toggle, a 1 is Pan mode and a 0 is slew mode). Bit 5 Top Right key Bit 6 Top Left key Bit 7 Changed key. The Changed key (bit 7) is used to tell if someone has pressed a keypad button since the last speed command is received. This feature is useful so a new tracking coordinate can be obtained, and the new tracking setpoint will track from the new position. This bit is automatically cleared if a new speed command is received. Several more functions have been added to the PicServo protocol. They are accessed using the PicServo NOP function with various lengths specified. Length of 0 (send a 0Eh. This is the same as the PicServo NOP function) Length of 1 (send a 1Eh for the PicServo function, then another control byte). If Control byte = 4, the controller reads the configuration from flash ROM If Control byte = 8, the controller writes the current configuration to flash ROM If Control byte = 16 the controller writes the factory defaults to the flash ROM If Control byte = 32 the controller reverts to the ASCII mode. Length of 2 (send a 2Eh for the PicServo function, the control byte, then another data byte. If Control byte = 2 the controller will update the Xbits (or Ybits if even address) with the data byte. Length of 5 (send a 5Eh for the PicServo function, a control byte, then four data bytes. If Control byte = 1 the controller will update the Altitude (Azimuth if even address) location with the next 4 bytes. If Control byte = 64 the controller will update the Altitude (Azimuth if even address) guide rate with the next 4 bytes. Length of 9 (send a 9Eh for the PicServo function, a control byte, then eight data bytes. If Control byte = 32 the controller will load the next two long ints (8 data bytes) into the Slew rate and the Pan rate. For odd address it is the altitude, for even addresses it is the azimuth. If the controller hasn't received a PicServo command for more than the PicServo timeout period, the controller will stop any motion, and revert to the ASCII mode. The PicServo timout is set with the XXJ command, and the units are Seconds. Set to zero to disable PicServo timout. ***************************************************************************** ***************************************************************************** ***************************************************************************** New ASCII checksum commands =========================== About the new ASCII CS (ACS) Mode: The SiTech ASCII command set has a lot of commands that can be typed in from a terminal program. But this was problematic when communications were not very good (noisy RS232 lines, etc). Sometimes when SiTechExe sent a binary command, the controller did not receive it as a binary command. Then, by chance, some of the binary data would equal an ASCII command, such as "Reset Controller", or other commands, and the controller would do unpredictable things. To solve this, I devised an ASCII Checksum Mode (ACS). If in the ACS mode, after the in the command is sent, you send another byte, which is the 8 bit sum of all the bytes, inverted. Entering and Leaving the ACS mode: YXY0 + 184 We go out of the ASCII Checksum mode YXY1 We go into the ASCII Checksum mode YXY + 232 Returns "Y0" if not in ASCII Checksum mode, and "Y1" if in ASCII cs mode. If controller is in the ASCII CS mode, and it is receiving characters, if the character stream stops for more than 50 mSecs, the controller resets the serial stream, and the next character will be placed at the beginning of the receive buffer. If the controller is not in the ASCII CS mode, you can send characters with any time spacing, and it will always respond. Example of a "YXS" command, in ACS mode: 59 58 53 D EE One more oddity.... If controller is in the ACS mode, and you want to "talk" to the focuser/rotator, then you replace the first 'X' with 'T', and the first 'Y' with 'U' (same as previously), but you calculate the checksum based on if it had been the 'X' or 'Y'. ***************************************************************************** There are two ASCII commands that require binary data to follow. These are: XXR and YXR Obviously, if in the ACS mode, there would be a checksum following the The checksums in the following commands do not include the ASCII portion, or the ASCII checksum (if in ACS mode) Following the ASCII portion of the XXR command, is the 21 binary data as follows: 4 bytes Alt/Dec destination 4 bytes Alt/Dec Speed 4 bytes Az/RA destination 4 bytes Az/RA Speed 1 byte. bit 0 means use following xbits and ybits value, if zero, ignore. 1 byte xbits 1 byte ybits 1 byte checksum (low byte) 1 byte checksum (high byte) (inverted) Following the ASCII portion of the YXR command, is the 34 binary data as follows: 4 bytes Alt/Dec destination 4 bytes Alt/Dec Speed (base rate) 4 bytes Az/RA destination 4 bytes Az/RA Speed (base rate) 4 bytes Alt/Dec Rate Adder 4 bytes Az/RA Rate Adder 4 bytes Alt/Dec Rate Adder Time (in Servo Loops (1953 would be 1 second) ) 4 bytes Az/RA Rate Adder Time (in Servo Loops (1953 would be 1 second) ) 1 byte checksum (low byte) 1 byte checksum (high byte) (inverted) The Rate Adder is added to the base rate for the number of servo loops specified. For instance if the base rate is 2000 and the rate adder is -2100, then the rate will be -100 for 66 servo loops. This in effect will change the direction of the motor for 66 servo loops. In SiTechExe, I truncate the rate adder so in never actually changes motor directions, because, if the controller has backlash enabled, it will toggle back and forth. Here's an example of what SiTechExe sends the controller for the YXR command while in the ACS mode: 59 58 52 D EF F7 25 CF FF D0 7 0 0 B CF BA 58 EB 15 0 0 0 0 0 0 16 EA FF FF 42 0 0 0 42 0 0 0 2F F5 Here's the interpretation thereof: YXR/n,ASCIICS:239,AlDst:-3201545,AlSpd:2000, AzDst:1488637707,AzSpd:5611,AlRateAdd:0,AzRateAdd:-5610, AlRateTime:66,AzRateTime:66 ***************************************************************************** ***************************************************************************** Here is the Binary Response, returned from the controller, Version 3.6C: This response is returned from all of these commands: XXS XXR YXR All Multi-bytes (Ints and Longs) are lsb first. 1 byte 0xA8 + controller address (1, 3 or 5) 4 bytes of Alt motor position 4 bytes of AZ motor position 4 bytes of Alt scope encoder position 4 bytes of Az scope encoder position 1 byte of keyboard status 1 byte for Xbits 1 byte for YBits 1 byte for various bits. //0 = X stopped (altitude) //1 = X Manual (Altitide) //2 = DigIn0 (v2.0 and later) //3 = DigIn1 (v2.0 and later) //4 = YStopped (Azimuth) //5 = Y Manual (Azimuth) //6 = Y PEC Recording //7 = Y PEC Playing 2 bytes Analog Input 1 2 bytes Analog Input 2 4 bytes millisecond clock 1 byte, temperature Deg's F (This will be changed to Alt/Dec Worm Phase eventually) 1 byte Az/RA Worm Phase 4 bytes. Alt/Dec motor location at last Alt/Dec Scope Encoder location change 4 bytes. Az/RA motor location at last Az/RA Scope Encoder location change 2 bytes for checksum The checksum is the 16 bit sum of all bytes, starting with the A8 + controller address (byte 1) The high byte of the cs is inverted. Here's a typical binary response (in hex): A9 1D 5C 0 0 5E 67 4 0 0 0 0 0 1D 19 0 0 0 60 0 80 0 0 0 0 5E 96 E 0 50 99 0 0 0 0 2D 67 4 0 84 FA Here's the same response broken down: A9 = 0xA8 + controller address Alt/Dec Motor Position 1D 5C 0 0 23581 Az/Ra Motor Position 5E 67 4 0 288606 Alt/Dec Scope Encoder Location 0 0 0 0 0 Az/RA Scope Encoder Location 1D 19 0 0 6429 Keypad Status: 0 0 XBits (XBits and YBits functions are the same as listed in ServoDoc.pdf 60 (hex) 96 (dec) YBits 0 (hex) 0 (bin) 0 (dec) 0 (oct) Various Bits (it looks like the YPEC is playing) 80 (hex) 128 (dec) Analog Input 1 0 0 Analog Input 2 0 0 Millisecond Clock 5E 96 E 0 955998 Temperature (Deg's F) (will be changed to Alt/Dec Worm Phase eventually) 50 (hex) 80 (dec) Az/RA Worm Phase (0-255) 99 153 (59.7 percent) Alt/Dec Motor Location at last Alt/Dec Scope Encoder Location Position Change 0 0 0 0 Az/RA Motor Location at last Az/Ra Scope Encoder Location Position Change 2D 67 4 0 288557 Checksum 84 FA ***************************************************************************** ***************************************************************************** *****************************************************************************