Dmcwin32 Galil Windows Api Tool Kit: User Manual
Dmcwin32 Galil Windows Api Tool Kit: User Manual
DMCWin32
Galil Windows API
Tool Kit
Rev. 2.2
Rev 6/06
OVERVIEW ..................................................................................................................................................9
PROGRAMMING MODEL ..............................................................................................................................10
Step 1 Register Controller ..................................................................................................................10
Step 2 Declare Functions ...................................................................................................................10
Step 3 Open Communication ..............................................................................................................10
Step 4 Download Program .................................................................................................................10
Step 5 Send Commands ......................................................................................................................10
Step 6 Close Communication..............................................................................................................10
VISUAL BASIC ............................................................................................................................................10
Example 1: Sending Commands in VB ...............................................................................................11
Example 2: Downloading Programs in VB ........................................................................................11
C/C++ ........................................................................................................................................................12
Declaration Files...................................................................................................................................12
DMCCOM.H ......................................................................................................................................................12
DMCWIN.H (C++ only) ....................................................................................................................................12
DMCMLIB.H .....................................................................................................................................................12
Linking Your Application with the Galil DLLs .................................................................................................12
Example 1: Sending Commands Using DMCCOM.H........................................................................12
Example 2: Downloading Programs using DMCCOM.H..................................................................13
Example 3: Sending Commands Using the Class Library (C++)......................................................13
APPLICATION PROGRAMMING INTERFACE (DMCCOM.H) ......................................................14
DLL API LIST FOR DMCCOM.H ..............................................................................................................14
Communication......................................................................................................................................14
Registry..................................................................................................................................................15
Binary Commands .................................................................................................................................15
Data Record...........................................................................................................................................15
Other......................................................................................................................................................15
ERROR CODES ............................................................................................................................................16
API ROUTINE DETAILS ...............................................................................................................................17
DMCAddGalilRegistry and DMCAddGalilRegistry2............................................................................17
DMCArrayDownload ............................................................................................................................17
DMCArrayUpload .................................................................................................................................18
DMCAssignIPAddress ...........................................................................................................................18
DMCBinaryCommand ...........................................................................................................................18
DMCChangeInterruptNotification ........................................................................................................19
DMCClear .............................................................................................................................................19
DMCClose .............................................................................................................................................19
DMCCommand......................................................................................................................................19
DMCCommand_AsciiToBinary.............................................................................................................20
DMCCommand_BinaryToAscii.............................................................................................................20
DMCCompressFile................................................................................................................................20
DMCCopyDataRecord ..........................................................................................................................21
DMCDeleteGalilRegistry ......................................................................................................................21
DMCDiagnosticsOff ..............................................................................................................................21
DMCDiagnosticsOn ..............................................................................................................................21
DMCDownloadFile ...............................................................................................................................21
DMCDownloadFirmwareFile ...............................................................................................................22
DMCDownloadFromBuffer...................................................................................................................22
DMCEditRegistry ..................................................................................................................................22
DMCEnumGalilRegistry and DMCEnumGalilRegistry2 ......................................................................22
DMCError .............................................................................................................................................23
DMCFastCommand...............................................................................................................................23
This manual describes DMCWin32: the Galil Windows API (Application Programming Interface). It include
DLLs (dynamic link libraries) for developing programs on a PC to communicate with a Galil controller as well as
sample programs and utilities to help design a software interface. Any Windows programming environment that
can interface with DLLs can be used with DMCWin32, including Microsoft Visual Basic, Microsoft Visual C++,
and National Instruments LabView.
This section describes the basic requirements for programming in C, C++, and Visual Basic, along with simple
programming examples. The remaining sections document each function in the API and provide more advanced
program examples. For additional examples, refer to the source code contained in the C, CPP and VB directories
located under /DMCWIN.
The DMCWin32 DLL files are used within Windows development environments to create programs that
communicate with Galil controllers. Two libraries are included with the tool kit:
Using these DLLs, a program can send commands, upload and download programs, and check the status of any
controller in a system. Programming with the Galil DLLs is source code compatible across the following
Windows environments: 98SE, ME, NT4, 2000, and XP.
Visual Basic
Declaration Files Before using the DLL functions, add the module file included in the \dmcwin\vb directory named
DMCCOM40.BAS. This module declares the functions, making them available for the VB project. To add this
file, select ‘Add Module’ from the ‘Project’ menu in VB5/6.
The following code illustrates the use of DMCOpen and DMCCommand. Here, the controller is sent the
command TPX when a Command Button is pressed. The response is placed in a text box. To use this example,
start a new Visual Basic project, place a Text Box and a Command Button on a Form, add the DMCCOM40.BAS
module, and type the following code:
RC = DMCOpen(Controller, 0, hDmc)
RC = DMCDownloadFromBuffer(hDmc, Buffer, "")
RC = DMCCommand(hDmc, "XQ", Response, ResponseLength)
RC = DMCClose(hDmc)
End
End Sub
Note: See the DLL function descriptions later in this manual for more functions.
Declaration Files
DMCCOM.H
All Galil communications programs written in C must include the DMCCOM.H file. This allows a program to
access the DLL functions through the declared function calls. The DMCCOM.H header file is located in the
\dmcwin\include directory.
DMCMLIB.H
These advanced motion functions are not available as a C++ class library and are independent from the DMCCOM
functions. To use, include the file DMCMLIB.H located in the \dmcwin\include directory.
#include <windows.h>
#include <dmccom.h>
long rc;
HANDLEDMC hDmc;
HWND hWnd;
int main(void)
{
// Connect to controller number 1
rc = DMCOpen(1, hWnd, &hDmc);
if (rc == DMCNOERROR)
{
char szBuffer[64];
// Move the X axis 1000 counts
rc = DMCCommand(hDmc, "PR1000;BGX;", szBuffer, sizeof(szBuffer));
long rc;
HANDLEDMC hDmc;
HWND hWnd;
char szBuffer[64];
char filename[] = “c:\\dmcwin\\yourfile.dmc”;
int main(void)
{
// Connect to controller number 1
rc = DMCOpen(1, hWnd, &hDmc);
//Download file
rc = DMCDownloadFile(hDmc, filename, NULL);
//Start program on controller at label ‘A’
rc = DMCCommand(hDmc, “XQ#A”, szBuffer, sizeof(szBuffer));
//Close communication
rc = DMCClose(hDmc);
return 0;
}
In this example the label was set to NULL, causing the existing program to be overwritten. If a label is used in
place of NULL, the DMCDownloadFile will try to find that label within the program already present on the
controller and start the download from there. A “#” will append the program to the existing program.
Note: All existing programs must be halted before an upload or download occurs.
This example tells the controller to start jogging the Y axis at 10000 counts per second:
Communication
DMCOpen Open communications with interrupt support Page 29
DMCOpen2 Open communications with interrupt support Page 29
DMCClose Close communications Page 19
DMCSendCW2OnClose Clears most significant bit of unsolicited messages Page 31
DMCCommand Send a command Page 19
DMCFastCommand Send special commands Page 23
DMCArrayDownload Download an array Page 17
DMCArrayUpload Upload an array Page 18
DMCDownloadFile Download a file from hard disk Page 21
DMCUploadFile Upload file to hard disk Page 32
DMCCompressFile Compress a Galil language program file Page 20
DMCDownloadFromBuffer Download file from buffer Page 22
DMCUploadToBuffer Upload file to buffer Page 32
DMCSendFile Send a file Page 31
DMCDownloadFirmwareFile Download Firmware Page 22
DMCGetAdditionalResponse Read long response Page 25
DMCGetAdditionalResponseLen Read long response length Page 25
DMCGetUnsolicitedResponse Read card messages Page 28
DMCReadData Low level read function Page 29
DMCWriteData Low level write function Page 32
DMCClear Clear FIFO Page 19
DMCGetTimeout Return the current timeout Page 28
DMCSetTimeout Set timeout Page 31
DMCWaitForMotionComplete Wait for motion complete Page 32
DMCMasterReset Master reset controller Page 28
DMCReset Reset controller Page 30
DMCVersion Get firmware version Page 32
Binary Commands
DMCBinaryCommand Send binary command Page 18
DMCCommand_AsciiToBinary Convert ASCII command to binary Page 20
DMCCommand_BinaryToAscii Convert a binary command to ASCII Page 20
DMCFile_AsciiToBinary Convert file of ASCII commands to binary Page 23
DMCFile_BinaryToAscii Convert file of binary commands to ASCII Page 23
DMCReadSpecialConversionFile Special conversion file Page 29
DMCSendBinaryFile Send a binary file Page 30
Data Record
DMCRefreshDataRecord Request a new data record Page 30
DMCGetDataRecordByItemId Return part of the data record (preferred method) Page 25
DMCGetDataRecordItemOffsetById Get data record item offset Page 26
DMCGetDataRecordConstPointer Get pointer to data record Page 26
DMCGetDataRecordRevision Get version of record Page 27
DMCGetDataRecordArray Return all cached data record (1700, 1800 only) Page 27
DMCGetDataRecordConstPointerArray Return a const pointer to all cached data records Page 26
(1700, 1800 only)
DMCCopyDataRecord Copy data record into a structure Page 21
DMCGetDataRecordSize Returns number of bytes in data record Page 27
Other
DMCChangeInterruptNotification Notify for interrupt by handle or thread Page 19
DMCDiagnosticsOff Stop diagnostics Page 21
DMCDiagnosticsOn Start diagnostic file Page 21
DMCError Read error message Page 23
DMCGetHandle Return the controller handle Page 28
DMCSelectController Selection Dialog Page 30
DMCStartDeviceDriver Starts Galil device driver (NT4 only) Page 31
DMCStopDeviceDriver Stops Galil device driver (NT4 only) Page 31
DMCAssignIPAddress Assign the IP Address to an Ethernet controller Page 18
Syntax varies for Visual Basic and C++; you can compare the syntax differences by looking at the
DMCCOM40.BAS for Visual Basic and DMCWIN.CPP for C++.
Add a Galil controller to the Windows registry. The controller number is returned in the argument pusController.
The DMCAddGalilRegistry2 function is a replacement for DMCAddGalilRegistry.
pgalilregistry/pgalilregistry2 Pointer to a GALILREGISTRY or GALILREGISTRY2 struct.
pusController Pointer to an unsigned short that will receive the Galil controller number.
DMCArrayDownload
LONG FAR GALILCALL DMCArrayDownload(HANDLEDMC hdmc, PSZ pszArrayName, USHORT usFirstElement,
USHORT usLastElement, PCHAR pchData, ULONG cbData, PULONG cbBytesWritten);
Download an array to the Galil controller. The array must already exist in the controller. Array data can be
delimited by a comma or CR (0x0D) or CR/LF (0x0D0A).
Note: The firmware on the controller must be recent enough to support the QD command.
DMCArrayUpload
LONG FAR GALILCALL DMCArrayUpload(HANDLEDMC hdmc, PSZ pszArrayName, USHORT usFirstElement,
USHORT usLastElement, PCHAR pchData, ULONG cbData, PULONG pulBytesRead, SHORT fComma);
Upload an array from the Galil controller to the PC. The array must exist on the controller. Array data will be
delimited by a comma or CR (0x0D) depending of the value of fComma.
Note: The firmware on the controller must be recent enough to support the QU command.
DMCAssignIPAddress
LONG FAR GALILCALL DMCAssignIPAddress(HWND hWnd, PGALILREGISTRY2 pgalilregistry2);
Assign an IP Address to an Ethernet controller. The controller must be in BOOTP broadcast mode.
hwnd The window handle of the calling application. If NULL, the window with the
current input focus is used.
szIPAddress The IP address as a string. Example: "160.35.50.1".
DMCBinaryCommand
LONG FAR GALILCALL DMCBinaryCommand(HANDLEDMC hdmc, PBYTE pbCommand, ULONG ulCommandLength,
PCHAR pchResponse, ULONG cbResponse);
Send a DMC command in binary format to the Galil controller. Most commands have a binary equivalent that will
be processed faster by the controller.
Change the window handle used in DMCOpen or the thread ID used in DMCOpen2. This value is for notification
of interrupts.
DMCClear
LONG FAR GALILCALL DMCClear(HANDLEDMC hdmc);
DMCClose
LONG FAR GALILCALL DMCClose(HANDLEDMC hdmc);
Close communications with the Galil controller. Failing to call DMCClose can result in memory leaks.
DMCCommand
LONG FAR GALILCALL DMCCommand(HANDLEDMC hdmc, PSZ pszCommand, PCHAR chResponse,
ULONG cbResponse);
Note: This function can only send commands or groups of commands up to 1024 bytes long.
DMCCommand_BinaryToAscii
LONG FAR GALILCALL DMCCommand_BinaryToAscii(HANDLEDMC hdmc, PBYTE pbBinaryCommand,
LONG ulBinaryCommandLength, PSZ pszAsciiResult, ULONG cbAsciiResult,
ULONG FAR *pulAsciiResultLength);
DMCCompressFile
LONG FAR GALILCALL DMCCompressFile(PSZ pszInputFileName, PSZ pszOutputFileName,
USHORT usLineWidth, PUSHORT pusLineCount);
Compress a DMC file so that program space in the controller is fully utilized. Lines are put together whenever
possible to make more lines available. Leading and trailing spaces are removed as well.
Get a copy of the data record used for fast polling. The data record is only as recent as the last call made to
DMCRefreshDataRecord.
DMCDeleteGalilRegistry
LONG FAR GALILCALL DMCDeleteGalilRegistry(SHORT sController);
Delete a Galil controller in the Windows registry. If a Plug-and-Play controller (USB or PCI) is deleted, the
computer must be rebooted to recover the controller in the registry.
DMCDiagnosticsOff
LONG FAR GALILCALL DMCDiagnosticsOff(HANDLEDMC hdmc);
DMCDiagnosticsOn
LONG FAR GALILCALL DMCDiagnosticsOn(HANDLEDMC hdmc, PSZ pszFileName, BOOL fAppend);
DMCDownloadFile
LONG FAR GALILCALL DMCDownloadFile(HANDLEDMC hdmc, PSZ pszFileName, PSZ pszLabel);
Download a Galil-language application program to the controller from a file on the hard drive.
Update the controller's firmware. This function will open a binary firmware file and write new firmware to the flash
EEPROM of the controller.
Note: This function is for the DMC-1200, DMC-14x5, DMC-1600, DMC-1700, DMC-1800, DMC-18x2, DMC-
2000, DMC-2100, DMC-2200, DMC-21x2/3, and DMC-34x5 only.
DMCDownloadFromBuffer
LONG FAR GALILCALL DMCDownloadFromBuffer(HANDLEDMC hdmc, PSZ pszBuffer, PSZ pszLabel);
Download a Galil-language application program from a memory buffer to the Galil controller.
DMCEditRegistry
VOID FAR GALILCALL DMCEditRegistry(HWND hwnd);
Edit the Windows registry: add, change, or delete Galil motion controllers. This function requires the Galil
ActiveX control DMCReg.ocx to be installed and registered on the PC.
hwnd The window handle of the calling application. If NULL, the window with the
input focus is used.
Enumerate or list all the Galil controllers in the Windows registry. The user needs to make two calls to this
function. The first call should have a NULL for the argument pgalilregistry. The number of
GALILREGISTRY structs (number of Galil controllers in the Windows registry) will be returned in the argument
pusCount. The second call should have sufficient memory allocated for all the GALILREGISTRY structs to be
returned and pass the pointer to that memory as the argument pgalilregistry. It is the users responsibility to
allocate and free memory to hold the GALILREGISTRY structs. The DMCEnumGalilRegistry2 function is a
replacement for DMCEnumGalilRegistry.
DMCError
LONG FAR GALILCALL DMCError(HANDLEDMC hdmc, LONG lError, PCHAR pchMessage, LONG cbMessage);
Retrieve the error description for an error code when a Galil API function does not return DMCNOERROR.
DMCFastCommand
LONG FAR GALILCALL DMCFastCommand(HANDLEDMC hdmc, PSZ pszCommand);
Send a DMC command in ASCII format to the Galil controller and do not wait for a response. Use this function
with caution because command responses will not be removed from the controller’s output. In some applications it
may be necessary to first send the Galil command CW,1 to allow the controller to continue program execution when
the controller’s output FIFO is full.
Use this function for Galil commands which do not return an acknowledgment from the controller such as providing
data for the DL and QD commands.
Note: This function can only send commands or groups of commands up to 1024 bytes long.
DMCFile_AsciiToBinary
LONG FAR GALILCALL DMCFile_AsciiToBinary(HANDLEDMC hdmc, PSZ pszInputFileName,
PSZ pszOutputFileName);
DMCFile_BinaryToAscii
LONG FAR GALILCALL DMCFile_BinaryToAscii(HANDLEDMC hdmc, PSZ pszInputFileName,
PSZ pszOutputFileName);
Query the Galil controller for more response data. There will be more response data available if the DMCCommand
function returned DMCERROR_BUFFERFULL. Once this function is called, the internal additional response
buffer is cleared.
DMCGetAdditionalResponseLen
LONG FAR GALILCALL DMCGetAdditionalResponseLen(HANDLEDMC hdmc, PULONG pulResponseLen);
Query the Galil controller for the length of additional response data. There will be more response data available if
the DMCCommand function returned DMCERROR_BUFFERFULL.
DMCGetControllerDesc
LONG FAR GALILCALL DMCGetControllerDesc(USHORT usController, PSZ pszControllerDesc,
ULONG cbControllerDesc);
DMCGetDataRecordByItemId
LONG FAR GALILCALL DMCGetDataRecordByItemId(HANDLEDMC hdmc, USHORT usItemId, USHORT usAxisId,
PUSHORT pusDataType, PLONG plData);
Get a data item from the data record. Gets one item from the data record by using a predefined ID (see data record
IDs defined in DMCDRC.H). To retrieve data record items by offset instead of ID, use the function
DMCGetDataRecord.
Get a const pointer to the data record. Using this method to access the information in the data record eliminates
the copying necessary with DMCCopyDataRecord. Additional const pointers can be created to individual data
items by using DMCGetDataRecordItemOfsetById(). These two functions allow a one-time setup. Then, all that
is required to access information in the data record is to call DMCRefreshDataRecord() and then dereference the
desired pointer into the data record.
DMCGetDataRecordItemOffsetById
LONG FAR GALILCALL DMCGetDataRecordItemOffsetById(HANDLEDMC hdmc, USHORT usItemId,
USHORT usAxisId, LPUSHORT pusOffset, LPUSHORT pusDataType );
Get the total offset for a data item by data item ID (see data record IDs defined in DMCDRC.H). The returned offset
and data type can then be used to extract a value from the data record pointer retrieved using
DMCGetDataRecordConstPointer.
DMCGetDataRecordConstPointerArray
LONG FAR GALILCALL DMCGetDataRecordConstPointerArray(HANDLEDMC hdmc, const char **pchDataRecord,
LPUSHORT pusNumDataRecords);
Get a const pointer to the available data records. This function retrieves all the available cached data records from
a PCI or ISA controller. For DMC-1800 controllers, depending on the hardware/software version, the data record
may be accessed through 2nd FIFO or Dual Port RAM. The newest version of controller board (Rev. H and above
for 0-4 axes board, and Rev. D and above for 5-8 axes board) supports both Dual Port RAM and 2nd FIFO
functions. Version 7.0.3.0 of the PCI drivers (Glwdmpci.sys for Windows XP, 2000, ME,and 98SE, and
GalilPCI.sys for NT4.0) automatically accesses the data record using the Dual Port RAM on the newer controller
versions with firmware version M1 and higher.
Note: Use of this function requires Glwdmpci.sys, Glwdmisa.sys, and GalilPCI.sys driver versions 7.0.0.0 or
higher. The cache depth is set by controller properties stored in the Galil Registry. Do not call
DMCRefreshDataRecord prior to calling this function.
Get an array of data records. This function retrieves all the available cached data records from a PCI and ISA
controller with 2nd FIFO. For DMC1800 controllers, depending on the hardware/software version, the data record
may be accessed through 2nd FIFO or Dual Port RAM.
Note: Use of this function requires Glwdmpci.sys, Glwdmisa.sys, and GalilPCI.sys driver versions 7.0.0.0 or
higher. The cache depth is set by controller properties stored in the Galil Registry. Do not call
DMCRefreshDataRecord prior to calling this function.
DMCGetDataRecordRevision
LONG FAR GALILCALL DMCGetDataRecordRevision(HANDLEDMC hdmc, PUSHORT pusRevision);
DMCGetDataRecordSize
LONG FAR GALILCALL DMCGetDataRecordSize(HANDLEDMC hdmc, PUSHORT pusRecordSize);
Note: this function is for the DMC-1600, DMC-1700, and DMC-1800 only.
Get Windows registry information for a given Galil controller. The DMCGetGalilRegistryInfo2 function is a
replacement for DMCGetGalilRegistryInfo.
Get the handle for a Galil controller which was already opened using DMCOpen or DMCOpen2. The handle to
the Galil controller is returned in the argument phdmc.
usController A number between 1 and 64. Up to 64 Galil controllers may be addressed per
process.
phdmc Buffer to receive the handle to the Galil controller to be used for all subsequent
API calls. Users should declare a variable of type HANDLEDMC and pass
the address of the variable to the function.
DMCGetTimeout
LONG FAR GALILCALL DMCGetTimeout(HANDLEDMC hdmc, LONG FAR* pTimeout);
Get the current time-out value, which determines how long the communications driver will wait for a command
response from the controller.
DMCGetUnsolicitedResponse
LONG FAR GALILCALL DMCGetUnsolicitedResponse(HANDLEDMC hdmc, PCHAR chResponse, ULONG cbResponse);
Query the Galil controller for unsolicited responses. These are messages output from programs running in the
Galil controller. The most common command to produce messages is MG.
DMCMasterReset
LONG FAR GALILCALL DMCMasterReset(HANDLEDMC hdmc);
Master reset the Galil controller. This returns the controller to its factory default setting, erasing all data saved
with BN, BP, and BV. Ensure that important data is backed up before performing a master reset. The master
reset may take up to 5 seconds. Make sure the timeout is large enough before performing the master reset.
Change a Galil controller in the Windows registry. The DMCModifyGalilRegistry2 function is a replacement for
DMCModifyGalilRegistry.
Open communications with the Galil controller. The handle to the Galil controller is returned in the argument
phdmc. For every DMCOpen, you must issue a DMCClose.
Note: hwnd is not used for controllers which do not support bus interrupts.
usController A number between 1 and 64. Up to 64 Galil controllers may be addressed per
process.
hwnd The window handle to use for notifying the application program of an interrupt
via PostMessage.
phdmc Buffer to receive the handle to the Galil controller to be used for all subsequent
API calls. Users should declare a variable of type HANDLEDMC and pass
the address of the variable to the function.
DMCOpen2
LONG FAR GALILCALL DMCOpen2(USHORT usController, LONG lThreadID, PHANDLEDMC phdmc);
Open communications with the Galil controller with interrupt handling. The handle to the Galil controller is
returned in the argument phdmc. For every DMCOpen2, you must issue a DMCClose.
usController A number between 1 and 64. Up to 64 Galil controllers may be addressed per
process.
lThreadID The thread ID identifies the calling thread and is also used for notifying the
application program of an interrupt via PostThreadMessage.
phdmc Buffer to receive the handle to the Galil controller to be used for all subsequent
API calls. Users should declare a variable of type HANDLEDMC and pass
the address of the variable to the function.
DMCReadData
LONG FAR GALILCALL DMCReadData(HANDLEDMC hdmc, PCHAR pchBuffer, ULONG cbBuffer,
PULONG pulBytesRead);
Low-level I/O function to read data from the Galil controller. The function will read whatever is currently in the
controller’s output FIFO (bus controller) or communications port input queue (serial controller). The function will
read up to cbBuffer characters from the controller. The data placed in the user buffer (pchBuffer) is NOT NULL
terminated. The data returned is not guaranteed to be a complete response - you may have to call this function
repeatedly to get a complete response.
DMCReadSpecialConversionFile
LONG FAR GALILCALL DMCReadSpecialConversionFile(HANDLEDMC hdmc, PSZ pszFileName);
DMCRefreshDataRecord
LONG FAR GALILCALL DMCRefreshDataRecord(HANDLEDMC hdmc, ULONG ulLength);
DMCRegisterPnpControllers
LONG FAR GALILCALL DMCRegisterPnpControllers(USHORT* pusCount);
OBSOLETE. Update the Windows registry for all Galil plug-and-play controllers. This function may add new
controllers to the registry or update existing ones.
DMCReset
LONG FAR GALILCALL DMCReset(HANDLEDMC hdmc);
DMCSelectController
SHORT FAR GALILCALL DMCSelectController(HWND hwnd);
Select a Galil motion controller from a list of registered controllers. Returns the selected controller number or -1 if
no controller was selected.
hwnd The window handle of the calling application. If NULL, the window with the
input focus is used.
DMCSendBinaryFile
LONG FAR GALILCALL DMCSendBinaryFile(HANDLEDMC hdmc, PSZ pszFileName);
Send a file consisting of DMC commands in binary format to the Galil controller. Commands are executed
immediately.
Determines if the controller is sent CW2 command on closing. The CW2 command causes the controller to NOT
set the most significant bit of unsolicited messages to 1 (please see the Galil Motion Control command reference).
The default behavior is TRUE, which means the CW2 command is sent prior to closing a controller handle.
DMCSendFile
LONG FAR GALILCALL DMCSendFile(HANDLEDMC hdmc, PSZ pszFileName);
Send a file consisting of DMC commands in ASCII format to the Galil controller. Commands are executed
immediately.
DMCSetTimeout
LONG FAR GALILCALL DMCSetTimeout(HANDLEDMC hdmc, LONG lTimeout);
Set time-out value. If the time-out value is set to zero, the DLLs will ignore time-out errors. This is useful for
sending Galil commands which do not return a response, such as providing records to the DL or QD commands.
DMCStartDeviceDriver
LONG FAR GALILCALL DMCStartDeviceDriver(USHORT usController);
Start the device driver associated with the given controller. All controller handles must be closed. Use this
function to recycle the device driver after making a configuration change through the Windows registry.
DMCStopDeviceDriver
LONG FAR GALILCALL DMCStopDeviceDriver(USHORT usController);
Stop the device driver associated with the given controller. All controller handles must be closed. Use this
function to recycle the device driver after making a configuration change through the Windows registry.
Upload the application program from the Galil controller to a file on the hard disk.
DMCUploadToBuffer
LONG FAR GALILCALL DMCUploadToBuffer(HANDLEDMC hdmc, PCHAR pchBuffer, ULONG cbBuffer);
Upload the application program from the Galil controller to a memory buffer on the PC.
DMCVersion
LONG FAR GALILCALL DMCVersion(HANDLEDMC hdmc, PCHAR pchVersion, ULONG cbVersion);
DMCWaitForMotionComplete
LONG FAR GALILCALL DMCWaitForMotionComplete(HANDLEDMC hdmc, PSZ pszAxes, SHORT fDispatchMsgs);
Wait for motion complete by creating a thread to query the controller. The function returns when motion is
complete.
DMCWriteData
LONG FAR GALILCALL DMCWriteData(HANDLEDMC hdmc, PCHAR pchBuffer, ULONG cbBuffer,
PULONG pulBytesWritten);
Low-level I/O function to write data to the Galil controller. Data is written to the Galil controller only if it is "ready"
to receive it. The function will attempt to write exactly cbBuffer characters to the controller.
These functions perform advanced functions that can extend the capabilities of the motion controller.
DMCEllipse
This function allows a controller to perform elliptical motion. When it is called, it will create a text file containing
VP commands that define an ellipse. This file can then be sent to the card to perform the motion using
DMCSendFile or inserted into a larger sequence of VP and CR commands.
LONG GALILCALL DMCEllipse(char *filename, int FirstOffset, int SecondOffset, double a, double b,
double theta, double delta_theta, double increment, double rotation);
Description
The parameters sent to the DMCEllipse function are similar to those for the CR command. An ellipse is defined
by the starting angle, ending angle, and the major and minor axis. This function takes those values and creates an
ellipse using VP commands. The end result is a sequence of line segments that produce the curve.
The first point calculated is at the angular position theta. The next is at theta+increment and so on until the final
angle (theta+delta_theta) is reached. Obviously, the length of the computed segments will determine how smooth
the curve will be. To control the coarseness of the curve use a small increment value. The smaller the increment
the more points are created.
FirstOffset and SecondOffset determine the position of the first point of the curve.
Although it is not clear by the drawing, the starting position is unchanged by the rotation.
Note: The DMCEllipse function can be used to create circles with a very large radius. The Galil CR command is
limited to 6000000. To make larger circles make a=b=radius of circle.
Error Codes
If there are no errors the DMCEllipse function returns a 0. Here are the conditions that can generate errors and the
code that is returned.
Condition Code
Bad arguments: delta_theta positive but increment negative and visa versa; delta_theta = 0; -12
increment=0; a or b <=0
Could not open output file -4
#include "DMCMLIB.H"
int main(void)
{
long rc;
char filename[] = "c:\\ellout.sen";
HANDLEDMC hDmc;
HWND hWnd;
char szBuffer[80];
//start motion
rc = DMCCommand(hDmc, "VE", szBuffer, sizeof(szBuffer));
rc = DMCCommand(hDmc, "BGS", szBuffer, sizeof(szBuffer));
rc = DMCClose(hDmc);
return 0;
}
Here the ellipse started with offsets 1000 and 1500, with a major axis of 2000 , minor axis of 800, starting angle of
30, delta angle of 190 and a rotation of 30. To make the motors move the DMCSendFile is used to take the VP
commands from the file and put them in the coordinated motion segment buffer inside the controller. The LE sent
by DMCCommand tells the controller the sequence is ended and the BGS command starts the motion.
It is not necessary to include DMCCOM.H in the above example because it is already included in the
DMCMLIB.H library header file.
DMCSpline
Use DMCSpline to fit a curve through the points that define a 1-8 axis move to remove infinite accelerations around
corners.
Description
DMCSpline fits a curve through the points in the input file using the equation:
For each segment in the input file coefficients are calculated for each axis then the points are created as a function
of the vector distance. A point is created for every v where v = 0 to the total vector distance with increments of
delta_vector.
LI n,n,n,n,n,n,n,n < s
LI n,n,n,n,n,n,n,n < s
LI n,n,n,n,n,n,n,n < s
…
Each segment must be at least 2 counts long or an error will occur. If a speed value is not specified do not use the
less than sign. A negative speed is ignored. The number of axis is defined by the number of commas in the first
line. Make sure the number of commas match on each and every line. The LI (or any non-numeric characters) at
the beginning of the line is ignored and can be removed.
Error Codes
If there are no errors the DMCSpline function returns a 0. Here are the conditions that can generate errors and the
code that is returned.
Condition Code
Axis distance greater than 8 characters long or speed over 12 characters long. -12
More than 8 axis are specified in input file -12
Could not open output or input file or input file is empty -4
Example
This input file defining a two axis move is used:
LI 1000,1000
LI 1000,0
LI 0,1000
LI -1000,0
LI 0,-1000
Note: A smaller delta_vector will result in a smoother curve but it will also create more LI points in the output file.
If the delta_vector is larger than the segment then the no smoothing will occur on that segment.
Here is a sample C program to create a spline motion. This program uses splinein.txt for the input file, splinout.txt
for the output and 10 counts for the vector increment.
#include "DMCMLIB.H"
int main(void)
{
long rc;
char outfile[] = "c:\\splinout.txt";
char infile[]= “c:\\splinein.txt”;
HANDLEDMC hDmc;
HWND hWnd;
char szBuffer[80];
//start motion
rc = DMCCommand(hDmc, "LE", szBuffer, sizeof(szBuffer));
rc = DMCCommand(hDmc, "BGS", szBuffer, sizeof(szBuffer));
rc = DMCClose(hDmc);
return 0;
}
ULONG GALILCALL DMCSCurve(char Axis, unsigned long Distance, unsigned long Speed,
unsigned long Acceleration, unsigned long Jerk, PSZ FileName);
Description
This function generates an S-curve motion profile based on a set of motion constraints. If the specified constraints
would result in a discontinuous profile (i.e. triangular acceleration or velocity) the function optimizes the parameters
so that a true S-curve is generated. The motion profile is generated through a series of contour data (CD) moves.
Note: there is a small amount of rounding error in this function which may cause the actual length of a move to
vary from the specified length by a few counts (usually less than 10).
The following figure shows an exaggerated example of an S-curve. The trapezoidal graph is a 5000 count Position
Relative move with a slew speed of 25000 and an acceleration of 256000. The S-curve graph is the same move
generated by the DMCSCurve function with a limitation on jerk of 10000 counts/sec3.
5000
4000
Distance
3000
Trapezoidal
S-Curve
2000
1000
0
1000
1100
1200
1300
1400
100
200
300
400
500
600
700
800
900
0
Time
Error Codes
If there are no errors, DMCSCurve returns a 0. The following codes are returned in the event of an error:
Condition Code
Could not open output file -4
Out of memory -8
Bad arguments: One or more arguments to a function was NULL or invalid -12
Invalid Distance parameter -97
Invalid Speed parameter -98
Invalid Acceleration parameter -99
#include “dmcmlib.h”
void main(void)
{
long rc;
char filename[] = "c:\\windows\\desktop\\scurve.dmc";
HANDLEDMC hDmc;
HWND hWnd;
// start motion
rc = DMCCommand(hDmc, “XQ”, szBuffer,sizeof(szBuffer));
}
In the above example, the X axis is used to generate an S-curve profile. The length of the move is 10000 counts,
speed is 50000 counts/sec, acceleration is 256000 counts/sec2 and jerk is 15625000 counts/sec3.
After the output file has been generated, it is downloaded to the controller and executed using functions from
DMCCOM.H, which has already been included in the DMCMLIB.H header file.
DMCHelix
This function generates a helical motion profile. Two axes follow a coordinated circular path while a third axis
generates a linear motion perpendicular to the circle.
The function also compensates for offset error (Desired Distance - Actual Distance) which results from round-off
error in the GR command.
ULONG GALILCALL DMCHelix(char PlaneAxis1, char PlaneAxis2, char TraverseAxis, short Pitch,
ulong Radius, short StartAngle, long Dist, ulong Speed, ulong Accel, ulong Decel,
PSZ FileName);
Description
Helical motion is a combination of two types of motion: a circular move in one plane and a linear move
perpendicular to the plane of the circle. PlaneAxis1 and PlaneAxis2 define the plane of the circle while TraverseAxis
defines the axis used for the linear move. The Pitch parameter relates the circular motion to the linear motion: it is
Error Codes
If there are no errors, DMCHelix returns a 0. The following codes are returned in the event of an error:
Condition Code
Bad arguments: One or more arguments to a function was NULL or invalid -12
Could not open output file -4
Example
The following C program uses the DMCHelix function to generate a helix, sends the resulting output file to the
controller, and executes it.
#include “dmcmlib.h”
void main(void)
{
long rc;
char filename[] = "c:\\windows\\desktop\\helix.dmc";
HANDLEDMC hDmc;
HWND hWnd;
// start motion
rc = DMCCommand(hDmc, “XQ”, szBuffer,sizeof(szBuffer));
In the above example, the X and Y axes are used for circular motion while the Z axis is used for linear motion. The
pitch of the helix is -360, which means that the Z axis will move forward 360 counts for every XY circle. Since the
sign of the pitch is negative, the helix will be generated in the clockwise direction. The radius is 5000, start angle is
0, traversed distance is 100000, speed is 50000, and both acceleration and deceleration are 256000.
Description
General tuning is a method used by Galil to automatically tune servo motors. The DMCGeneralTuning function
creates a Galil program and stores it in a file. The file must be downloaded and then executed on a Galil controller
to perform the tuning.
Once the Galil program is run the servo motor will be stepped back and forth and its position error monitored.
Gradually the PID values are increased until the motor becomes unstable. The values are then backed off. The
final values should be appropriate for most servo systems. Manual fine tuning may be needed to produce the best
system response.
While general tuning is the most flexible tuning method from Galil it may not work on all systems. If this is the
case, we recommend using WSDK where other tuning methods are available.
Error Codes
If there are no errors the DMCGeneralTuning function returns a 0. A non zero return value indicates an error
occurred. See the header file DMCCOM.H for a definition of the error codes.
Example
This C program creates the automatic tuning file. This file is then downloaded and run on the controller.
#include "windows.h"
#include "dmccom.h"
#include "dmcmlib.h"
int main(void)
{
int rc;
char filename[] = "c:\\gtune.dmc";
USHORT stepsize = 300;
HANDLEDMC hDmc;
HWND hWnd=0;
char szBuffer[64];
char axis='X';
return 0;
}
Description
DMCAutoTuning is an alternative to the DMCGeneralTuning function to automatically tune servo motors. The
DMCAutoTuning function creates a Galil program and stores it in a file. The file must be downloaded and then
executed on a Galil controller to perform the tuning.
The program generated by DMCAutoTuning will send a series of pulses to the amplifier of the specified voltage
and duration. These disturbances are used to determine the optimum crossover frequency of the system. After the
best crossover frequency is found, the PID values are adjusted for best response at the selected frequency. The final
values should be appropriate for most servo systems. Manual fine tuning may be needed to produce the best
system response.
While auto tuning is the most flexible tuning method from Galil it may not work on all systems. If this is the case,
we recommend using WSDK where other tuning methods are available.
Error Codes
If there are no errors the DMCAutoTuning function returns a 0. A non zero return value indicates an error
occurred. See the header file DMCCOM.H for a definition of the error codes.
Example
This C program creates the automatic tuning file. This file is then downloaded and run on the controller.
#include "windows.h"
#include "dmccom.h"
#include "dmcmlib.h"
void main(void)
{
int rc;
char filename[] = "c:\\atune.dmc";
double pulsesize = 5.5;
USHORT pulseduration 20;
HANDLEDMC hDmc;
HWND hWnd=0;
char szBuffer[64];
char axis='X';
Introduction
This section discusses a number of topics of interest to a PC programmer interfacing with a Galil controller. In
additions, a number of sample programs are included in the DMCWIN directory under \C\Samples, \CPP\Samples,
and \VB\Samples.
You may also use the Galil "DL" command to build your own download function. If you do, make sure that you
set the time-out (using the API function DMCSetTimeout) to zero as the DL command will not return an
acknowledgment from the controller (except in the case of an error) until the end of file character ('\' or Cntl-Z) is
sent. Remember to restore the time-out value before exiting your function.
GALILREGISTRY galilregistry;
In your .H file, manually add the function prototype for the interrupt handling function to your message map, after
the Class Wizard comments.
//{{AFX_MSG(CMyApp)
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnCommand1
afx_msg void OnCommand2
//}}AFX_MSG
afx_msg LONG OnDMCInterrupt(UINT nWP, LONG nLP);
DECLARE_MESSAGE_MAP()
In your .CPP file, manually add the ON_MESSAGE macro to your message map, after the Class Wizard
comments.
BEGIN_MESSAGE_MAP(CMyApp, CWinApp)
//{{AFX_MSG_MAP(CMyApp)
ON_WM_TIMER()
ON_COMMAND(IDC_COMMAND1, OnCommand1)
ON_COMMAND(IDC_COMMAND2, OnCommand2)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_DMCINTERRUPT, OnDMCInterrupt)
END_MESSAGE_MAP()
To cut down on the amount of trace being output, call DMCDiagnosticsOn as close to the part of your program you
wish to debug as possible. In addition, DMCDiagnosticsOn can be called with a flag to append trace output rather
than replace trace output.
The time-out value is initialized to the value stored in the Windows Registry database each time you call
DMCOpen. You can get the current time-out value with the API function DMCGetTimeout. You can set the
current time-out value with the API function DMCSetTimeout.
Note: the lowest you can set the time-out value in the Windows Registry database is 1 ms. The default time-out
value is 1000 ms or 1 second.
Low-Level I/O
There are two functions available for performing low-level I/O: DMCWriteData and DMCReadData. They are
ideal if you need to send data to the controller which is time critical, such as contour data or linear interpolation
segments. The most important point to remember if you use DMCWriteData to send commands to the controller is
that you need to periodically call DMCReadData or DMCClear to clear the outbound FIFO or communications
buffer. Failure to do so will cause communications and application programs to halt if the outbound FIFO or
communications buffer fills up (unless CW,1 is sent). On Galil bus controllers, the outbound FIFO is configured
to hold 512 bytes.
Binary Communications
All Galil controllers are communicated with in ASCII format. That is, you send commands in ASCII and the
controller responds in ASCII. All controllers but the DMC-1000, 1300, 1500, 1410, 1411, 1412, and 1417 add a
binary form of communication: you can send commands in binary format. The controller responds to binary
commands the same as ASCII commands: by ASCII. The advantage of sending commands in binary is speed of
execution. If the command is already in binary form, it does not need to be decoded by the controller, resulting in
higher throughput. Sending contour data is one area where speed is critical and may benefit from sending
commands in binary.
Use the API function DMCBinaryCommand to send a command to the controller in binary. Use the API function
DMCSendBinaryFile to send a file of binary commands to the controller. In addition, there are API functions to
convert commands and files to/from ASCII/binary. Note that converting a command from ASCII to binary in-line
or on-the-fly may still result in improved throughput. Following is an example of converting a command from
ASCII to binary on-the-fly then sending it to the controller.
LONG rc;
CHAR szCommand = "PR1000,2000"
CHAR szResponse[256];
BYTE BinaryCommand[32];
ULONG BinaryCommandLength;
// Send the binary command to the controller and get the response
rc = BinaryCommand(BinaryCommand, BinaryCommandLength, szResponse,
sizeof(szResponse));
There are four different methods to access the data record: Primary Communication Channel (QR command),
Secondary FIFO, DMA, and Dual Port RAM. Regardless of which method is used, the format of the data is the
same. The following table shows which controllers support which method(s):
DMC-1700
For DMC-1700 controllers, the data record is sent from the controller to the PC using either DMA or the secondary
FIFO channel. The command DR is used to set the update rate and select the Data Record Access method (DMA
or FIFO). The data record is always available, even if the primary FIFO channel is blocked because a trip-point
(such as AM) is pending.
DMC-1800
For DMC-1800 controllers, the data record may be accessed through the secondary FIFO or Dual Port RAM.
(Previous board versions supported only the secondary FIFO--Rev. G and below for 1-4 axes board, and Rev. C and
below for 5-8 axes board). Version 7.0.3.0 of the PCI drivers (Glwdmpci.sys for Windows XP, 2000, ME, and
98SE, and GalilPCI.sys for NT4.0) automatically accesses the data record using the Dual Port RAM on controllers
with firmware version M1 and higher. The command DR is used to set the update rate and DU selects the data
record access method (Dual Port RAM or FIFO).
DMCGetDataRecordByItemId
Use the DMCGetDataRecordByItemId function to return a single record item as in this Win32 console example:
#include "windows.h"
#include "Dmccom.h"
#include "stdio.h"
int main(void)
{
long rc;
HANDLEDMC hDmc;
HWND hWnd=0;
ULONG length=0;
USHORT DataType;
ULONG data;
//Connect to controller #1
rc = DMCOpen(1,hWnd, &hDmc);
if (rc==DMCNOERROR)
{
//refresh local copy of data record
rc = DMCRefreshDataRecord(hDmc, length);
rc = DMCClose(hDmc);
return 0;
}
DMCRefreshDataRecord is used to copy the data record into a buffer in the DLL. All calls to read a record item
are done on this local copy. If the data is time sensitive, the buffer should be refreshed just before any call to
DMCGetRecordByItemId.
The item returned from DMCGetRecordByItemId is specified by the second parameter passed to the function. In
this case, the constant DRIdAxisMotorPosition is passed to get the motor position. The third parameter,
DRIdAxis1, specifies the axis. The constants used to define the record items are in the header file Dmcdrc.h and
are automatically included by Dmccom.h.
#include "windows.h"
#include "Dmccom.h"
#include "stdio.h"
int main(void)
{
long rc;
HANDLEDMC hDmc;
HWND hWnd=0;
ULONG length=0;
USHORT RecordSize;
DMCDATARECORD MyDataRecord;
//Connect to controller #1
rc = DMCOpen(1,hWnd, &hDmc);
if (rc==DMCNOERROR)
{
//refresh local copy of data record
rc = DMCRefreshDataRecord(hDmc, length);
rc=DMCClose(hDmc);
return 0;
}
Here the data record is first copied to a local buffer with DMCRefreshDataRecord and then placed into our data
record structure with DMCCopyDataRecord. As with the single item method the data must be refreshed before
being read to make sure it is up to date.
Note: you may wish to alter the DMCDATARECORD structure depending on your controller's configuration. See
the header file DMCDRC.H for more details.
The following sample code demonstrates how to retrieve the sample number:
#include <windows.h>
#include "dmccom.h"
#include <stdio.h>
long rc;
HANDLEDMC hDmc;
HWND hWnd;
ULONG DRlength=0;
USHORT DataType;
LONG oldDRData=0;
const char *pchDataRecord;
unsigned short *pMyLong;
USHORT usOffset; //Total offset (number of bytes) from the beginning of the data
//record to the data item. Output Only.
USHORT usDataType; //Data type of the data item. The data type of the
//data item is returned on output. Output Only.
if (rc==DMCNOERROR)
{
//Find data record offset
rc= DMCGetDataRecordItemOffsetById(hDmc, DRIdSampleNumber, DRIdAxis1, &usOffset,
&usDataType);
do
{
rc= DMCRefreshDataRecord(hDmc,DRlength);
printf("SAMPLE NUMBER: %d\n", (int)*pMyLong);
}while(1);
The following example uses the DMCGetDataRecordArray to get an array of data records and then retrieves the
sample number and X axis motor position from those records.
while (i<numberofdatarecord){
sample = pdatarecordarray[i].SampleNumber;
xpos = pdatarecordarray[i].AxisInfo[0].MotorPosition;
printf("sample %d position %d \n",sample,xpos);
i=i+1;
}
#include "windows.h"
#include "Dmccom.h"
#include "stdio.h"
int main(void)
{
long rc;
HANDLEDMC hDmc;
HWND hWnd=0;
DMCDATARECORDQR MyDataRecordQR;
//Connect to controller #1
rc = DMCOpen(1,hWnd, &hDmc);
if (rc==DMCNOERROR)
{
rc = DMCCommand(hDmc, "QR\r", (LPCHAR)&MyDataRecordQR,
sizeof(MyDataRecordQR));
rc=DMCClose(hDmc);
return 0;
}
QR is sent using DMCCommand and a pointer to the response is returned. This pointer has been cast as a
LPCHAR so that the DMCCommand would accept it. The QR command can return a full copy of the data record
or a subset depending on the arguments used with it. For more information, consult the Galil Command Reference
for your controller.
Note: you may wish to alter the DMCDATARECORDQR structure depending on your controller's firmware and
number of axes. See the header file DMCDRC.H for more details.
This section lists the run time files that need to be distributed with software developed with DMCWIN. For
additional information, please consult DISTNOTE.TXT located within the DMCWIN directory.
These device drivers are normally installed using .INF files. You can place GLWDMPCI.INF, GLWDMISA.INF,
and GLWDMUSB.INF in the WINDOWS/INF or WINNT/INF directory and the operating system will find the
Galil INF files when looking for a driver for the controller.
You should also copy DMC32.DLL and DMCBUS32.DLL (for bus controllers), or DMCSER32.DLL (for serial
controllers) in the WINDOWS\SYSTEM or WINNT\SYSTEM32 directory. You will also need to copy and register
dmcreg.ocx.
Note: the WINDOWS or WINNT directory may have a different, user-specified name.
Windows NT 4.0
For ISA bus controllers, copy GALIL.SYS to the WINNT\SYSTEM32\DRIVERS directory. For PCI or
CompactPCI controllers, copy GALILPCI.SYS to the WINNT\SYSTEM32\DRIVERS directory.
You should also copy DMC32.DLL and DMCBUS32.DLL (for bus controllers), or DMCSER32.DLL (for serial
controllers) in the WINNT\SYSTEM32 directory. You will also need to copy and register dmcreg.ocx with the
communication dlls.
Note: the WINNT directory may actually have a different, user-specified name.
Note: If your project is built using Visual Basic or Delphi, or a Version of Visual C++ other than 6.0, you will
also need to distribute the run-time files for those tools.