library/drivers/.

Writing a Telescope Driver

Introduction

This page contains information for programmers wishing to write a new telescope device driver for SkyMap Pro. Although this page discusses drivers in terms of the C++ programming language, it should be possible to write a driver using any language capable of creating a Win32 DLL.

Change history

19 Apr 1998

Several users have requested the capability of handling telescope communications themselves, rather than using the serial comms facilities provided by the telescope control DLL. One user, for example, wishes to write a "pseudo driver" which makes calls to his own, more sophisticated, LX200 control program; another user wishes to communicate with a remote telescope using TCP/IP.

To allow this type of driver to be written, a new version 1.1 of the telescope control DLL is now available from the Service Packs page of this web site. Information specific to this scope.dll v1.1 is clearly marked below.

Overview

A SkyMap Pro telescope driver is a 32-bit Windows dynamic link library (DLL), renamed to have a ".drv" file extension, and placed in the "drivers" subdirectory of the SkyMap Pro installation directory. No form of "installation" is required; simply copying the driver file to the correct directory is sufficient to make it available to SkyMap Pro.

The driver DLL must "export" a set of specifically-named functions, by which it is controlled by SkyMap Pro. These functions can be divided into two groups:

Different devices obviously offer different capabilities; for example a fully computer-controlled telescope such as the Meade LX200 offers considerably more capabilities than does a simple "digital setting circles" device. When SkyMap Pro loads a telescope driver, it will "query" the driver to discover which functions that particular driver offers. This makes it very easy to initially write a very simple driver for a new device, and then gradually add new capabilities to it, one at a time.

Telescope control DLL

All telescope control functions in SkyMap Pro are handled via the telescope control DLL, "scope.dll", which is located in the "system" subdirectory of the SkyMap Pro installation directory. Whenever SkyMap Pro wishes to carry out a telescope control operation, it does so by calling a function in "scope.dll" which, in turn, calls the appropriate function in the current telescope driver DLL.

Virtually all currently-available telescopes and digital setting circle (DSC) devices which offer the ability to be "controlled" by a PC do so via an RS232 serial link. Writing reliable serial comms code can be quite tricky, so to avoid having to write essentially the same comms functions in every telescope driver, "scope.dll" exports a set of "high level" functions which manage serial communications, and which a driver can call to do the actual "talking" to the device; this makes it a lot easier to write drivers!

[New in scope.dll v1.1] There are situations in which you may not wish scope.dll to handle serial comms; you may wish to handle the serial comms yourself, or you may wish to use a completely different comms protocol, such as TCP/IP. Version 1.1 of scope.dll, downloadable from the Service Packs page of this web site, now permits a telescope driver to specify that it wishes to handle its own comms.

The function exported by scope.dll are all defined in a C++ header file "scope.h", and the telescope driver is then linked with scope.dll's import library "scope.lib". Both of these files are available for download at the end of this page.

The functions exported by "scope.dll", and available for use by a driver, are as follows:

Serial buffer functions:

All data received from the telescope via the serial link is stored in a "serial buffer". These functions allow a telescope driver to empty, read, and query that buffer.


void ScopeSerialBufferEmpty(void)

Empty the serial buffer, throwing away any data which may be stored. This is useful at the start of a sequence of commands to make sure that the buffer is initially in a "known state".


int ScopeSerialBufferCharCount(void)

Return the number of characters currently stored in the serial buffer. This function is useful when waiting for a specific number of characters to be sent back by the device in response to a command.


void ScopeSerialBufferRead( char *pDest, int nCount )

Read "nCount" characters from the serial buffer into the memory address starting at "pDest". Reading characters removes them from the buffer. Note that it is the caller's responsibility to ensure that "pDest" is pointing at a block of memory at least "nCount" characters in size.


Sending commands to the telescope

The following functions are available for sending commands to the telescope:


BOOL ScopeSendData( char *pData )

Send the NULL-terminated string pointed at by "pData" to the telescope. The return value is TRUE if the command is successfully transmitted, or FALSE if an error occurs.


BOOL ScopeExecuteCommand( char *pCommand, int nWaitCount, char *pResult )

This is a "high level" command allowing a driver to send a command to the telescope and await a response, with a single function call. The NULL-terminated command string "pCommand" is sent to the telescope, and then the function waits to receive "nWaitCount" characters back from the telescope, writing the received characters to the address "pResult". The return value is TRUE if everything works successfully, or FALSE if an error occurred.

Telescope driver DLL

As described previously, a telescope driver DLL must export a set of mandatory functions, and may export a set of optional functions, depending on its capabilities. We describe here those functions:

Mandatory functions


void DriverDescription( char *pName )

Write to address "pName" a string up to 32 characters in length containing a descriptive name for the driver. This string is displayed as the driver name when the user selects the Telescope/Configure menu item from SkyMap Pro.


BOOL DriverQuery( int nFlag )

This function is repeatedly called by the telescope control DLL to determine the capabilities of the driver. For each possible value of "nFlag" (see below), the driver should return TRUE if that capability is supported by the driver, or FALSE if not. Note that any "unrecognised" flag value must return FALSE. The current capability flags are:

DRIVER_CONFIG Does the driver has a configuration dialog?
DRIVER_GETRADEC Can the telescope return its current RA/dec coordinates?
DRIVER_GETALTAZ Can the telescope return its current alt/az coordinates?
DRIVER_SLEWRADEC Can the telescope slew (move itself) to a specified RA/dec position?
DRIVER_SETTIME Can the telescope set the current time?
DRIVER_SETPOS Can the telescope set the observation site coordinates?
DRIVER_SYNC Can the telescope "sync" on the last position slewed to?
DRIVER_SHUTDOWN [New in scope.dll v1.1] Does the driver have a "shutdown" function?

void DriverGetCommsParameters( int *pnBaudRate, int *pnParity, int *pnDataBits, int *pnStopBits )

This function is called by the telescope control DLL to determine the serial port settings required by the device. The four parameters - baud rate, parity, data bits, and stop bits should be specified using the predefined constants defined in the Windows API help file description of the "DCB" (device control block) data structure. For example, a device which uses a serial port setting of 9600,N,8,1 (such as the Meade LX200 does) could implement this function as follows:

void DriverGetCommsParameters( int *pnBaudRate,
                               int *pnParity,
                               int *pnDataBits,
                               int *pnStopBits )
{
    *pnBaudRate = CBR_9600;
    *pnParity = NOPARITY;
    *pnDataBits = 8;
    *pnStopBits = ONESTOPBIT;
}

[New in scope.dll v1.1] If a driver wishes to handle its own comms, it should return the value "-1" for the baud rate, in which case the other parameters are ignored. If this value is returned, SkyMap Pro will not open the serial port itself, and the driver must not attempt to call any of the serial comms functions described previously.


BOOL DriverInitConnection( int nTimeout )

This function is called by the telescope control DLL immediately after setting up the comms link to the telescope, and should be used to both carry out any "initialisation" tasks (such as sending configuration commands to the telescope), and to test whether the comms link to the telescope is "alive" - eg by sending a command to the telescope and awaiting a known response.

The "nTimeout" parameter specifies the maximum time that SkyMap Pro wishes to wait for a response from the telescope, and is in units of 10ths of a second - eg a value of 50 indicates a "timeout" of 5 seconds.

The function should return TRUE if the comms link is successfully tested as "alive", or FALSE if an error occurs.

Optional functions

There is one function in this group corresponding to each of the driver "capability flags" described above in the description of the "DriverQuery" function. If the driver returns TRUE for a capability flag, the corresponding function must be present in the driver.


void DriverConfig( HINSTANCE hInst )

This function must be present if the driver returns TRUE to the DRIVER_CONFIG capability flag.

Some telescope drivers have no "user configurable" options; others do. For example a DSC driver might need to know the number of "steps" in its encoders. If a driver requires configuration input from the user, it should return TRUE from the DRIVER_CONFIG query flag, and implement this function. When the user displays the Telescope/Configure dialog and clicks the driver name, the Configure... button on the telescope configuration dialog will be enabled, and this function will be called when the user clicks that button.

The function can do whatever it wishes, but the typical action will be to display a configuration dialog allowing the user to enter or edit the required configuration information. When the dialog is dismissed, the driver can store the information which has been entered, for example in an INI file or the Registry. That information can then be retrieved whenever the driver is loaded in the future.

The "hInst" parameter specifies the "instance handle" of the device driver DLL, and can be used to load resources (such as a config dialog) from the correct location.


BOOL DriverGetRADec( double *pdRA, double *pdDec, int nTimeout )

This function must be present if the driver returns TRUE to the DRIVER_GETRADEC capability flag.

This function is called at regular intervals by the telescope control DLL to retrieve the current RA/dec coordinates at which the telescope is pointing. This is then used to display the "cross-hair" telescope cursor on the map.

The function parameters are as follows:

pdRA Address of a variable in which to write the telescope's current right ascension, in units of decimal degrees.
pdDec Addess of a variable in which to write the telescope's current declination, in units of decimal degrees.
nTimeout Maximum time to wait for a response from the telescope, in units of 10ths of a second.

The return value should be TRUE if the position was successfully retrieved, or FALSE if an error occurred.


BOOL DriverGetAltAz( double *pdAlt, double *pdAz, int nTimeout )

This function must be present if the driver returns TRUE to the DRIVER_GETALTAZ capability flag.

This function is called at regular intervals by the telescope control DLL to retrieve the current alt/az coordinates at which the telescope is pointing. This is then used to display the "cross-hair" telescope cursor on the map.

The function parameters are as follows:

pdAlt Address of a variable in which to write the telescope's current altitude, in units of decimal degrees.
pdAz Addess of a variable in which to write the telescope's current azimuth, in units of decimal degrees.
nTimeout Maximum time to wait for a response from the telescope, in units of 10ths of a second.

The return value should be TRUE if the position was successfully retrieved, or FALSE if an error occurred.


int DriverSlewRADec( double dRA, double dDec, int nTimeout )

This function must be present if the driver returns TRUE to the DRIVER_SLEWRADEC capability flag, and is called by the telescope control DLL to slew the telescope to specified RA/dec coordinates.

The function parameters are as follows:

dRA The right ascension to slew to, in units of decimal degrees.
dDec The declination to slew to, in units of decimal degrees.
nTimeout Maximum time to wait for a response from the telescope, in units of 10ths of a second.

The return value should be:

0 If the operation was successfully completed.
1 If the selected target is not currently available (eg below the horizon).
-1 If an error occurred.

BOOL DriverSetTime( int nTimeout )

This function must be present if the driver returns TRUE to the DRIVER_SETTIME capability flag, and is called by the telescope control DLL to set the telescope's date and time to the current date and time read from the computer's clock.

The "nTimeout" parameters specifies the timeout, in the usual units of 10ths of a second. The return value should be TRUE if the operation was successfully completed, or FALSE if an error occurred.



BOOL DriverSetPosition( double dLat, double dLong, int nTimeDiff, int nTimeout )

This function must be present if the driver returns TRUE to the DRIVER_SETPOS capability flag, and is called by the telescope control DLL to set the telescope's position and time zone.

The function arguments are:

dLat The observer's latitude, in decimal degrees. This should be positive for north latitudes, negative for south latitudes.
dLong The observer's longitude, in decimal degrees. This should be positive for west longitudes, negative for east longitudes.
nTimeDiff The observer's time difference from UT (GMT) in minutes. This should be positive if the observer is west of Greenwich, negative if the observer is east of Greenwich.
nTimeout Maximum time to wait for a response from the telescope, in units of 10ths of a second.

The return value should be TRUE if the operation was successfully completed, or FALSE if an error occurred.


void DriverShutdown( void )

[New in scope.dll v1.1]

This function must be present if the driver returns TRUE to the DRIVER_SHUTDOWN capability flag, and is called by the telescope control DLL when the user selects the "Close Connection" command from the "Telescope" menu. It provides an opportunity for the driver to carry out "clean up" operations.

This function was primarily added for the benefit of telescope drivers which handle their own comms, to provide a suitable place to cleanly close down the comms link. If it is implemented by a driver which uses SkyMap Pro's comms facility, the function is called immediately prior to the serial port being closed, so all the standard serial port facilities are still available to this function (ie it can send commands to, and receive responses back from the telescope).


BOOL DriverSync( int nTimeout )

This function must be present if the driver returns TRUE to the DRIVER_SYNC capability flag, and is called by the telescope control DLL to "synchronize" the telescope's current position with the coordinates of the last target slewed to.

The "nTimeout" parameters specifies the timeout, in the usual units of 10ths of a second. The return value should be TRUE if the operation was successfully completed, or FALSE if an error occurred.


Sample code

The following code samples are provided for your free use. Please feel free to use them in any way desired.

Telescope control DLL header file and import library
"scope.h" and "scope.lib" files, required to build a new telescope driver.
Sample LX200 driver
Complete source code (written for the Microsoft Visual C++5 compiler) for the SkyMap Pro Meade LX200 telescope driver. This is the source code used to build the "lx200.drv" driver supplied as standard with SkyMap Pro.

Driver library

If you do write a driver for a new device, we'd love to add it to the driver library here on the SkyMap web site. Please contact chris@skymap.com for details of how to submit a new driver to the library.