Function call prototypes and pointer casting from header file.
(only those used in following example shown)
see other protypes
here
|
-
-
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;
|
Variables declarations from header file
(only those used in following example shown)
see other protypes
here
|
-
-
-
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
|
|
|
-
Scanning -
Showing multi-chan-digin scan (CMND_MULTI_CHAN_SCAN)
- this scan includes digital in put in separate buffer with each conversion
Back
to main source:
- Shows complete initialization, misc functions, I/O, and CMND_SINGLE_CHAN_SCAN type scan
Links to other scan types:
CMND_SINGLE_CHAN_DIGIN_SCAN single chan - includes digin in separate buffer with each conversion
CMND_MULTI_CHAN_CAL_SCAN multi chan - includes chan 7 each scan
CMND_MULTI_CHAN_DIGIN_SCAN multi chan - includes digin in separate buffer with each conversion
CMND_MULTI_CHAN_DIGIN_CAL_SCAN multi chan - includes digin in separate buffer with each conversion and chan 7 each scan
-
-
BOOLEAN DoScan(void)
{
-
NOTE:
The following is just an overview of the CMND_MULTI_CHAN_SCAN scanning procedure.
Please see sample source code downloadable from web site for working example.
//Total channels to scan (1-8).
Chan 6 is full scale and 7 (already included in this type of scan) is offset for calibration usage.
BYTE bNumMultiChanCnt = 5;
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_MULTI_CHAN_SCAN;
pScanObject->SO_dblRate = padblRate[bCurListIndex];
pScanObject->SO_uiPointsInBuffer = 0;
pPSCAN_OBJECT->SO_bScanArg = bNumMultiChanCnt;
UINT SO_uiStatus_TEMP;
// 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");
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; }
//Make the following anything within reason. One scan consists of data for all channels set to scan.
BYTE bNumScans = 3;
USHORT usNumPointsToRead = bNumMultiChanCnt * bNumScans;
UINT* pauiDataBuff = new UINT[usNumPointsToRead];
if(!pauiDataBuff) { /*
do critical error handling here and exit (can't go further if this fails)
*/ return FALSE; }
memset(pauiDataBuff, 0, usNumPointsToRead);
// Start the scan
if(!pDLL_StartScan_DIO(pausDevList[bCurListIndex], pScanObject, 0)
{
  // Do critical error handling here and exit
  delete [] pauiDataBuff; delete [] pabDiginBuff; return FALSE;
}
char szBuff [2048], szBuff_Temp[128];
sprintf(pBuff, "SCAN Voltages Digital input\r\n\r\n");
//Always set the following to 0 for scans that include digital input.
bCurChan = 0;
BYTE bScanIndex = 0, bChanIndex = 0, bBuffIndex = 0;
DOUBLE dblTimeout = (double)usNumPointsToRead * 5 * (1.0 / padblRate[bCurListIndex]);
UINT uiTimeoutMultiplier = 2; UINT uiTimeout = dblTimeout * 1000 * uiTimeoutMultiplier;
clock_t clkTimeout = clock() + uiTimeout;
NOTE:
This scan will scan the number of channels passed in the pPSCAN_OBJECT->SO_bScanArg
structure member. The multi-channel scans only scan channel sequentially. The digital
input is returned for each point into a separate "mirrored" buffer. In other words, the offset
of the digital input in one buffer matches the offset of the data point within the
other buffer. See the C/C++ function call prototypes for more information concerning
this type of scan.
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, usNumPointsToRead, pPSCAN_OBJECT);
if (pPSCAN_OBJECT->SO_uiPointsInBuffer >= usNumPointsToRead)
{
// Read the data
pDLL_ReadScanData(pausDevList[bCurListIndex], pauiDataBuff, 0, pPSCAN_OBJECT);
for (bScanIndex; bScanIndex < bNumScans; bScanIndex++)
{
for (bChanIndex = 0; bChanIndex < bNumMultiChanCnt; bChanIndex++)
{
sprintf(szBuff_Temp, "Chan: %d %2.3lf\r\n", bChanIndex, ((INT)pauiDataBuff[bBuffIndex] - 8388608) * 0.00000059604645);
strcat(pBuff, szBuff_Temp);
bBuffIndex++;
}
strcat(pBuff, "\r\n");
}
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(50);
}
}
// 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);
delete [] pauiDataBuff;
return TRUE;
}
|
|