USB-1808 C++ Example - Continuous Analog Input & Output

The example program below demonstrates (using C++) using the USB-1808 to simultaneously stream analog input and output. It also demonstrates device discovery which doesn't require the user to run InstaCal. InstaCal must still be installed because doing so installs the device drivers. At the bottom of this article you will find a Zip file that contains the Visual Studio 2008 project.

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "cbw.h"

#define NUM 4096
#define HALF NUM/2
#define OPTIONS CONTINUOUS + BACKGROUND
#define FIRST 0
#define LAST 1
#define CHANCOUNT 2
#define RESOLUTION 65536
#define MAXNUMDEVS 100

//flags to control when to read or write fresh data
bool inPtrReadLower = TRUE;
bool outPtrWriteLower = TRUE;

int BoardNum = 0;
int ULStat = 0;
long iRate = 4096;
long oRate = 100000;
long Count = NUM;

HGLOBAL MemHandleIn = 0;
HGLOBAL MemHandleOut = 0;

// output data buffer
unsigned short pOut[NUM];


int ReadInput();
int WriteOutput();
void DisplayData(unsigned long datArray[], int rows);

void main (void)
{

   
	float RevLevel = (float)CURRENTREVNUM;

    double angle = 6.28318 / Count;
    double value;

    int numberOfDevices = MAXNUMDEVS;
    DaqDeviceDescriptor inventory[MAXNUMDEVS];
    DaqDeviceDescriptor DeviceDescriptor;
    int BoardNum = -1;


	ULStat = cbDeclareRevision(&RevLevel);
	ULStat = cbErrHandling (PRINTALL, DONTSTOP);

	//Ignore InstaCal device discovery
	cbIgnoreInstaCal();

	//locate USB devices
	ULStat = cbGetDaqDeviceInventory(USB_IFC, inventory, &numberOfDevices);
	for(int i = 0; i < numberOfDevices; i++)
		{
			DeviceDescriptor = inventory[i];

			//Product ID for USB-1808 = 0x13D
			//Product ID for USB-1808X = 0x13E
			//Product IDs can be found in ULProps.txt located in 
			// C:\Program Files (x86)\Measurement Computing\DAQ

			if(DeviceDescriptor.ProductID == 0x13E)
			{
				BoardNum = i;
				//create USB-1808
				ULStat = cbCreateDaqDevice(BoardNum, DeviceDescriptor);
				break;
			}
			
		}

   if(BoardNum < 0)
   {
	   printf("USB device not found...press any key to exit\n");
	   getch();
	   return;
   }

	//Allocate driver buffers
	MemHandleIn = cbWinBufAlloc32(Count);
	MemHandleOut = cbWinBufAlloc(Count);

	//load up users output buffer with data
	for (int i = 0; i < Count; i++)
	{
        value = (sin(angle * i) + 1) * (RESOLUTION/2);
		pOut[i] = (unsigned short)value;
	}

	//transfer users output buffer to internal buffer
	cbWinArrayToBuf(pOut, MemHandleOut,0,Count);
	//Start Analog Output - single channel
	ULStat = cbAOutScan(BoardNum, 0, 0, Count, &oRate, BIP10VOLTS, MemHandleOut, OPTIONS);
	//Start Analog Input
	ULStat = cbAInScan(BoardNum, FIRST, LAST, Count, &iRate, BIP10VOLTS, MemHandleIn, OPTIONS);
	
	//loop reading and writing
	do{
		//WriteOutput is only necessary when the new data is to be written
		//otherwise the existing data will continue to cycle
		WriteOutput();
		ReadInput();

	}while(!kbhit());

	cbStopBackground(BoardNum,AIFUNCTION);
	cbStopBackground(BoardNum,AOFUNCTION);

	cbWinBufFree(MemHandleIn);
	cbWinBufFree(MemHandleOut);

	cbReleaseDaqDevice(BoardNum);
	return;
}

int ReadInput()
{	
	short status;
	long CurCount, CurIndex;
	unsigned long data[HALF];
	cbGetStatus(BoardNum, &status, &CurCount, &CurIndex, AIFUNCTION);
	if(CurCount > 0)
	{
		//read low half of the buffer
		if ((CurIndex > HALF) & inPtrReadLower) //check for 50% more data
		{
			ULStat = cbWinBufToArray32(MemHandleIn,data,0,HALF);
			DisplayData(data, HALF / CHANCOUNT);
			inPtrReadLower = FALSE;
		}
		//read upper half of the buffer
		else if ((CurIndex < HALF ) & !inPtrReadLower)
		{
			ULStat = cbWinBufToArray32(MemHandleIn,data,HALF,HALF);
			DisplayData(data, HALF / CHANCOUNT);
			inPtrReadLower = TRUE;

		}
	}
	return 0;
}

int WriteOutput()
{	
	short status;
	long CurCount, CurIndex;

	cbGetStatus(BoardNum, &status, &CurCount, &CurIndex, AOFUNCTION);

	if ((CurIndex > HALF) & outPtrWriteLower) //check if low half need update
	{
		ULStat = cbWinArrayToBuf(pOut, MemHandleOut, 0, HALF);
		outPtrWriteLower = FALSE;
	}
	else if ((CurIndex < HALF ) & !outPtrWriteLower)
	{
		//increment data array by HALF to point to the upper half of the buffer
		ULStat = cbWinArrayToBuf(pOut+HALF, MemHandleOut, HALF, HALF);
		outPtrWriteLower = TRUE;

	}
	return 0;
}


void DisplayData(unsigned long datArray[], int rows)
{
    //Writes data to screen and to file
    int i = 0;
    for (int row = 0; row < rows; row++)
    {

        for (int c = 0; c < CHANCOUNT; c++)
        {
            printf("%d\t", datArray[i]);
            i++;
        }
        printf("\r\n");
    }
}

Attachments
VC_2008_USB-1808_AnalogOutput.zip