Measurement Computing   Easy to Use | Easy to Integrate | Easy to Support catalog banner

Measurement Computing Data Acquisition Knowledgebase

Welcome Guest ( )

How to program two USB-1608G

Expand / Collapse
 

How to program two USB-1608G


The example below demonstrates how to read two USB-1608G. The example C# project can be found as an attachment at the bottom. 

The program assumes you have two USB-1608G (Or 1608GX or 1608GX-2AO) devices configured in InstaCal for board number 0 and 1. For simplicity, both devices were configured for the same number of channels.

Data collection uses a do...while loop that continuously reads both device buffers one half at a time. The continuous mode is set using the Scan Options enumeration Background and Continuous. Data is collected by ping-ponging between the lower half then the upper. Care should be taken that data doesn't come in so fast that the program fails to keep up. When this happens a buffer overrun occurs which is condition where unread data get overwritten. If this happens, a bigger buffer or lower sample rate is usually the fix.

Depending on your use case, you may want to synchronize both USB-1608G using the AICKO and AICKI signals. The AICKO pin is the output clock and the AICKI pin is the input clock. To synchronize the two, wire the one to the other. For instance, AICKO (board number 0) to AICKI (board number 1). Board number 0 will be the clock provider and 1 will be the receiver. The output clock is always active, but the input clock isn’t. To use the input clock, include EXTCLOCK in the AInScan Scan Options parameter when programming the receiver. For example, ScanOptions.Background | ScanOptions.ScaleData | ScanOptions.Continuous | ScanOptions.ExtClock. If you go this route, the key is to program the clock receiver first then the clock provider. The reason for this is that the receiver waits for the clock signal before starting. When you start the provider (by calling AInScan), its output clock becomes active which simultaneously start the receive

This program is a 32-bit C# Console Application. If you start a new project, you must first add a Dot Net reference to the MccDaq object. The InstaCal installation our Dot Net UL object. Adding the reference is usually accomplished by right clicking the Project [under the Project Explorer] and selecting Add Reference.

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;
namespace AinScanBackgroundContinuousScan
{
    class Program
    {
        public const int BLOCKSIZE = 256;
        public const int CHANCOUNT = 2;
        public const int FIRSTCHANNEL = 0;
        public const int LASTCHANNEL = 1;
        public const int FREQ = 256;
        public const int BUFFERSIZE = BLOCKSIZE * CHANCOUNT;
        public const int HALFBUFFSIZE = BUFFERSIZE / 2;

        static void Main(string[] args)
        {

            MccDaq.ErrorInfo RetVal;

            int Rate = FREQ;

            bool ReadLower = true;

            MccBoard daq0 = new MccDaq.MccBoard(0);
            MccBoard daq1 = new MccDaq.MccBoard(1);

            IntPtr buffer0 = MccService.ScaledWinBufAllocEx(BUFFERSIZE);
            IntPtr buffer1 = MccService.ScaledWinBufAllocEx(BUFFERSIZE);


            short[] chArray = new short[CHANCOUNT]; //configuration array for channel numbers
            Range[] chRange = new Range[CHANCOUNT]; //configuration array for input ranges

            //choose channel order
            chArray[0] = 0;
            chArray[1] = 1;

            //select channel range
            chRange[0] = Range.Bip10Volts;
            chRange[1] = Range.Bip10Volts;

            RetVal = daq0.ALoadQueue(chArray, chRange, CHANCOUNT);
            IsError(RetVal);

            RetVal = daq1.ALoadQueue(chArray, chRange, CHANCOUNT);
            IsError(RetVal);

            //setup the acquisiton
            RetVal = daq0.AInScan(FIRSTCHANNEL,
                                    LASTCHANNEL,
                                    BUFFERSIZE,
                                    ref Rate,
                                    Range.Bip10Volts,
                                    buffer0,
                                    ScanOptions.Background | ScanOptions.ScaleData | ScanOptions.Continuous
                                );
            IsError(RetVal);

            RetVal = daq1.AInScan(FIRSTCHANNEL,
                                     LASTCHANNEL,
                                     BUFFERSIZE,
                                     ref Rate,
                                     Range.Bip10Volts,
                                     buffer1,
                                     ScanOptions.Background | ScanOptions.ScaleData | ScanOptions.Continuous | ScanOptions.ExtClock
                                    );
            IsError(RetVal);

            int Count = 0;
            int Index = 0;
            short daqStatus;

            double[] Data0 = new double[HALFBUFFSIZE];
            double[] Data1 = new double[HALFBUFFSIZE];
            int rows = HALFBUFFSIZE / CHANCOUNT;
            System.ConsoleKeyInfo cki = new System.ConsoleKeyInfo();

            //Loop until key press
            do
            {
                //check status on the device receiving the clock
                RetVal = daq1.GetStatus(out daqStatus, out Count, out Index, FunctionType.AiFunction);
                if ((Index >= HALFBUFFSIZE) & ReadLower) //check for 50% more data
                {
                    //get lower half of buffer - ScaledWinBufToArray returns engineering units
                    RetVal = MccService.ScaledWinBufToArray(buffer0, Data0, 0, HALFBUFFSIZE);
                    IsError(RetVal);

                    RetVal = MccService.ScaledWinBufToArray(buffer1, Data1, 0, HALFBUFFSIZE);
                    IsError(RetVal);

                    DisplayData(Data0, Data1, rows);
                    ReadLower = false; //flag that controls the next read
                }
                else if ((Index < HALFBUFFSIZE) & !ReadLower)
                {
                    //get the upper half  - ScaledWinBufToArray returns engineering units
                    RetVal = MccService.ScaledWinBufToArray(buffer0, Data0, HALFBUFFSIZE, HALFBUFFSIZE);
                    IsError(RetVal);
                    RetVal = MccService.ScaledWinBufToArray(buffer1, Data1, HALFBUFFSIZE, HALFBUFFSIZE);
                    IsError(RetVal);

                    DisplayData(Data0, Data1, rows);
                    ReadLower = true;//flag that controls the next read
                }
                System.Threading.Thread.Sleep(100);

            } while (!Console.KeyAvailable);

            cki = Console.ReadKey();


            //stop the  acquisition
            RetVal = daq0.StopBackground(FunctionType.AiFunction);
            RetVal = daq1.StopBackground(FunctionType.AiFunction);

            //free up memory
            MccService.WinBufFreeEx(buffer0);
            MccService.WinBufFreeEx(buffer1);

            WaitForKey();

        }

        //error check routine
        public static int IsError(ErrorInfo e)
        {
            if (e.Value != 0)
            {
                Console.WriteLine(e.Message);
                return 1;
            }
            return 0;
        }

        //routine to wait for a key press
        public static void WaitForKey()
        {
            Console.WriteLine("\nPress <SpaceBar> to continue...");

            System.ConsoleKeyInfo cki;
            do
            {
                cki = Console.ReadKey();
            } while (cki.Key != ConsoleKey.Spacebar);
        }

        //This routine prints the data to the screen
        public static void DisplayData(double[] buf0, double[] buf1, int rows)
        {
            //Writes data to screen and to file
            int i = 0;

            for (int row = 0; row < rows; row++)
            {
                //print daq0 array
                for (int c = 0; c < CHANCOUNT; c++)
                {
                    Console.Write("{0}\t", buf0[i].ToString("0.0000").PadLeft(10));
                    i++;
                }
                //print daq1 array
                i = 0;
                for (int c = 0; c < CHANCOUNT; c++)
                {
                    Console.Write("{0}\t", buf1[i].ToString("0.0000").PadLeft(10));
                    i++;
                }
                Console.Write("\r\n");
            }
        }

    }
}



Rate this Article:
Tags:

Attachments


CSharp_2x_USB_1608G.zip CSharp_2x_USB_1608G.zip (4.21 KB, 418 views)

Add Your Comments


For comments email [email protected].

Details
Article ID: 50798

Last Modified:1/9/2020 8:11:00 AM

Article has been viewed 2,815 times.

Options