CSharp (C#) AIn/Aout Sweep Generator
The example below is closely related to the Streaming AIn/AOut Function Generator example described in a previous article. It streams data out the analog output pins while at the same time reading it back in. However the waveform consists of a sweeping frequency from 10 Hz to 1000 Hz. To use this program you must have a device that supports hardware analog output scanning at rates of at lest 50,000 per second. At the beginning of the program where the constants are defined there is a section of tested devices. Uncomment the device you have and comment the current device which is the USB-1408FS-Plus.
The example program writes the data to a text file that is compatible with the DASYLab ReadFile module and Excel. To visually verify the data, I found the easiest method was to read the file in with DASYLab and display it in a strip chart. Connect the outputs to the inputs using wire and run the program to generate the data file. Run the attached DASYLab 13.0 test worksheet to see the data. The worksheet will not only display data but will also measure the frequency. If you change the example program's block size and sample rate you must also change it in the DASYLab worksheet in the Read module ASCII Options. If you don't have DASYLab there is 30 day evaluation available on the MCC web site.
The program uses the MccDaq.dll .net assembly API. To be able to access this API, in your project add a reference to it. Adding the reference is usually accomplished by right clicking the Project [under the Project Explorer] and selecting Add Reference. On the .NET page find and select the MccDaq component. My complete Visual Studio 9.0 project is attached to this article further down.
Disclaimer:
The attached Code or Example is provided As Is. It has not been tested or validated as a product, for use in a deployed application or system, or for use in hazardous environments. You assume all risks for use of the Code or Example.
using System; using MccDaq; using System.IO; using System.Linq; namespace Ain_Aout_Sweep_Generator { class Program { public const int iBLOCKSIZE = 4096; //input block size public const int oBLOCKSIZE = 65536 * 4; //output block size public const int iFREQ = 5000; //input sample rate public const int oFREQ = 50000; //output update rate public const int FIRSTCHANNEL = 0; public const int LASTCHANNEL = 0; public const int CHANCOUNT = 1; public const int iBUFFERSIZE = iBLOCKSIZE * CHANCOUNT; //input buffer size public const int oBUFFERSIZE = oBLOCKSIZE * CHANCOUNT; //output buffer size public const int iHALFBUFFSIZE = iBUFFERSIZE / 2; public const int oHALFBUFFSIZE = oBUFFERSIZE / 2; //The following devices have been tried...Uncomment yours //public const string DEVICE = "PCI-DAS6052"; //public const int RESOLUTION = 65535; public const ScanOptions ExtraOpts = ScanOptions.BurstMode | ScanOptions.BlockIo; //public const string DEVICE = "USB-1608GX-2AO"; //public const int RESOLUTION = 65535; public const ScanOptions ExtraOpts = ScanOptions.BurstMode | ScanOptions.BlockIo; //public const string DEVICE = "USB-1616HS-4"; //public const int RESOLUTION = 65535; public const ScanOptions ExtraOpts = ScanOptions.BlockIo; //public const string DEVICE = "USB-1616HS-2"; //public const int RESOLUTION = 65535; public const ScanOptions ExtraOpts = ScanOptions.BlockIo; //public const string DEVICE = "USB-2527"; //public const int RESOLUTION = 65535; public const ScanOptions ExtraOpts = ScanOptions.BlockIo; //public const string DEVICE = "USB-1208HS-4AO"; //public const int RESOLUTION = 4096; public const ScanOptions ExtraOpts = ScanOptions.BurstMode|ScanOptions.BlockIo; public const string DEVICE = "USB-1408FS-Plus"; public const int RESOLUTION = 4096; public const ScanOptions ExtraOpts = ScanOptions.BlockIo; //public const string DEVICE = "USB-1208FS-Plus"; //public const int RESOLUTION = 4096; public const ScanOptions ExtraOpts = ScanOptions.BlockIo; public static StreamWriter fStream; public static IntPtr OutBuf; public static IntPtr buffer; public static bool inLower; public static bool outLower; public static ushort[] inArray; public static ushort[] outArray; public static MccBoard daq; public static MccDaq.ErrorInfo RetVal; // ************************************************************************************************ // ************************************************************************************************ // ************************************************************************************************ static void Main(string[] args) { MccDaq.ErrorInfo RetVal; int BoardNum = 0; int iRate = iFREQ; //input rate int oRate = oFREQ; //output rate inLower = true; outLower = true; Console.WriteLine("Connecting to {0}", DEVICE); BoardNum = GetBoardNum(DEVICE); if (BoardNum == -1) { Console.WriteLine("No {0} detected!", DEVICE); WaitForKey(); return; } else { ///////// BEGIN PROGRAM /////////// daq = new MccDaq.MccBoard(BoardNum); //create the driver buffers OutBuf = MccService.WinBufAllocEx(oBUFFERSIZE); buffer = MccService.ScaledWinBufAllocEx(iBUFFERSIZE); Console.WriteLine("{0} Connected", DEVICE); if ((OutBuf == IntPtr.Zero) || (buffer == IntPtr.Zero)) { Console.WriteLine("Insufficient Memory"); WaitForKey(); return; } //create the user output buffer. outArray = new ushort[oBUFFERSIZE]; //create the waveforms float startFreq = 10.0f; float stopFreq = 1000.0f; GetWaveForm(outArray,startFreq,stopFreq); //write the user data to the driver buffer MccService.WinArrayToBuf(outArray, OutBuf, 0, oBUFFERSIZE); //start the waveform RetVal = daq.AOutScan(FIRSTCHANNEL, LASTCHANNEL, oBUFFERSIZE, ref oRate, Range.Bip10Volts, OutBuf, ScanOptions.Background | ScanOptions.Continuous ); if (IsError("AOutScan", RetVal) == 1) return; short[] chArray = new short[CHANCOUNT]; //configuration array for channel numbers for (short i = 0; i < CHANCOUNT; i++) chArray[0] = i; fStream = new StreamWriter(@"C:\Users\Public\Documents\DataFile.asc"); CreateFileHeaders(chArray); //writes basic info to the beginning of the file System.ConsoleKeyInfo cki; WaitForKey(); //begin analog input RetVal = daq.AInScan(FIRSTCHANNEL, LASTCHANNEL, iBUFFERSIZE, ref iRate, Range.Bip10Volts, buffer, ScanOptions.Background | ScanOptions.Continuous | ExtraOpts ); if (IsError("AInScan", RetVal) == 1) return; bool exit = false; //do loop to switch waveforms and read/write data do { if (Console.KeyAvailable) { cki = Console.ReadKey(true); switch (cki.Key) { case ConsoleKey.Spacebar: exit = true; break; } } if (ReadInputBuffer() == 1) return; if (WriteOutputBuffer() == 1) return; } while (!exit); //flush buffered data out to disk fStream.Flush(); //close file fStream.Close(); //stop the acquisition RetVal = daq.StopBackground(FunctionType.AiFunction); RetVal = daq.StopBackground(FunctionType.AoFunction); //free up memory MccService.WinBufFreeEx(buffer); MccService.WinBufFreeEx(OutBuf); return; } }
Attachments
AIn_Aout_Sweep_Generator.zip