//Example of using the Scanning DMM and configuring channels

// """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
//  © Agilent Technologies Inc. 2004, 2005, 2006
//  All rights reserved.
//
// You have a royalty-free right to use, modify, reproduce and distribute
// the Sample Application Files (and/or any modified version) in any way
// you find useful, provided that you agree that Agilent Technologies has no
// warranty, obligations or liability for any Sample Application Files.
//
// Agilent Technologies provides programming examples for illustration only,
// This sample program assumes that you are familiar with the programming
// language being demonstrated and the tools used to create and debug
// procedures. Agilent Technologies support engineers can help explain the
// functionality of Agilent Technologies software components and associated
// commands, but they will not modify these samples to provide added
// functionality or construct procedures to meet your specific needs.
// """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

// This program configures some Multiplexer channels for the Dmm to scan, initiates the
// scan, retrieves the data, and prints the results.

// NOTE: This include MUST be first, else will not compile cleanly
#include "stdafx.h"

#include "ag34980a.h"
// NOTE: The above include (ag34980A.h) needs some IVI shared component includes.  The path to these
// is often something like "C:\Program Files\IVI\Include".  You need to add this to your includes path at
// either the project level or the system level.  For project level, select Tools\Options, then click
// on "Projects" file tab, select "VC++ Directories".  This brings up a dialog box.  In the upper
// right of this dialog, there is a "Show Directories for" drop down -- select Include files. Then 
// input the include path desired in the window beneath.  You may also need to add an include path
// for Visa.h (which is often in C:\Program Files\Visa\winnt\include).
//
// NOTE: If the above include directory "C:\Program Files\IVI\Include" does not contain the IVI shared files
// (ivi.h, iviDmm.h, iviSwtch.h), then you must get them from the NI web site (www.ni.com).  Once there,
// select the "Support" tab in the upper portion of the screen, this will bring up a new window.  In the
// upper part of that window, do a "Search" for "IVI Compliance" by placing the string "IVI Compliance" in
// the text box just to the left of the "Go" button.  On the web page that comes up, scroll down
// and select the most recent version of "IVI Compliance Version....." for your operating system.  Downloading 
// this will place the appropriate .h files into the include directory mentioned above.

ViSession vi;  // needs to be global so can print errors out

void printErrs(ViStatus s)
{
	char errMssg[300];
	ViInt32 errCode = -1;
	ViStatus s2;

	s2 = ag34980a_GetError(vi, &errCode, (ViInt32)300, errMssg);
	printf("Got Visa error: %ld, %s\n", errCode, errMssg);
	if (errCode = -1074135039)  // instr has errors in its queue
	{
		// print out the instr specific errors
		while ((s2 >= 0) && (errCode != 0))
		{
			s2 = ag34980a_error_query(vi, &errCode, errMssg);
			if ( (s2 > -1) && (errCode != 0) )
				printf("Instr reported err: %ld, %s\n", errCode, errMssg);
		}
	}
}
   

#define	CHECK(func)	\
do {\
    ViStatus _s = (func);\
    if (_s < 0)\
    {\
	printf("Error calling function: %s\n", #func);\
	printErrs(_s);\
    }\
} while (0)

int main (int argc, char *argv[])
{
	ViSession vi;
	ViStatus status;
	ViInt32 lActualSize = 0;
	ViInt32 numberChannels;
	ViInt32 row; 
    char strData[600];
	char *nextSpace;
	char *searchBegin;
	char tempStr[80];
	
	//Open a session to the instrument and have the driver check the instrument for errors
	status = ag34980a_InitWithOptions("TCPIP0::156.140.92.11::INSTR", VI_FALSE, VI_TRUE,
                                        "QueryInstrStatus=true",&vi);
                                  
	// Configure Channel 1001   Temp. Thermist. 5k  °C
	CHECK(ag34980a_ConfigureThermistor(vi,"1001",
		AG34980A_VAL_RESOLUTION_DEFAULT,AG34980A_VAL_THERMISTOR5000));
    // Configure Channels 1004:1005  Volts DC    10 V    5 ½ digits
    CHECK(ag34980a_ConfigureDCVoltage(vi,"1004,1005",10.0,AG34980A_VAL_RESOLUTION_DEFAULT));
    // Channels 1006   Resistance  10 Mohm 5 ½ digits
    // Channels 1007   Resistance  10 Mohm 5 ½ digits
	CHECK(ag34980a_ConfigureResistance(vi,"1006,1007",10000000.0,AG34980A_VAL_RESOLUTION_DEFAULT));
    // Channel 1014   Resistance  100 ohm 5 ½ digits
    CHECK(ag34980a_ConfigureResistance(vi,"1014",100.0,AG34980A_VAL_RESOLUTION_DEFAULT));
    // Channels 1015   4w Resistance   100 ohm 4 ½ digits
    CHECK(ag34980a_ConfigureResistance(vi,"1015",100.0,AG34980A_VAL_RESOLUTION_LEAST));
	
	// Specify the scan list, 1 sweep per trigger, and have the scan order be ascending by channel number
    CHECK(ag34980a_ConfigureScan(vi, "1001,1002:1005,1006,1007,1014,1015", 1, VI_TRUE));
    
    // Configure the trigger source, set number of triggers 2
    // Set trigger source timer, and time between triggers as 2.2 seconds
	status = ag34980a_ConfigureTrigger(vi, AG34980A_VAL_TRIGGER_SOURCE_TIMER, 2, 2.2, 1);
    
    // Read the number of channels in scan list
    status = ag34980a_GetAttributeViInt32 (vi, "", AG34980A_ATTR_CHANNEL_SCAN_SIZE, &numberChannels);
    
    // Arm the trigger with initiate, this starts the measurement process
    status = ag34980a_Initiate(vi);
    
    // Wait up to 30 seconds for the scan to complete
    CHECK(ag34980a_WaitForOperationComplete (vi, 30000));
    
    //Enable channel number and units to be returned in data
    status  = ag34980a_ConfigureDataFormat(vi, VI_FALSE, // Disable alarm ,
                                         VI_TRUE, // Enable channel number
                                         VI_FALSE,// Disable time
                                         AG34980A_VAL_TIME_OFFSET_ABSOLUTE, // if time enabled, use absolute
                                         VI_TRUE // Enable Units
										 );

    //Retrieve the formatted data from the instrument
	status = ag34980a_Fetch(vi, 500, strData, &lActualSize);
    
    // Print the data to the text box and the Immediate window
	printf("Channel\t\tData\t\tUnits\n");
	printf("_________________________________\n");
	searchBegin = &strData[0];
    for(row = 0; row < numberChannels * 2; row++)
	{
		tempStr[0] = '\0';   // clear out the string
		nextSpace = strchr(searchBegin,' ');
		if (nextSpace)
		{
			//strncpy(chanStr,(nextSpace+5),4);

			strncat(tempStr,(nextSpace+5),4);  // the channel number field
			strcat(tempStr,"\t");
			strncat(tempStr,searchBegin,(nextSpace - searchBegin)); // the data
			strcat(tempStr,"\t\t");
			strncat(tempStr,(nextSpace+1),3);  // the units field
			printf("%s\n",tempStr);
			searchBegin = nextSpace + 10;
		}
	}
 
    // close session and exit
	status = ag34980a_close(vi);

	printf("Done...Press Enter key to exit\n");
	getchar();

	return 0;
	
}
