Jump to content
  • 0

thermocouple inputs on USB 1616HS


e_reed

Question

I'm trying to find the fastest way to read TC inputs on a USB-1616HS-4. When I use ul.t_in_scan() I can read 8 TC values with good accuracy. But when I use ul.daq_in_scan() with the CJCs and the 8 TCs, all the temperature values are off by 10-20 degrees (F), however they are still responsive to temperature changes and the direction of the differential signal is correct. Is there a way to find out the CJC offset, or is there additional calibration that I'm missing?

Link to comment
Share on other sites

2 answers to this question

Recommended Posts

  • 0

Hello @e_reed

Hopefully you don't mind reviewing C#. I'm hoping to have a mcculw Python example next week. Attached is a C# example that uses the DaqInScan functionality to continuously collect TC data. First, it's important to associate the correct CJC channel with each TC channel. For instance, CJC3 is assigned to TC4 and CJC4 is assigned to both TC5 and TC6.  Collecting the 16 channels (8x CJC and 8x TC) should be straightforward. The default oversample property is 256 which makes the device no faster than 1M Hz / 256 / number of channels or about 244 Hz. When in doubt check the return 'rate' variable from DaqInScan.

The confusing part is the GetTCValues. I put a few notes in the section that continuously reads the data and gets the TC values.

Below is the algorithm that spins while data is being collected waiting to process more data when another half buffer has filled. The WinBufToArray is not needed but is included if later you change a TC channel back to Analog voltage or digital.

using System;
using MccDaq; // also, add reference to MccDaq to the project

//This program uses the DaqInScan function to read 8 thermocouple channels; the return data 
//in the form of raw counts from both the CJC and the thermocouple; in order to get
//temperature data, as second function named GetTCValues is used
namespace CSharp_USB_1616HS_DaqInScan
{
    static class Constants
    {
        public const int ChanCount = 16; //number of channels ( 8x TC 8x CJC)

        public const int BUFFSIZE = 32 * ChanCount;
        public static int bufferSize = BUFFSIZE;
        public const int HALFBUFF = BUFFSIZE / 2;

        public static MccBoard daq;
        public static int rate = 100;
        public static int preTrigCount = 0;
        public const int TC_Count = 2;


    }
    class Program
    {

        static void Main(string[] args)
        {
            int BoardNum = 0;
            int Count = 0;
            int Index = 0;
            short daqStatus = 0;

            ushort[] ADData = new ushort[Constants.BUFFSIZE]; //raw data
            float[] tempVals = new float[Constants.BUFFSIZE]; //used for temperatures

            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("1616");

            if (BoardNum == -1)
            {
                Console.WriteLine("Device not detected!");
                WaitForKey();
                return;
            }
            else
            {
                Constants.daq = new MccDaq.MccBoard(BoardNum);


                Constants.daq.AInputMode(AInputMode.Differential);
               


                //Channel configuration array definitions
                int i = 0;


                //if mixing voltage an TC, make the TC channels first in the list for easier conversion using GetTCValues. 

                //TC0
                ChanArray[i] = 0;
                ChanTypeArray[i] = ChannelType.CJC;
                GainArray[i] = Range.NotUsed;
                i++;

                ChanArray[i] = 0;
                ChanTypeArray[i] = ChannelType.TC;
                GainArray[i] = Range.NotUsed;

                //TC1
                i++;
                ChanArray[i] = 1;
                ChanTypeArray[i] = ChannelType.CJC;
                GainArray[i] = Range.NotUsed;
                i++;

                ChanArray[i] = 1;
                ChanTypeArray[i] = ChannelType.TC;
                GainArray[i] = Range.NotUsed;
                i++;

                //TC2
                ChanArray[i] = 1; //TC2 uses CJC1
                ChanTypeArray[i] = ChannelType.CJC;
                GainArray[i] = Range.NotUsed;
                i++;

                ChanArray[i] = 2;
                ChanTypeArray[i] = ChannelType.TC;
                GainArray[i] = Range.NotUsed;
                i++;

                //TC3
                ChanArray[i] = 2; //TC3 uses CJC2
                ChanTypeArray[i] = ChannelType.CJC;
                GainArray[i] = Range.NotUsed;
                i++;

                ChanArray[i] = 3;
                ChanTypeArray[i] = ChannelType.TC;
                GainArray[i] = Range.NotUsed;
                i++;

                //TC4
                ChanArray[i] = 3; //TC4 uses CJC3
                ChanTypeArray[i] = ChannelType.CJC;
                GainArray[i] = Range.NotUsed;
                i++;

                ChanArray[i] = 4;
                ChanTypeArray[i] = ChannelType.TC;
                GainArray[i] = Range.NotUsed;
                i++;

                //TC5
                ChanArray[i] = 4; //TC5 uses CJC 4
                ChanTypeArray[i] = ChannelType.CJC;
                GainArray[i] = Range.NotUsed;
                i++;

                ChanArray[i] = 5;
                ChanTypeArray[i] = ChannelType.TC;
                GainArray[i] = Range.NotUsed;
                i++;

                //TC6
                ChanArray[i] = 4; //TC6 also uses CJC4
                ChanTypeArray[i] = ChannelType.CJC;
                GainArray[i] = Range.NotUsed;
                i++;

                ChanArray[i] = 6;
                ChanTypeArray[i] = ChannelType.TC;
                GainArray[i] = Range.NotUsed;
                i++;


                //TC7
                ChanArray[i] = 5; //TC7 uses CJC5
                ChanTypeArray[i] = ChannelType.CJC;
                GainArray[i] = Range.NotUsed;
                i++;

                ChanArray[i] = 7;
                ChanTypeArray[i] = ChannelType.TC;
                GainArray[i] = Range.NotUsed;


                ScanOptions Options = ScanOptions.ConvertData
                                        | ScanOptions.Continuous
                                        | ScanOptions.Background;

                //allocate buffer
                int bufferSize = Constants.bufferSize;

                IntPtr buffer = MccService.WinBufAllocEx(Constants.bufferSize);

                Console.WriteLine("Actual Rate {0}\n", Constants.rate);

                WaitForKey();

                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();


                bool readLow = true;

                do
                {


                    System.Threading.Thread.Sleep(1);

                    IsError(Constants.daq.GetStatus(out daqStatus, out Count, out Index, FunctionType.DaqiFunction));

                    if ((Index > Constants.HALFBUFF) && readLow)
                    {
                        MccService.WinBufToArray(buffer, ADData, 0, Constants.HALFBUFF);

                        //the buffer contains 32 scans of the 16 channels. Because the TC are first in the list the TC conversion starts at 0 for the lower portion.
                        //Keep in mind that GetTCValues uses scans whereas WinBufToArray uses Scans * Channel Count
                        IsError(Constants.daq.GetTCValues(ChanArray, ChanTypeArray, Constants.ChanCount, buffer, 0, 16, TempScale.Celsius, tempVals));

                        readLow = false;

                        i = 0;
                        for (int idx = 0; idx < Constants.HALFBUFF; idx+=16)
                        {
                            Console.Write("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\r\n",
                                                 tempVals[i++].ToString("00.00"),
                                                 tempVals[i++].ToString("00.00"),
                                                 tempVals[i++].ToString("00.00"),
                                                 tempVals[i++].ToString("00.00"),
                                                 tempVals[i++].ToString("00.00"),
                                                 tempVals[i++].ToString("00.00"),
                                                 tempVals[i++].ToString("00.00"),
                                                 tempVals[i++].ToString("00.00"));

                            idx += 8;
                        }

                    }

                    else if ((Index < Constants.HALFBUFF) && !readLow)
                    {
                        MccService.WinBufToArray(buffer, ADData, Constants.HALFBUFF, Constants.HALFBUFF);

                        //the buffer contains 32 scans of the 16 channels. Because the TC are first in the list the TC conversion starts at 16 for the upper portion.
                        //Keep in mind that GetTCValues uses scans whereas WinBufToArray uses Scans * Channel Count
                        IsError(Constants.daq.GetTCValues(ChanArray, ChanTypeArray, Constants.ChanCount, buffer, 16, 16, TempScale.Celsius, tempVals));

                        readLow = true;

                        i = 0;
                        for (int idx = 0; idx < Constants.HALFBUFF; idx+=16)
                        {
                            Console.Write("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\r\n",
                                                 tempVals[i++].ToString("00.00"),
                                                 tempVals[i++].ToString("00.00"),
                                                 tempVals[i++].ToString("00.00"),
                                                 tempVals[i++].ToString("00.00"),
                                                 tempVals[i++].ToString("00.00"),
                                                 tempVals[i++].ToString("00.00"),
                                                 tempVals[i++].ToString("00.00"),
                                                 tempVals[i++].ToString("00.00"));


                        }
                    }

                } while (!Console.KeyAvailable);
                cki = Console.ReadKey();

                //stop background operation
                IsError(Constants.daq.StopBackground(FunctionType.DaqiFunction));
                Constants.daq.TimerOutStop(0);
                //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...\n");
            do
            {   //idle loop
                System.Threading.Thread.Sleep(10);
            } while (!Console.KeyAvailable);
            Console.ReadKey();//get rid of the key press
        }

        /*////////////////////////////////////////////////////////////////////////////////////*/

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


        /*////////////////////////////////////////////////////////////////////////////////////*/
        //function to convert to engineering units; if just volts set scale to 1.0 and offset to 0.0
        public static double ScaleData(Range rng, ushort dataval, double scale, double offset)
        {
            float V2 = 0.0f;
            Constants.daq.ToEngUnits(rng, dataval, out V2);
            return V2 * scale + offset;

        }

    }
}
 

 
 

Best regards,

John

 

Program.cs

Link to comment
Share on other sites

  • 0

Attached is a Python for Windows program to read the TC inputs using the daq_in_scan function.

Best regards,

John

"""
File:                       daq_in_scan_usb_1800.py

Library Call Demonstrated:  mcculw.ul.daq_in_scan()

Purpose:                    Synchronously scans 8 thermocouple channels

Demonstration:              how to covert raw data to temperature

Other Library Calls:        mcculw.ul.daq_in_scan()
                            mcculw.ul.get_tc_values()
                            mcculw.ul.win_buf_free()
                            mcculw.ul.release_daq_device()

Special Requirements:       This examples filters on the USB-1808 Series.
"""
from __future__ import absolute_import, division, print_function
from builtins import *  # @UnusedWildImport
from time import sleep
# 1616HS and 2500 series do not have ScaleData support
# from ctypes import cast, POINTER, c_double
from ctypes import cast, POINTER, c_ushort, c_float

from mcculw import ul
from mcculw.enums import ScanOptions, ChannelType, ULRange, TempScale, DigitalPortType
from mcculw.device_info import DaqDeviceInfo
from mcculw.ul import ULError
from mcculw.enums import FunctionType, Status


try:
    from console_examples_util import config_first_detected_device
except ImportError:
    from .console_examples_util import config_first_detected_device


def run_example():

    use_device_detection = False
    board_num = 0
    # Supported PIDs for the USB-1808 Series
    rate = 100
    points_per_channel = 64
    memhandle = None

    try:

        # use board zero from InstaCal
        daq_dev_info = DaqDeviceInfo(board_num)
        print('\nActive DAQ device: ', daq_dev_info.product_name, ' (',
              daq_dev_info.unique_id, ')\n', sep='')

        scan_options = ScanOptions.FOREGROUND

        # Create the daq_in_scan channel configuration lists
        chan_list = []
        chan_type_list = []
        gain_list = []

        # Analog channels must be first in the list
        chan_list.append(0)
        chan_type_list.append(ChannelType.CJC)
        gain_list.append(ULRange.BIP10VOLTS)

        chan_list.append(0)
        chan_type_list.append(ChannelType.TC)
        gain_list.append(ULRange.BIP10VOLTS)

        chan_list.append(1)
        chan_type_list.append(ChannelType.CJC)
        gain_list.append(ULRange.BIP10VOLTS)

        chan_list.append(1)
        chan_type_list.append(ChannelType.TC)
        gain_list.append(ULRange.BIP10VOLTS)

        chan_list.append(1)
        chan_type_list.append(ChannelType.CJC)
        gain_list.append(ULRange.BIP10VOLTS)

        chan_list.append(2)
        chan_type_list.append(ChannelType.TC)
        gain_list.append(ULRange.BIP10VOLTS)

        chan_list.append(2)
        chan_type_list.append(ChannelType.CJC)
        gain_list.append(ULRange.BIP10VOLTS)

        chan_list.append(3)
        chan_type_list.append(ChannelType.TC)
        gain_list.append(ULRange.BIP10VOLTS)

        chan_list.append(3)
        chan_type_list.append(ChannelType.CJC)
        gain_list.append(ULRange.BIP10VOLTS)

        chan_list.append(4)
        chan_type_list.append(ChannelType.TC)
        gain_list.append(ULRange.BIP10VOLTS)

        chan_list.append(4)
        chan_type_list.append(ChannelType.CJC)
        gain_list.append(ULRange.BIP10VOLTS)

        chan_list.append(5)
        chan_type_list.append(ChannelType.TC)
        gain_list.append(ULRange.BIP10VOLTS)

        chan_list.append(4)
        chan_type_list.append(ChannelType.CJC)
        gain_list.append(ULRange.BIP10VOLTS)

        chan_list.append(6)
        chan_type_list.append(ChannelType.TC)
        gain_list.append(ULRange.BIP10VOLTS)

        chan_list.append(5)
        chan_type_list.append(ChannelType.CJC)
        gain_list.append(ULRange.BIP10VOLTS)

        chan_list.append(7)
        chan_type_list.append(ChannelType.TC)
        gain_list.append(ULRange.BIP10VOLTS)
        num_chans = len(chan_list)

        total_count = num_chans * points_per_channel
        half_count = total_count / 2

        # Allocate memory for the scan and cast it to a ctypes array pointer
        memhandle = ul.scaled_win_buf_alloc(total_count)

        # 1616HS and 2500 series do not have ScaleData support
        # ctypes_array = cast(memhandle, POINTER(c_double))
        ctypes_array = cast(memhandle, POINTER(c_ushort))

        # Check if the buffer was successfully allocated
        if not memhandle:
            raise Exception('Error: Failed to allocate memory')

        scan_options = ScanOptions.CONTINUOUS | ScanOptions.BACKGROUND

        # Start the scan
        actRate, preCount, postCount = ul.daq_in_scan(
            board_num, chan_list, chan_type_list, gain_list, num_chans,
            rate, 0, total_count, memhandle, scan_options)

        status, curr_count, curr_index = ul.get_status(
            board_num, FunctionType.DAQIFUNCTION)

        # boolean flag used to toggle reading upper and lower buffer
        read_lower = True

        # acquire 640 samples
        acquire = points_per_channel * num_chans * 10
        while status != Status.IDLE:

            status, curr_count, curr_index = ul.get_status(
                board_num, FunctionType.DAQIFUNCTION)

            if (curr_index > half_count) and (read_lower == True):
                # use if you also have voltage or digital inputs
                ul.win_buf_to_array(memhandle, ctypes_array, 0, int(half_count))

                # Points per channel is 64 so there are 32 to convert which starts at the zero
                e, temps = ul.get_tc_values(
                    board_num, chan_list, chan_type_list,
                    num_chans, memhandle, 0, int(points_per_channel/2), TempScale.CELSIUS)

                for j in range(256):
                    if j % 8 == 0:
                        print()
                    print('{:2.2f}\t'.format(temps[j]), end ='')

                read_lower = False

            elif (curr_index < half_count) and (read_lower == False):
                # use if you also have voltage or digital inputs
                ul.win_buf_to_array(memhandle, ctypes_array, int(half_count), int(half_count))

                # Points per channel is 64 so there are 32 to convert which starts at the halfway point
                e, temps = ul.get_tc_values(
                    board_num, chan_list, chan_type_list,
                    num_chans, memhandle, int(points_per_channel/2), int(points_per_channel/2), TempScale.CELSIUS)

                for j in range(256):
                    if j % 8 == 0:
                        print()
                    print('{:2.2f}\t'.format(temps[j]), end='')

                read_lower = False

            if curr_count > acquire:
                print('\nAcquired number of scans = {:d}'.format(int(curr_count / num_chans)))
                break

        ul.stop_background(board_num, FunctionType.DAQIFUNCTION)
        print("\nscan completed successfully.")
    except ULError as e:
        print('\n', e)
    finally:
        if memhandle:
            # Free the buffer in a finally block to prevent a memory leak.
            ul.win_buf_free(memhandle)
        if use_device_detection:
            ul.release_daq_device(board_num)


if __name__ == '__main__':
    run_example()

daq_in_scan_tc_get_values.py

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...