/****************************************************************************
      Copyright © 2005, 2006 Agilent Technologies Inc. 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 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 support engineers can help explain the
   functionality of Agilent 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 uses the Agilent 34980A IVI-COM driver.
// This program requires either NI Visa or
// Visa from Agilent I/O library version M or later to be installed
// on the computer.
//
// This program demonstrates how to receive digital data on the 34950A module
// and place it into memory (creating a Trace).  The data is received by this
// card and is assumed to be transmitted from some other device (not shown).
//

#include "stdafx.h"
#include <atlstr.h>
#include <atlsafe.h>
#include <comutil.h>   // used to convert SafeArray BSTR to String for printing

#import "C:/Program Files/IVI/Bin/Agilent34950A.dll"	no_namespace

int _tmain(int argc, _TCHAR* argv[])
{
	::CoInitialize(NULL);

	try
	{
		IAgilent34980A2Ptr host(__uuidof(Agilent34980A));
	
		// Setup IVI-defined initialization options
		CString strStandardInitOptions = 
			"Cache=false, InterchangeCheck=false, QueryInstrStatus=true, RangeCheck=false, RecordCoercions=false, Simulate=false";
			
		// Initialize instrument and clear status system/errors
		host->Initialize("TCPIP0::156.140.92.161::INSTR", VARIANT_FALSE, VARIANT_TRUE, LPCTSTR(strStandardInitOptions));	
		host->Status->Clear();

//		Configure Channel 1001   Temp. Thermist. 5k  °C
		IAgilent34950APtr digIO = (IAgilent34950APtr) host->Personality->Select( _bstr_t("Agilent34950A") );

//		Configure receiver for Input, width = byte, threshold 2.5
		digIO->Digital->Input->Configure(_bstr_t("1101"),Agilent34950AChannelWidthByte, 2.5);

//		Set up handshaking
		digIO->Digital->Handshake->Configure(_bstr_t("1101"),Agilent34950AHandshakeModeSynchronous,2.5,5.0);
		digIO->Digital->Handshake->SetPolarity(_bstr_t("1101"),Agilent34950AHandshakeLineIDH2,Agilent34950APolarityInverted);
		// NOTE: Polarity above was set to "Inverted" becase we were pacing the sender
		// with the same clock the receiver was using -- that way, the rising edge can 
		// cause an output on the sender, and the falling edge can start the "read";
		// the time between edges allows the data to become "stable" before the read. 
		// Unpredictable results occur if you attempt to use the same edge of a single clock
		// source to both pace the "send" and to trigger the "read".

//		set up receiver, rate is 500K, external source for the strobe
		digIO->Digital->Handshake->put_Rate(_bstr_t("1101"),500000);
		digIO->Digital->Handshake->put_SyncStrobe(_bstr_t("1101"),Agilent34950AHandshakeStrobeSourceExternal);
		digIO->Digital->Input->Memory->Clear(_bstr_t("1101"));
//		Set sample count to 3000 
		digIO->Digital->Input->Memory->put_SampleCount(_bstr_t("1101"),3000);

//		Set up the sender (not shown here)

//		Start the receiver first, then start the sender
		digIO->Digital->Input->Memory->Start(_bstr_t("1101"));

//		Start the sender, he will pace the transfer

//		After transfer complete, stop the receiver 
		digIO->Digital->Input->Memory->Stop(_bstr_t("1101"));

//		Now read what was written into memory
//		NOTE: You MUST Disable memory on the receiver before reading the contents
		digIO->Digital->Input->Memory->put_Enable(_bstr_t("1101"),false);

		// Set a longer timeout before data fetch
		host->System->TimeoutMilliseconds = 8000;

		// See how much data was sent
		long numPoints;
		digIO->Digital->Input->Memory->get_DataPoints(_bstr_t("1101"), &numPoints);

		if (numPoints > 0)
		{
			//Retrieve the data from the instrument
			SAFEARRAY* psaData = digIO->Digital->Input->Memory->ReadAllData(_bstr_t("1101")); 
			CComSafeArray<long> saData;
			saData.Attach(psaData);

			// View and manipulate data here if desired
			printf("First 3 data points in pattern: \n");
			for (int i=0; i<3; i++)
			{
				printf("Index %d: %ld \n", i, saData.GetAt(i));
			}

			// NOTE!!!!  destroy SAFEARRAY when done with it to avoid memory leak
			::SafeArrayDestroy(psaData);

		}

		printf("%ld data points were transmitted.\n", numPoints);

		host->Close();
	}
	catch (_com_error& e)
	{
		::MessageBox(NULL, e.Description(), e.ErrorMessage(), MB_ICONERROR);
	}

	::CoUninitialize();

	printf("Press Enter/Return to end program\n");
    getchar();

	return 0;
}