Function call prototypes and pointer casting from header file.
(only those used in following example shown)
|
-
-
typedef BOOLEAN(*P_SP_INIT_ALL_DEVICES)
(USHORT* pDevList, BYTE* pbNumDevices_LV, DOUBLE* dblRate,
BOOLEAN fShowDevList);
P_SP_INIT_ALL_DEVICES pSP_InitAllDevices = NULL;
typedef BOOLEAN(*P_SP_INIT_ALL_DEVICES_THREAD)
(USHORT* pDevList, DOUBLE* dblRate, BOOLEAN fShowDevList);
P_SP_INIT_ALL_DEVICES_THREAD pSP_InitAllDevices_Thread = NULL;
typedef BOOLEAN(*P_SP_GET_ONE_CONVERSION)
(USHORT usDevID, UINT* uiConvRawCount, DOUBLE* dblRate,
BYTE bCurChan, BYTE* pbLastDigin);
P_SP_GET_ONE_CONVERSION pSP_GetOneConversion = NULL;
typedef BOOLEAN(*P_DLL_START_SCAN)
(USHORT usDevID, PSCAN_OBJECT_DIO pScanObj_DIO, BYTE bStartMode );
P_DLL_START_SCAN pDLL_StartScan_DIO = NULL;
typedef BOOLEAN(*P_DLL_READ_SCAN_DATA)
(USHORT usDevID, UINT* puiDataBuff, SHORT numPointsToRead,
PSCAN_OBJECT_DIO pScanObj_DIO);
P_DLL_READ_SCAN_DATA pDLL_ReadScanData_DIO = NULL;
typedef BOOLEAN(*P_SP_END_SCAN)
(USHORT usDevID);
P_SP_END_SCAN pSP_EndScan = NULL;
typedef BOOLEAN(*P_SP_SEND_CHAN)
(USHORT usDevID, BYTE bCurChan, BYTE* pbLastDigin);
P_SP_SEND_CHAN pSP_SendChan = NULL;
typedef BOOLEAN(*P_SP_SEND_DIG_OUT)
(USHORT usDevID, BYTE bDigOut, BYTE* pbLastDigin);
P_SP_SEND_DIG_OUT pSP_SendDigOut = NULL;
typedef BOOLEAN(*P_SP_SEND_DAC)
(USHORT usDevID, DOUBLE dblVoltage, BYTE bDAC, BYTE* pbReserved);
P_SP_SEND_DAC pSP_SendDAC = NULL;
typedef BOOLEAN(*P_SP_SEND_RATE)
(DOUBLE* dblRate, USHORT usDevID);
P_SP_SEND_RATE pSP_SendRate = NULL;
|
Variables declarations from header file
|
-
-
-
Initialization related
-
-
#define MAX_DEV_CNT = 32
HINSTANCE hDLL;
USHORT ausDevList[MAX_DEV_CNT];
USHORT* pausDevList = ausDevList;
DOUBLE adblRate[MAX_DEV_CNT];
DOUBLE* padblRate = adblRate;
BYTE bNumDevices, bCurChan, bLastDigin, bCurListIndex;
BOOLEAN fShowDevList;
|
-
Get one conversion
-
-
Scan related
-
-
typedef struct
_SCAN_OBJECT{
// NOTE:
Most commonly used members are underlined
-
BYTE SO_bScanType;
|
// app writes
|
(needed by DLL to start scan)
|
DOUBLE SO_dblDevRate;
|
// app writes
|
(needed by DLL to start scan)
|
UINT SO_uiTotalPointsReadByDrvr;
|
// DLL writes
|
(can be read by app)
|
UINT SO_uiPointsInBuffer;
|
// DLL writes
|
(app reads this to get num points available to be read)
|
UINT SO_uiStatus;
|
// DLL writes
|
(important scanning status information needed by app)
|
UINT SO_uiSizeVoltageArray;
|
// No longer used
|
(but must be present as placeholder)
|
UINT SO_uiCurHead;
|
// DLL writes
|
(can be read by app)
|
UINT SO_uiCurTail;
|
// DLL writes
|
(can be read by app)
|
BYTE SO_bDigitalInput;
|
// DLL writes
|
(can be read by app)
|
BYTE SO_bChecksum;
|
// DLL writes
|
(can be read by app)
|
BYTE SO_bDeviceDisconnect;
|
// No longer used
|
(but must be present as placeholder)
|
UINT SO_uiScanStartTime;
|
// No longer used
|
(app may use for convenience)
|
UINT SO_uiScanEndTime;
|
// No longer used
|
(app may use for convenience)
|
BYTE SO_bScanArg;
|
// app writes
|
(needed by DLL to start scan)
|
-
SCAN_OBJECT, *PSCAN_OBJECT;
'NOTE:
The following are possible bit settings for SO_Status shown above
#define SCAN_RUNNING 0x1
|
not currently used
|
#define SCAN_DATA_REQUEST_SUCCEEDED 0x2
|
not currently used
|
#define SCAN_ENDING 0x4
|
not currently used
|
#define SCAN_HALTED 0x8
|
if set, the device is no longer scanning
|
#define SCAN_CHECKSUM_ERROR 0x10
|
if set there has been a checksum error
|
#define SCAN_VOLTAGE_BUFFER_WRAP 0x20
|
indicates a wrap in the DLL's data buffer
|
#define SCAN_MICRO_CODE_BUFF_WRAP 0x40
|
indicates a wrap in the device's data buffer
|
#define SCAN_DEVICE_IO_ERROR 0x80
|
indicates I/O error
|
#define SCAN_DEVICE_DISCONNECTED 0x100
|
The device has been disconnected
|
#define SCAN_DEVICE_NOT_FOUND 0x200
|
not currently used
|
-
'NOTE:
The following are possible bit settings for SO_bScanType shown above
#define CMND_SINGLE_CHAN_SCAN 1
|
// single chan scan (normal)
|
#define CMND_SINGLE_CHAN_DIGIN_SCAN 2
|
// single chan with digin after every conversion
|
#define CMND_MULTI_CHAN_SCAN 3
|
// multi chan regular
|
#define CMND_MULTI_CHAN_CAL_SCAN 4
|
// multi chan with cal
|
#define CMND_MULTI_CHAN_DIGIN_SCAN 5
|
// multi chan with digin
|
#define CMND_MULTI_CHAN_DIGIN_CAL_SCAN 6
|
// multi chan with cal and digin
|
|
|
-
-
-
Preinitialization
-
-
BOOLEAN DoPreInitialization(void)
{
-
//Initialize global variables that will be used later on
memset(ausDevList, 0, sizeof(ausDevList));
memset(adblRate, 0, sizeof(adblRate));
bCurChan = 6;
bCurListIndex = 0;
if(!hDLL) LoadLibrary("LL_USB.DLL");
if((!hDLL) return FALSE;
return TRUE;
}
|
-
Initialize all devices
-
-
BOOLEAN Initialize(void)
{
-
bCurListIndex = 0;
ausDevList[bCurListIndex] = 199; // your device ID here
adblRate[bCurListIndex] = 200; // your desired rate here
fShowDevList = FALSE;
pSP_InitAllDevices = (P_SP_INIT_ALL_DEVICES)GetProcAddress(hDLL, "SP_InitAllDevices");
if(!pSP_InitAllDevices)
{ /*
do critical error handling here and exit
*/ return FALSE; }
if(!pSP_InitAllDevices(pausDevList, &bNumDevices,
padblRate, FALSE))
{ /*
do critical error handling here and exit
*/ return FALSE; }
NOTE:
This function does not return until it's attempted to initialize
all of the devices listed in ausDevList. Each device could take
up to 3 seconds. If you are using 3 or more devices, it's recommended
that you use SP_InitAllDevices_Thread(), discussed elsewhere within
this documentation.
Place only those devices that you wish to initialize, in the
ausDevList array, any devices already initialized will remain
undisturbed.
}
|
-
GetOneConversion
-
-
BOOLEAN SP_GetOneConversion(void)
{
-
bCurListIndex = 0
pSP_GetOneConversion = (P_SP_GET_ONE_CONVERSION)GetProcAddress(hDLL, "SP_GetOneConversion");
if(!pSP_GetOneConversion)
{ /*
do critical error handling here and exit
/* return FALSE; }
if(!pSP_GetOneConversion(pausDevList[bCurListIndex],
&uiConvRawCount, bCurChan, &bLastDigin)
{ /*
do critical error handling here and exit
*/ return FALSE; }
//display +-5 volt range in a Windows message box
char szTempBuff[128];
sprintf(szTempBuff, "Voltage: \r\n\r\n%lf", ((INT)uiConvRawCount - 8388608) * 0.00000059604645);
MessageBox(GetForegroundWindow(), szTempBuff, " VOLTAGE----", 0);
NOTE:
The SP_GetOneConversion() function returns 24-bits of valid data in a 32-bit variable.
I convert it to a signed value above just so that I can more easily manipulate
the result to a +-5Volt value.
Please note that even though the current channel is passed as an
argument in this call, it is not used unless the DLL experiences an error
while communicating with the device, in which case it will take steps to
recover from the error... one of which includes resetting the device for
which it needs the channel value passed to it in this call. It is important
for you to understand that you must set the channel to what you want it to
be each time after initialization, ending a scan, or just when you want a
different channel selected. Use SP_SendChan() shown further down in this
file to do a channel change.
return TRUE;
}
|
-
Scanning -
(includes reading scan data and ending scan)
showing single chan scan (CMND_SINGLE_CHAN_SCAN)
links to other scan type examples:
CMND_SINGLE_CHAN_DIGIN_SCAN single chan - includes digital input in separate buffer with each data point
CMND_MULTI_CHAN_SCAN multi chan scan (normal)
CMND_MULTI_CHAN_CAL_SCAN multi chan - includes chan 7 with each scan
CMND_MULTI_CHAN_DIGIN_SCAN multi chan - includes digital input in separate buffer with each data point
CMND_MULTI_CHAN_DIGIN_CAL_SCAN multi chan - includes digital input in separate buffer with each data point and chan 7 each scan
-
-
BOOLEAN DoScan(void)
{
-
NOTE:
The following is just a simple overview of the single-channel scanning procedure.
Please see sample source code downloadable from web site for better example.
#define MAX_BUFF_SZ 10
UINT auiDataBuff[MAX_BUFF_SZ];
UINT* pauiDataBuff = auiDataBuff;
USHORT usNumPointsToRead;
bCurListIndex = 0;
SCAN_OBJECT ScanObject;
PSCAN_OBJECT pScanObject = &ScanObject;
// only members required for this type of scan are initialized.
pScanObject->SO_uiStatus = 0;
pScanObject->SO_bScanType = CMND_SINGLE_CHAN_SCAN;
pScanObject->SO_dblRate = adblRate[bCurListIndex];
pScanObject->SO_uiPointsInBuffer = 0;
// Assign the various scan related function call pointers
pDLL_StartScan_DIO = (P_DLL_START_SCAN)GetProcAddress(hDLL, "DLL_StartScan_DIO");
if(!pDLL_StartScan_DIO)
{ /*
do critical error handling here and exit
*/;
return FALSE; }
pDLL_ReadScanData = (P_DLL_READ_SCAN_DATA)GetProcAddress(hDLL, "DLL_ReadScanData_DIO");
if(!pDLL_ReadScanData)
{ /*
do critical error handling here and exit
*/;
return FALSE; }
pSP_EndScan = (P_SP_END_SCAN)GetProcAddress(hDLL, "SP_EndScan");
if(!pSP_EndScan)
{ /*
do critical error handling here and exit
*/;
return FALSE; }
// Start the scan
if(!pDLL_StartScan_DIO(pausDevList[bCurListIndex], pScanObject, 0)
{ /*
do critical error handling here and exit
*/ return FALSE; }
char szBuff [2048], szBuff_Temp[128];
UINT SO_uiStatus_TEMP;
// Make the following anything within reason. The driver reads a minimum of 10 points with each
//   read of the device so it's recommended that you ask for an amount of points divisible by 10
//   with each read from the DLL.
USHORT usNumPointsToRead = 10;
sprintf(szBuff, "SCAN Voltages\r\n\r\n");
clock_t clkScanTestTimeout = clock() + 2000;
NOTE:
This scan (since it's single channel) will scan the channel set by last call to SP_SendChan()
For this example I'll just get 10 scans and then end the scan, displaying the data in a MessageBox.
while (TRUE)
{
//Check to see if all of our scans are ready yet.
//Calling this with usNumPointsToRead set to 0 updates pPSCAN_OBJECT->SO_uiPointsInBuffer
pDLL_ReadScanData(pausDevList[bCurListIndex], pauiDataBuff, 0, pPSCAN_OBJECT);
if (pPSCAN_OBJECT->SO_uiPointsInBuffer >= usNumPointsToRead)
{
// Read the data
pDLL_ReadScanData(pausDevList[bCurListIndex], pauiDataBuff, usNumPointsToRead, pPSCAN_OBJECT);
for (BYTE bIndex = 0; bIndex < 10; bIndex++)
{
sprintf(szBuff_Temp, "%lf\r\n", ((INT)pauiDataBuff[bIndex] - 8388608) * 0.00000059604645);
strcat(szBuff, szBuff_Temp);
}
break;
}
else
{
// Do some kind of handling of error bits that may be set in pPSCAN_OBJECT->SO_uiStatus.
// See possible bit settings above (Scan related variables). at least test for scan HALTED.
SO_uiStatus_TEMP = pPSCAN_OBJECT->SO_uiStatus; // easier to bit test as a fixed variable instead of a pointer.
if(SO_uiStatus_TEMP & SCAN_HALTED) break;
if(clock() > clkScanTestTimeout)
{ sprintf(pBuff, "\r\rScan TIMEOUT ERROR\r\n"); break; }
Sleep(100);
}
}
// Always end the scan when finished
if(!pSP_EndScan(pausDevList[bCurListIndex]))
{ /*
do critical error handling here
*/ }
// Display the data just using a simple MessageBox
MessageBox(GetForegroundWindow(), pBuff, " SCAN DATA --------", 0);
return TRUE;
}
|
-
Channel Change
-
-
BOOLEAN SendChan(void)
{
-
BYTE bChanToSendLocal = 7;
bCurListIndex = 0;
NOTE:
pbLastDigin remains unchanged in this call. It is included only for backward compatibility
if(!pSP_SendChan(pausDevList[bCurListIndex], bCurChan, pbLastDigin))
{ /*
do critical error handling here
*/ }
// Update controls to reflect new channel and digital input value
}
|
-
Send digital output
-
-
BOOLEAN SendDigOut(void)
{
-
BYTE bDigOut = 170;
bCurListIndex = 0
NOTE:
pbLastDigin remains unchanged in this call. It is included only for backward compatibility
if(!pSP_SendDigOut(pausDevList[bCurListIndex], bDigOut, pbLastDigin))
{ /*
do critical error handling here
*/ }
// Update controls to reflect new digital output values
}
|
-
Send analog output
-
-
BOOLEAN SendAnalogOut(void)
{
-
// Supported by Model 302 only
BYTE bDAC = 1;
DOUBLE dblVoltage = 2.5;
bCurListIndex = 0;
if(!pSP_SendDAC(pausDevList[bCurListIndex], dlbVoltage, bDAC, bReserved))
{ /*
do critical error handling here
*/ }
// Update controls to reflect new DAC settings
}
|
-
Change rate
-
-
BOOLEAN SendRate(void)
{
-
DOUBLE dblRate = 600;
bCurListIndex = 0;
if(!pSP_SendRate(&dlbRate, pausDevList[bCurListIndex]))
{ /*
do critical error handling here
*/ }
// Update controls to reflect new rate settings
}
|
|
|