Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
daq-and-datalogging:documents:usb-1808-polling-subsystems [2023/06/13 16:18] – created Scandiwebdaq-and-datalogging:documents:usb-1808-polling-subsystems [2023/07/28 01:01] (current) – Arthur Brown
Line 1: Line 1:
-====== Using a USB-TEMP-AI module and DAQami to measure temperature ======+====== USB-1808 Reading Multiple Subsystems With Polling ======
  
-This article explains how to use a USB-TEMP-AI module with DAQami to measure a 2-wire thermistor.  (A RTD sensor or thermocouple could also be used.)  This article assumes that the end-user has installed the latest MCC DAQ CD, which includes InstaCal and DAQami, and has the Steinhart-Hart Coefficients from the thermistor manufacturer. +The following example uses the DaqInScan function to simultaneous read the USB-1808 subsystems. It is configured to read four analog inputs, the four bit digital port, and one encoder channel. It configures a buffer with a size of packet times channel count times multiplier. To make the buffer bigger/smaller change change the multiplier. The sample rate is 3600 samples per second. The loop is set so as to read when a new half buffer is available.  The print routine prints only the first 32 samples to prevent it from consuming available time  
  
-In order to use a USB-TEMP-AI module, with DAQami, a user must first configure it with InstaCal.  Launch MCC’s InstaCal utility.  Once the USB-TEMP-AI module is visible in the PC Board List,  double mouse-click it to access the Board Configuration window.  Configure the Temperature Channels to be used; see image below.+To access the API, add a reference to the MccDaq object. Adding the reference is usually accomplished by right clicking the Project [under the Project Explorer and selecting Add Reference. The complete project is attached to the article and was created with Visual Studio 2008 using CSharp. Compiling and execution is quick as there is minimal Windows overhead and associated code. 
  
-{{https://files.digilent.com/resources/measurement-computing/Reference Images/pic_1.png?866x622}}+To make the code more readable a few convenience functions were added such as IsError, GetBoardNum, and WaitForKey. The IsError function checks the error number in the ErrorInfo object and if not zero displays the error message.  The GetBoardNum function begins reading the Device strings from each number location and as soon as it finds one that contains the identifying string it exits. The WaitForKey does just that - waits for someone to press a key. To view the complete program project download the attachment below.
  
-Verify the temperature readings via InstaCal's top menu option TEST - ANALOG.+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.
  
-{{https://files.digilent.com/resources/measurement-computing/Reference Images/pic_2.png?503x577}}+<code> 
 +using System; 
 +using MccDaq; // also, add reference to MccDaq to the project
  
-Afterwards, exit InstaCal and then launch DAQami.  (NOTE: Make sure you have closed InstaCal prior to loading DAQami!)   
  
-In DAQami’s Getting Started window, select ‘New Configuration’ icon followed by the ‘Automatic’ option.  DAQami displays the first four analog input channels (AI0 – AI3) as Active Channels, on the left side, and a Strip display on the right side.  In the upper left-hand corner, click on the third icon button to view the Configuration Panel.  Next, click on the Channels tab.  The top four analog input channels (AI0 – AI3) are the voltage input channels, while channels AI4 – AI7 are the temperature channels.  Deselect channels AI0 - AI3 and select temperature channel AI4.  When a temperature channel is selected, its Channel Settings shows the available options for TC Type and temperature units.  (Note:  If using a thermistor or RTD sensor, ignore the 'TC Type' option and select only the temperature channel(s) configured previously in InstaCal.)+//This program uses the DaqInScan function to read 4x AI, 1x DigIn, 1x Encoder simultaneously. It configures a  
 +//buffer with a size of packet times channel count time multipliers. To make the buffer bigger/smaller change 
 +//change the multiplier. The sample rate is 3600 samples per second. The loop is set so as to read when 
 +//a new half buffer is available. The program retrieves one half of the buffer when it available. The print  
 +//routine prints only the first 32 samples to prevent it from consuming available time
  
-{{https://files.digilent.com/resources/measurement-computing/Reference Images/pic_3.png?615x444}}+namespace CSharp_USB_1808_DaqInScanEncoder 
 +{ 
 +    static class Constants 
 +    { 
 +        public const int ChanCount = 6; //number of channels (4x AI, 1x DigIn, 2x Encoder) 
 +        public const int PACKET = 128; 
 +        public const int BUFFMULTIPLER = 100; 
 +        public const int BUFFSIZE = PACKET * ChanCount * BUFFMULTIPLER; 
 +        public static int bufferSize = BUFFSIZE; 
 +        public static int halfbuf = bufferSize / 2; 
 +        public const int COUNTER = 2;  //first encoder channel 
 +        public static int rows = halfbuf / ChanCount; 
 +        public static MccBoard daq; 
 +        public static int rate = 3600; 
 +        public static int preTrigCount = 0;
  
-Click on the third icon button, in the upper left corner, to switch to the Display Panel.  Right click on the Strip display and select Remove Display.  Next, click on the second icon button, in the upper left corner, to view the Display options.  Click on the Scalar option and drag it over to the Display Panel.  Then, click on an Active Channel to drag and drop onto the Scalar display.+    } 
 +    class Program 
 +    {
  
-{{https://files.digilent.com/resources/measurement-computing/Reference Images/pic_4.png?800x374}}+        static void Main(string[] args) 
 +        { 
 +            int BoardNum    = 0; 
 +            short daqStatus = 0; 
 +            int Count       = 0; 
 +            int Index       = 0; 
 + 
 +            short[]         ChanArray       = new short[Constants.ChanCount];         // array to hold channel queue information 
 +            ChannelType[]   ChanTypeArray   = new ChannelType[Constants.ChanCount];   // array to hold channel type information 
 +            Range[]         GainArray       = new Range[Constants.ChanCount];         // array to hold gain queue information 
 + 
 + 
 + 
 + 
 + 
 +            Console.WriteLine("Locating Device...Please wait\n"); 
 + 
 +            BoardNum = GetBoardNum("1808"); 
 + 
 +            if (BoardNum == -1) 
 +            { 
 +                Console.WriteLine("Device not detected!"); 
 +                WaitForKey(); 
 +                return; 
 +            } 
 +            else 
 +            { 
 +                Constants.daq = new MccDaq.MccBoard(BoardNum); 
 +           
 +                Constants.daq.AInputMode(AInputMode.SingleEnded); 
 + 
 +                CounterMode CMODE = CounterMode.Encoder | CounterMode.EncoderModeX1; 
 + 
 +                IsError(Constants.daq.CConfigScan(  2, 
 +                                                    CMODE, 
 +                                                    CounterDebounceTime.DebounceNone, 
 +                                                    CounterDebounceMode.TriggerAfterStable, 
 +                                                    CounterEdgeDetection.RisingEdge, 
 +                                                    CounterTickSize.Tick20ns, 
 +                                                    0)); 
 + 
 + 
 +                int i = 0; 
 +                ChanArray[i] = 0; 
 +                ChanTypeArray[i] = ChannelType.Analog; 
 +                GainArray[i] = Range.Bip10Volts; 
 +                i++; 
 + 
 +                ChanArray[i] = 1; 
 +                ChanTypeArray[i] = ChannelType.Analog; 
 +                GainArray[i] = Range.Bip10Volts; 
 +                i++; 
 + 
 +                ChanArray[i] = 2; 
 +                ChanTypeArray[i] = ChannelType.Analog; 
 +                GainArray[i] = Range.Bip10Volts; 
 +                i++; 
 + 
 +                ChanArray[i] = 3; 
 +                ChanTypeArray[i] = ChannelType.Analog; 
 +                GainArray[i] = Range.Bip10Volts; 
 +                i++; 
 + 
 + 
 +                ChanArray[i] = (int)DigitalPortType.AuxPort; 
 +                ChanTypeArray[i] = ChannelType.Digital; 
 +                GainArray[i] = Range.NotUsed; 
 +                i++; 
 + 
 +                ChanArray[i] = 2; //encoder channels are 2 & 3 
 +                ChanTypeArray[i] = ChannelType.Ctr; 
 +                GainArray[i] = Range.NotUsed; 
 +                i++; 
 + 
 +  
 +                ScanOptions Options =   ScanOptions.Default 
 +                                        | ScanOptions.Continuous 
 +                                        | ScanOptions.Background; 
 + 
 +                //allocate buffer 
 +                int bufferSize = Constants.bufferSize; 
 + 
 +                IntPtr buffer = MccService.WinBufAlloc32Ex(Constants.bufferSize); 
 + 
 +                 
 +                IsError(Constants.daq.DaqInScan(ChanArray,  
 +                                                ChanTypeArray,  
 +                                                GainArray,  
 +                                                Constants.ChanCount,  
 +                                                ref Constants.rate,  
 +                                                ref Constants.preTrigCount, 
 +                                                ref Constants.bufferSize,  
 +                                                buffer,  
 +                                                Options)); 
 + 
 +                System.ConsoleKeyInfo cki = new System.ConsoleKeyInfo(); 
 + 
 +                Console.WriteLine("Retrieving Data\n"); 
 + 
 +                int[] UserBuffer = new int[Constants.halfbuf]; 
 +                bool ReadLower = true; 
 +                do 
 +                { 
 + 
 +                    IsError(Constants.daq.GetStatus(out daqStatus, out Count, out Index, FunctionType.DaqiFunction)); 
 +                    if ((Index >= Constants.halfbuf) & ReadLower) //check for 50% more data 
 +                    { 
 +                        //get lower half of buffer 
 +                        IsError(MccService.WinBufToArray32(buffer, UserBuffer, 0, Constants.halfbuf)); 
 + 
 +                        DisplayData(UserBuffer, Constants.rows); 
 +                        ReadLower = false; //flag that controls the next read 
 +                    } 
 +                    else if ((Index < Constants.halfbuf) & !ReadLower) 
 +                    { 
 + 
 +                        //get the upper half 
 +                        IsError(MccService.WinBufToArray32(buffer, UserBuffer, Constants.halfbuf, Constants.halfbuf)); 
 + 
 +                        DisplayData(UserBuffer, Constants.rows); 
 +                        ReadLower = true;//flag that controls the next read 
 +                    } 
 + 
 +                } while (!Console.KeyAvailable); 
 +                cki = Console.ReadKey(); 
 + 
 +                //stop background operation 
 +                IsError(Constants.daq.StopBackground(FunctionType.DaqiFunction)); 
 + 
 +                //free up memory 
 +                IsError(MccService.WinBufFreeEx(buffer)); 
 + 
 +                WaitForKey(); 
 +            } 
 +            // end of program 
 +        } 
 +        /*////////////////////////////////////////////////////////////////////////////////////*/ 
 + 
 +        public static int GetBoardNum(string dev) 
 +        { 
 + 
 +            MccDaq.DaqDeviceManager.IgnoreInstaCal(); 
 +            MccDaq.DaqDeviceDescriptor[] inventory = MccDaq.DaqDeviceManager.GetDaqDeviceInventory(MccDaq.DaqDeviceInterface.Any); 
 +            int DevicesFound = inventory.Length; 
 +            if (DevicesFound > 0) 
 +            { 
 +                for (int boardNum = 0; boardNum < DevicesFound; boardNum++) 
 +                { 
 + 
 +                    try 
 +                    { 
 + 
 +                        if (inventory[boardNum].ProductName.Contains(dev)) 
 +                        { 
 +                            MccDaq.MccBoard daqBoard = MccDaq.DaqDeviceManager.CreateDaqDevice(boardNum, inventory[boardNum]); 
 +                            Console.WriteLine("Product Name:    {0}", inventory[boardNum].ProductName); 
 +                            Console.WriteLine("Device Type # :  {0}", inventory[boardNum].ProductID); 
 +                            Console.WriteLine("Serial # :       {0}", inventory[boardNum].UniqueID); 
 +                            return boardNum; 
 +                        } 
 +                    } 
 +                    catch (ULException ule) 
 +                    { 
 +                        Console.WriteLine("Error occured: " + ule.Message); 
 +                    } 
 +                } 
 +            } 
 +            return -1; 
 +        } 
 +        /*////////////////////////////////////////////////////////////////////////////////////*/ 
 + 
 +        public static void WaitForKey() 
 +        { 
 +            Console.WriteLine("\nPress any key to continue..."); 
 +            do 
 +            {   //idle loop 
 +                System.Threading.Thread.Sleep(10); 
 +            } while (!Console.KeyAvailable); 
 +        } 
 + 
 +        /*////////////////////////////////////////////////////////////////////////////////////*/ 
 + 
 +        public static int IsError(ErrorInfo e) 
 +        { 
 +            if (e.Value != 0) 
 +            { 
 +                Console.WriteLine(e.Message); 
 +                WaitForKey(); 
 +                return 1; 
 +            } 
 +            return 0; 
 +        } 
 +       //************************************************************** 
 +        public static void DisplayData(int[] datArray, int rows) 
 +        { 
 +            //Writes data to screen and to file 
 +            int i = 0; 
 +            double temp; 
 +            if (rows > 32) rows = 32; 
 +            for (int row = 0; row < rows; row++) 
 +            { 
 +                for (int c = 0; c < Constants.ChanCount; c++) 
 +                { 
 +                    if (c < 4) 
 +                    { 
 +                        IsError(Constants.daq.ToEngUnits32(Range.Bip10Volts, datArray[i], out temp)); 
 +                        Console.Write("{0}\t", temp.ToString("0.000")); 
 +                    } 
 +                    else 
 +                        Console.Write("{0}\t", datArray[i].ToString("000000")); 
 + 
 +                    i++; 
 +                } 
 +                Console.Write("\r\n"); 
 +            } 
 +            Console.WriteLine("\nScans of data read {0}\n", Constants.rows); 
 + 
 +        } 
 +         
 +        /*////////////////////////////////////////////////////////////////////////////////////*/ 
 + 
 +    } 
 +} 
 +</code> 
 + 
 +**Attachments**\\ 
 +[[ https://files.digilent.com/reference-attachments/CSharp_USB_1808_DaqInScanEncoder.zip | CSharp_USB_1808_DaqInScanEncoder.zip ]]
  
-Finally, in the top center of DAQami, click the green arrow to start an acquisition.