Esempio n. 1
0
HRESULT CbDevice::EnableSwClocking()
{    
    double maxRate, minRate;

    //
    // It is possible that the hardware will not have the same capabilities as our software clocking
    // In this case we must adjust our assumptions as to what the MIN and MAX sampling rates 
    // should be.
    //

    // Decide the true maximum sampling rate
    if(_maxSampleRate < MAX_SW_SAMPLERATE)
		maxRate = _maxSampleRate;
    else
		maxRate = MAX_SW_SAMPLERATE;

    // Decide the true minimum sampling rate
    if(_minSampleRate > MIN_SW_SAMPLERATE)
		minRate = _minSampleRate;
    else
		minRate = MIN_SW_SAMPLERATE;
    
    RETURN_HRESULT(pSampleRate.SetRange(minRate, maxRate));

	// Set the default rate to 1/5 the max rate
	double defaultRate = int(maxRate/5);
	pSampleRate.SetDefaultValue(defaultRate);

	// Range check the existing sample rate
    if (pSampleRate>maxRate)
	{
        pSampleRate=maxRate;
	}
    else if (pSampleRate<minRate)
	{
        pSampleRate=minRate;
	}

	// If this HW only supports SW Clocking then set the sample rate to the default
    if ( _ClockingType == SOFTWARE )
	{
		pSampleRate = defaultRate;
	}

    pSampleRate=RoundRate(pSampleRate);

    RETURN_HRESULT(_DaqHwInfo->put_MemberValue(L"minsamplerate", CComVariant(minRate)));	
    RETURN_HRESULT(_DaqHwInfo->put_MemberValue(L"maxsamplerate", CComVariant(maxRate)));	
    return S_OK;
}
Esempio n. 2
0
HRESULT CbDevice::SetClockSource()
{
    if (_UseSoftwareClock)
    {
        return EnableSwClocking();
    }
    else
    {
        RETURN_HRESULT(_DaqHwInfo->put_MemberValue(L"minsamplerate", CComVariant(_minSampleRate)));	
        RETURN_HRESULT(_DaqHwInfo->put_MemberValue(L"maxsamplerate", CComVariant(_maxSampleRate)));	
        pSampleRate.SetRange(_minSampleRate,_maxSampleRate);
        UpdateRateAndSkew();
    }
    return S_OK;
}
Esempio n. 3
0
HRESULT CbDevice::Open(IUnknown *Interface)
{
    RETURN_HRESULT(CmwDevice::Open(Interface));
    ATTACH_PROP(SampleRate);
    return S_OK;
    //EnableSwClocking();
}
Esempio n. 4
0
////////////////////////////////////////
// SetProperty()
//
// Called when a property is changed from the MATLAB environment.
// It gives us a chance to update other properties, do error checking, etc.
// /////////////////////////////////////
STDMETHODIMP CetfarduinoAin::SetProperty(long User, VARIANT* NewValue) {
	if (User) {
		CLocalProp* pProp = PROP_FROMUSER(User);
		variant_t* val = (variant_t*) NewValue;
		// SampleRate property
		if (User == USER_VAL(pSampleRate)) {
			double newSampleRate = *val;
			if (pClockSource == CLOCKSOURCE_SOFTWARE) {
				return CswClockedDevice::SetProperty(User, NewValue);
			}
			// Calculate a sample rate which is compatible with the board
			CalculateSampleRate(newSampleRate);
			*val = pSampleRate;
		}
		// ClockSource property
		if (User == USER_VAL(pClockSource)) {
			if ((long)(*val) == CLOCKSOURCE_SOFTWARE) {
				// Software clocking chosen
				// First, change the SampleRate to SW clocked defaults
				double softwareClockedDefault = 100;		// Let's avoid magic values
				pSampleRate.SetDefaultValue(CComVariant(softwareClockedDefault));
				pSampleRate = softwareClockedDefault;
				pSampleRate.SetRange(
					CComVariant((double)MIN_SW_SAMPLERATE),
					CComVariant((double)MAX_SW_SAMPLERATE));
				EnableSwClocking();
				// SamplesPerTrigger needs to be configured so that 1s of input data is acquired
				pSamplesPerTrigger->put_DefaultValue(CComVariant(softwareClockedDefault));
				pSamplesPerTrigger = softwareClockedDefault;
			} else {
				// Internal (HW) clocking chosen
				// First, change the SampleRate to SW clocked defaults
				double internalClockDefault = 1000;
				pSampleRate.SetDefaultValue(CComVariant(internalClockDefault));
				pSampleRate = internalClockDefault;
				pSampleRate.SetRange(m_minBoardSampleRate, m_maxBoardSampleRate);
				// Za SwClocking ovaj dio uradi CswClockedDevice::EnableSwClocking
				RETURN_HRESULT(_DaqHwInfo->put_MemberValue(L"minsamplerate", CComVariant(m_minBoardSampleRate)));	
				RETURN_HRESULT(_DaqHwInfo->put_MemberValue(L"maxsamplerate", CComVariant(m_maxBoardSampleRate)));
				// SamplesPerTrigger needs to be configured so that 1s of input data is acquired
				pSamplesPerTrigger->put_DefaultValue(CComVariant(internalClockDefault));
				pSamplesPerTrigger = internalClockDefault;
			}
		}
	}
	return S_OK;
}
Esempio n. 5
0
HRESULT CetfarduinoAin::SetDaqHwInfo() {
	// ----------------------------------
	// Set allowed InputRanges
	// ----------------------------------
	// The SAFEARRAYBOUND is used to create a multi dimensional array    
	SAFEARRAYBOUND rgsabound[2];  //the number of dimensions
    rgsabound[0].lLbound = 0;
	rgsabound[0].cElements = _validInputRanges.size(); // bipolar and unipolar - size of dimension 1
    rgsabound[1].lLbound = 0;
    rgsabound[1].cElements = 2;     // upper and lower range values - size of dimension 2
	
    SAFEARRAY* ps = SafeArrayCreate(VT_R8, 2, rgsabound); //use the SafeArrayBound to create the array
    if (ps == NULL) 
		throw "Failure to create SafeArray.";
	
	CComVariant vinrange;
    vinrange.parray = ps;
    vinrange.vt = VT_ARRAY | VT_R8;
    double *inRange, *min, *max;
    HRESULT hr = SafeArrayAccessData(ps, (void**)&inRange);
    if (FAILED(hr)) 
    {
        SafeArrayDestroy(ps);
        throw "Failure to access SafeArray data.";
    }       
	min = inRange;
	max = inRange + _validInputRanges.size();
	
	// Iterate through the validRanges, and transfer the Input Ranges.
	for (RangeList::iterator it = _validInputRanges.begin(); it != _validInputRanges.end(); ++it) {
		*min++ = it->minVal;
		*max++ = it->maxVal;
	}
    SafeArrayUnaccessData(ps);
    RETURN_HRESULT(_DaqHwInfo->put_MemberValue(CComBSTR(L"inputranges"), vinrange));

	// Polarity
	// Za sad je predvidjeno samo Unipolarni polaritet...
	RETURN_HRESULT(_DaqHwInfo->put_MemberValue(CComBSTR(L"polarity"), CComVariant(L"Unipolar")));

	// Description
	char driverDescrip[] = "Etf Arduino Driver: Analog Input";
	RETURN_HRESULT(_DaqHwInfo->put_MemberValue(CComBSTR(L"vendordriverdescription"), CComVariant(driverDescrip)));

	return S_OK;
}
Esempio n. 6
0
////////////////////////////////////////////////////////////////////////////////////
// Open()
//  This routine is called when MatLab executes the 'digitalio' instruction. 
//  Several things should be validated at this point. 
////////////////////////////////////////////////////////////////////////////////////
HRESULT CadvantechDio::Open(IUnknown *Interface,long ID)
{
	if (ID<0) 
	{
		return E_INVALID_DEVICE_ID;
	}
	
	RETURN_HRESULT(CmwDevice::Open(Interface));
    
	m_deviceID = static_cast<WORD>(ID);	// Set the Device Number to the requested device number set in Matlab.
	
	short numDevices;
	DEVLIST	deviceList[MaxDev];	// Structure containing list of installed boards (MaxDev is defined in driver.h)
	RETURN_ADVANTECH(DRV_DeviceGetList((DEVLIST far *)&deviceList[0], MaxDev, &numDevices));
	
	DWORD index = -1;
	for (int i=0; i < numDevices; i++)	// Find the deviceID which corresponds to the desired board.
	{
		if (deviceList[i].dwDeviceNum == m_deviceID)
		{
			index = i;
		}
	}
	if (index == -1)
	{
		return E_INVALID_DEVICE_ID;
	}
	strcpy(m_deviceName, deviceList[index].szDeviceName);

	// Open device and check that device number is valid
	RETURN_ADVANTECH(DRV_DeviceOpen(m_deviceID,(LONG far *)&m_driverHandle));
	PT_DeviceGetFeatures ptDevFeatures;
	ptDevFeatures.buffer = (LPDEVFEATURES)&m_devFeatures;
	ptDevFeatures.size = sizeof(DEVFEATURES);
	RETURN_ADVANTECH(DRV_DeviceGetFeatures(m_driverHandle, (LPT_DeviceGetFeatures)&ptDevFeatures));
	
	RETURN_HRESULT(LoadINIInfo());
	RETURN_HRESULT(SetDaqHwInfo());

	return S_OK;
} // end of Open()
Esempio n. 7
0
HRESULT CLabInput::Open(IDaqEngine *engine,int id,DevCaps* DeviceCaps)
{
    RETURN_HRESULT(Cnia2d::Open(engine, id,DeviceCaps));
    if (GetDevCaps()->Is700())
    {
        _chanSkewMode->ClearEnumValues();
        _chanSkewMode->AddMappedEnumValue(EQUISAMPLE, L"Equisample");
        _chanSkewMode=EQUISAMPLE;
        _chanSkewMode->put_DefaultValue(CComVariant(EQUISAMPLE));
        UpdateTimeing(FORSET);
    }

    return S_OK;
}
Esempio n. 8
0
HRESULT CbDevice::UpdateChans(bool ForStart)
{
    _chanList.resize(_nChannels);
    _chanRange.resize(_nChannels);
     AICHANNEL *aichan=NULL;
    if (_updateChildren && ForStart)
    {
#ifdef _DEBUG
        long chancheck=0;
        _EngineChannelList->GetNumberOfChannels(&chancheck);
        _ASSERTE(chancheck==_nChannels);
#endif
        for (int i=0; i<_nChannels; i++) 
        {    
            _EngineChannelList->GetChannelStructLocal(i, (NESTABLEPROP**)&aichan);
            _ASSERTE(aichan);
            _chanList[i]=static_cast<short>(aichan->Nestable.HwChan);
            RANGE_INFO *NewInfo;
            RETURN_HRESULT(FindRange(static_cast<float>(aichan->VoltRange[0]),
				                     static_cast<float>(aichan->VoltRange[1]),NewInfo));
            _chanRange[i]=NewInfo->rangeInt;
            if (aichan->Nestable.Type==NPAOCHANNEL)
            {
                RETURN_HRESULT(UpdateDefaultChannelValue(i,((AOCHANNEL*)aichan)->DefaultValue));
            }
            
        }
        
        _updateChildren=false;
    }
    else
    {
        // we still need working chanlist and rangelist if no gainlist
    }
    return S_OK;
}
Esempio n. 9
0
////////////////////////////////////////////////////////////////////////////////
// SetChannelProperty()
//
// Called by the engine when a channel property is set
// An interface to the property, the new value and as a link to the channel are passed 
// to the method
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CetfarduinoAin::SetChannelProperty(long UserVal, tagNESTABLEPROP* pChan, VARIANT* NewValue)
{
    int Index = pChan->Index-1;  // we use 0 based index
	variant_t& vtNewValue = reinterpret_cast<variant_t&>(*NewValue);
	
	// Input Range property
	if(UserVal == USER_INPUTRANGE) {
		TSafeArrayAccess<double> NewRange(NewValue);
		Range* range = 0;
		RETURN_HRESULT(FindRange(NewRange[0], NewRange[1], range));
		NewRange[0] = range->minVal;
		NewRange[1] = range->maxVal;
		_updateChildren = true;
	}
	_updateChildren = true;
    return S_OK;
}
Esempio n. 10
0
/////////////////////////////////////////////////////////////////////////////
// AdaptorInfo()
//
// The function is used to elicit relevant info about the current HW..
//..configuration from the HW API.
//  The info to extract is:
//..1)number of boards installed
//..2)board names
//..3)supported subsystems (AnalogInput, AnalogOutput, DigitalIO)
// The function is called by the engine in response to the ML user..
//..command DAQHWINFO 
/////////////////////////////////////////////////////////////////////////////
HRESULT Cadvantechadapt::AdaptorInfo(IPropContainer * Container)
{
	LONG lDriverHandle = (LONG)NULL;          // driver handle
	PT_DeviceGetFeatures ptDevFeatures;		// Devfeatures table
	DEVFEATURES DevFeatures;					// structure for device features
	
	int i = 0;          // Index variable
	
	// Get the name of the adaptor module
	TCHAR name[256];
	GetModuleFileName(_Module.GetModuleInstance(),name,256); // null returns MATLAB version (non existant)
	RETURN_HRESULT(Container->put_MemberValue(L"adaptordllname",CComVariant(name)));
	
	// Place the adaptor name in the appropriate struct in the engine.
	RETURN_HRESULT(Container->put_MemberValue(L"adaptorname",variant_t(ConstructorName)));
	
	// Find board IDs
	// Start by obtaining the DeviceList. Not stored.
	short numDevices;			// Number of devices
	DEVLIST deviceList[MaxDev]; // Space to store device information.
	CComVariant var;			// General CComVariant to return info to adaptor engine.
	RETURN_ADVANTECH(DRV_DeviceGetList((DEVLIST far *)&deviceList[0], MaxDev, &numDevices));
	
	// Create storage for board IDs, bord names and constructors.
	TSafeArrayVector<CComBSTR> IDs;			// Create A SafeArrayVector to store the IDs in
	IDs.Allocate(numDevices);				// Allocate the memory for the number of devices
	TSafeArrayVector<CComBSTR> Names;		// Create A SafeArrayVector to store the Names in
	Names.Allocate(numDevices);				// Allocate the memory for the number of devices
	SAFEARRAY *ps;							// SafeArray for the subsystem support [nDx3 CComBStrs]
	CComBSTR *subsystems;
	SAFEARRAYBOUND arrayBounds[2]; 
	arrayBounds[0].lLbound = 0;
	arrayBounds[0].cElements = numDevices;    
	arrayBounds[1].lLbound = 0;
	arrayBounds[1].cElements = 3;			// AnalogInput, AnalogOutput, DigitalIO subsystems.
	ps = SafeArrayCreate(VT_BSTR, 2, arrayBounds);
	if (ps==NULL)
		return E_FAIL;      
	
	// Set up the variant to contain subsystem constructor SafeArray
	var.parray = ps;
	var.vt = VT_ARRAY | VT_BSTR;
	HRESULT hRes = SafeArrayAccessData(ps, (void **)&subsystems);
	if (FAILED (hRes)) 
	{
		SafeArrayDestroy (ps);
		return hRes;
	}
	
	// Now loop through each device, getting the ID, BoardName and subsystem support.
	wchar_t str[40];
	for (i=0; i < numDevices; i++)
	{
		// Allocate the ID
		char* string;
		string = new char[20];
		_ltoa(deviceList[i].dwDeviceNum, string, 10);
		IDs[i] = CComBSTR(string);
		
		// Open Device
		RETURN_ADVANTECH(DRV_DeviceOpen(deviceList[i].dwDeviceNum,(LONG far *)&lDriverHandle));
		
		// Get BoardNames info
		Names[i] = CComBSTR(deviceList[i].szDeviceName);
		
		// Check to see which subsystems the current board supports.
		// Get device features
		ptDevFeatures.buffer = (LPDEVFEATURES)&DevFeatures;
		ptDevFeatures.size = sizeof(DEVFEATURES);
		RETURN_ADVANTECH(DRV_DeviceGetFeatures(lDriverHandle, (LPT_DeviceGetFeatures)&ptDevFeatures));
		if ((DevFeatures.usMaxAIDiffChl + DevFeatures.usMaxAISiglChl) > 0) 
		{
			swprintf(str, L"analoginput('%s',%s)", (wchar_t*)ConstructorName, (wchar_t*)IDs[i]);
			subsystems[i]=str;
		}
		if (DevFeatures.usMaxAOChl > 0)
		{
			swprintf(str, L"analogoutput('%s',%s)", (wchar_t*)ConstructorName, (wchar_t*)IDs[i]);
			subsystems[i + numDevices]=str;
		}
		if ((DevFeatures.usMaxDIChl + DevFeatures.usMaxDOChl) > 0)
		{
			swprintf(str, L"digitalio('%s',%s)",(wchar_t*) ConstructorName, (wchar_t*)IDs[i]);
			subsystems[i + 2*numDevices] = str;
		}  
		// Close device
		RETURN_ADVANTECH(DRV_DeviceClose((LONG far *)&lDriverHandle));
	}
	
	// Return Object Constructor Names since they're in var already.
	SafeArrayUnaccessData (ps);    
	RETURN_HRESULT(Container->put_MemberValue(L"objectconstructorname",var));
	
	// Return the board names
	var.Clear();			// resuse the same 'var' variable for the boardnames.
	Names.Detach(&var);
	RETURN_HRESULT(Container->put_MemberValue(L"boardnames",var));
	
	// Return the board numbers
	var.Clear();			//reuse the same 'var' variable for the IDs[]
	IDs.Detach(&var);
	RETURN_HRESULT(Container->put_MemberValue(L"installedboardids",var));   
	
	return S_OK;
} // end of AdaptorInfo()
Esempio n. 11
0
STDMETHODIMP SoundDA::SetProperty(long User, VARIANT *NewValue)  // return false for fail
{
    if (User)
    {
        variant_t *var = (variant_t*)NewValue;        
        
        // 
	// special case: if bitsPerSample is being changed, we
	// need to update the daqHwInfo to reflect this
	//
	if (User==(long)&_bitsPerSample)
	{      
           
       	    // set the daqHwInfo value which depends on the BitsPerSample property
            double offset;
	    // set the data type to match the bits, default is Int16
                long datatype;
                long bits=(long)*var;
		switch (bits)
                {
                case 8:
                    datatype=VT_UI1;
                    offset=128;
	        break;
                case 16:
                    datatype=VT_I2;
                    offset=0;
                    break;
                case 24:
                    datatype=VT_I4;
                    offset=0;
                    break;
                case 32:
                    datatype=VT_I4;
                    offset=0;
		    break;
                default:
                    if (bits<16 || bits > 32)
		        return E_INV_BPS;
                    _engine->WarningMessage(L"The bits value that has been set has no standard implementation"
                        L" by sound cards.  Acquisition may be unreliable.  To remove this warning rebuild the winsound adaptor");
                    datatype=VT_I4;
                    offset=0;
	        }
                WaveFormat.SetBits(static_cast<WORD>(bits));
                HRESULT hRes = GetHwInfo()->put_MemberValue(L"nativedatatype",CComVariant(datatype));
                if (!(SUCCEEDED(hRes))) return hRes;
                hRes = GetHwInfo()->put_MemberValue(L"bits",*NewValue);
                if (!(SUCCEEDED(hRes))) return hRes;
                
            // now set the offset value that the engin uses to calculate naiveoffset
            for (int i=0;i<_nChannels;i++)
            {
                AOCHANNEL *chan;
                _EngineChannelList->GetChannelStructLocal(i,(NESTABLEPROP**)&chan);
                chan->ConversionOffset=offset;
            }

            // set the default offset
            CComPtr<IPropRoot> iProp;
            GetChannelProperty(L"conversionoffset",&iProp);
            iProp->put_DefaultValue(CComVariant(offset));
        

        }
	else if (User==(long)&_standardSampleRates)
	{
            // Get a pointer to the IProp interface for theSampleRate property.
            if ((bool)(*var) == true){
	        // Need to snap current SampleRate to one of the standard samplerates.
                // A one percent tolerance is given.  
                // Ex. 8080 snaps to 8000 not 11025.
                _cSamplesPerSec=SnapSampleRates(_cSamplesPerSec);
                WaveFormat.SetRate(_cSamplesPerSec);
                RETURN_HRESULT(SetSampleRateRange(8000,static_cast<long>(WaveCaps.GetMaxSampleRate())));
            }else{
                // SampleRate can be set to a maximum of 96000Hz.
                RETURN_HRESULT(SetSampleRateRange(5000,96000));
            }
	}
	else if (User==(long)&_cSamplesPerSec)
	{
	    // SampleRate has been chosen.  Depending on standardSampleRates value
	    // may need to snap to specified SampleRate to 8000, 11025, 22050, 44100, 
            //  A one percent tolerance is given.

	    // Get a pointer to the IProp interface for the StandardSampleRates 
	    // property.
	    IProp* iProp;
            HRESULT hRes = GetProperty(L"StandardSampleRates", &iProp);
            if (FAILED(hRes)) return hRes;	   
   
	    // Get the value of the StandardSampleRates property.
            variant_t standardSR;
            iProp->get_Value(&standardSR);

            switch ((bool)standardSR)
            {
            case false:
                {	// StandardSampleRates is off.  Don't need to snap but do need to 
                    // round up to the next integer value.
                    
                    // Get the fraction portion of the SampleRate (8050.50)
                    double n;
                    double fraction=modf(*var, &n);
                    
                    // If not a fraction round up.
                    if (fraction!=0.0){
                        *var=(long)++n;
                    }
                    break;
                }
            case true:
                {	// StandardSampleRates is on.  Need to snap the specified SampleRate to
                    // either 8000, 11025, 22050, 44100
                    *var = SnapSampleRates(*var);
                    break;
                } 
            } // close switch
            
            iProp->Release();
	} //close else

       	// set the local value
	((CLocalProp*)User)->SetLocal(*var);

    }
    return S_OK;
}
Esempio n. 12
0
/////////////////////////////////////////////////////////////////////////////
// Open()
//
// Function is called by the OpenDevice(), which is in turn called by the engine.
// CetfarduinoAin::Open() function's main goals are ..
// 1)to initialize the hardware and hardware dependent properties..
// 2)to expose pointers to the engine and the adaptor to each other..
// 3)to process the device ID, which is input by a user in the MATLAB command line.
// The call to this function goes through the hierarchical chain: ..
//..CetfarduinoAin::Open() -> CswClockedDevice::Open() -> CmwDevice::Open()
// CmwDevice::Open() in its turn populates the pointer to the..
//..engine (CmwDevice::_engine), which allows to access all engine interfaces.
// Function MUST BE MODIFIED by the adaptor programmer.
//////////////////////////////////////////////////////////////////////////////
HRESULT CetfarduinoAin::Open(IUnknown* Interface, long ID)
{
	if (ID < 0) {
		// Undocumented MATLAB Daq Engine bug!
		// When Open() returns an error, the reference to the analoginput object is leaked
		// and never freed! Thereby, all resources this object owns are also leaked since
		// the destructor is never called.
		// :TODO: Implement a way to free all resources without the dtor (cannot use RAII for
		// this object)
		return CComCoClass<ImwDevice>::Error(CComBSTR("etfarduino: Invalid device ID."));
	}
	RETURN_HRESULT(TBaseObj::Open(Interface));
	DeviceId = ID;
	TCHAR portName[10];
	bool registered = 
		service.CheckDeviceRegistered(DeviceId, portName);
	if (!registered) {
		char tempMessage[255];
		sprintf(tempMessage, "etfarduino: Device %d not found.", DeviceId);
		return CComCoClass<ImwDevice>::Error(CComBSTR(tempMessage));
	}
    wchar_t idStr[8];
    swprintf(idStr, L"%d", ID);
	RETURN_HRESULT(_DaqHwInfo->put_MemberValue(CComBSTR(L"id"), CComVariant(idStr)));		
	// Fixed device config values. They could be moved to a config file.
	m_minBoardSampleRate = 4;
	m_maxBoardSampleRate = 12500;				// 80us period
	_engine->GetBufferingConfig(&m_engineBufferSamples, NULL);
	// ------------
	// SetDaqHwInfo
	// ------------
	wchar_t deviceName[30];
	swprintf(deviceName, _T("etfarduino (Device %d)"), DeviceId);
    RETURN_HRESULT(InitHwInfo(
		VT_UI2,
		Bits,
		MAX_CHANNELS,	// maximum number of channels
		SE_INPUT,		// Setting Single Ended input channels
		Cetfarduinoadapt::ConstructorName,
		deviceName));
	RETURN_HRESULT(SetDaqHwInfo());

	//////////////////////////////// Properties ///////////////////////////////////
	// The following Section sets the Propinfo for the Analog input device      //
	///////////////////////////////////////////////////////////////////////////////
	// Attach to the ClockSource property
    ATTACH_PROP(ClockSource);
	// The etfarduino must work as both software and internally clocked
    EnableSwClocking();
    pClockSource->AddMappedEnumValue(CLOCKSOURCE_SOFTWARE, TEXT("Software"));
	pClockSource->AddMappedEnumValue(CLOCKSOURCE_INTERNAL, TEXT("Internal"));
	pClockSource->put_DefaultValue(CComVariant(CLOCKSOURCE_INTERNAL));
	pClockSource = CLOCKSOURCE_INTERNAL;

	// SampleRate property
	double defaultSampleRate = 1000;
	ATTACH_PROP(SampleRate);
	pSampleRate.SetDefaultValue(CComVariant(defaultSampleRate));
	pSampleRate = defaultSampleRate;
	pSampleRate.SetRange(m_minBoardSampleRate, m_maxBoardSampleRate);
	RETURN_HRESULT(_DaqHwInfo->put_MemberValue(TEXT("minsamplerate"), CComVariant(m_minBoardSampleRate)));	
	RETURN_HRESULT(_DaqHwInfo->put_MemberValue(TEXT("maxsamplerate"), CComVariant(m_maxBoardSampleRate)));	

	// SamplesPerTrigger property
	// Needs to be set so that 1s of data is acquired with the default sample rate
	ATTACH_PROP(SamplesPerTrigger);
	pSamplesPerTrigger->put_DefaultValue(CComVariant(defaultSampleRate));
	pSamplesPerTrigger = defaultSampleRate;

	// TriggerRepeat property
	// How many times will the trigger be repeated
	ATTACH_PROP(TriggerRepeat);

	// ----------------------------
	// Postaviti InputRange default
	// ----------------------------
	CRemoteProp remoteProp;
	CComVariant var;
	// Hardcoded input range of [0, 5] [V]
	double InputRange[2] = {0., 5.};
	CreateSafeVector(InputRange, 2, &var);
	remoteProp.Attach(_EngineChannelList, TEXT("inputrange"));
	remoteProp->put_DefaultValue(var);
	remoteProp->put_User(USER_INPUTRANGE);
	remoteProp.SetRange(InputRange[0], InputRange[1]);
	remoteProp.Release();

    TRemoteProp<long>  pInputType;
    pInputType.Attach(_EnginePropRoot, L"InputType");
    pInputType->AddMappedEnumValue(0, L"SingleEnded");

	// TODO: May need to add the ChannelSkewMode enumerated property...

    return S_OK;
} // end of Open()
Esempio n. 13
0
////////////////////////////////////////////////////////////////////////////////////
// SetDaqHWInfo()
// Set the fields needed for DaqHwInfo. 
//  It is used when you call daqhwinfo(analoginput('advantech'))
////////////////////////////////////////////////////////////////////////////////////
HRESULT CadvantechDio::SetDaqHwInfo()
{	
	// Adaptor Name
	RETURN_HRESULT(_DaqHwInfo->put_MemberValue(CComBSTR(L"adaptorname"), CComVariant(Cadvantechadapt::ConstructorName)));
	
	// Device Name
	char tempstr[15] = "";
	sprintf(tempstr, " (Device %d)", m_deviceID); 
	strcat(m_deviceName, tempstr);					
	RETURN_HRESULT(_DaqHwInfo->put_MemberValue(CComBSTR(L"devicename"), CComVariant(m_deviceName)));
	
	// Device ID
	wchar_t idStr2[10];
	swprintf(idStr2, L"%d", m_deviceID );	// Convert the Device id to a string
	RETURN_HRESULT(_DaqHwInfo->put_MemberValue(CComBSTR(L"id"), CComVariant(idStr2)));
	
	// Vendor Driver Description
	char vendorDriverDescription[30]; // The place to store the driver description
	// This call gets the value which corresponds to the description, and converts it to a string
	strcpy(vendorDriverDescription, m_devFeatures.szDriverName);
	RETURN_HRESULT(_DaqHwInfo->put_MemberValue(CComBSTR(L"vendordriverdescription"),CComVariant(vendorDriverDescription)));
	
	// Vendor Driver Version
	char vendorDriverVersion[30]; // The place to store the driver description
	// This call gets the value which corresponds to the description, and converts it to a string
	strcpy(vendorDriverVersion, m_devFeatures.szDriverVer);
	RETURN_HRESULT(_DaqHwInfo->put_MemberValue(CComBSTR(L"vendordriverversion"),CComVariant(vendorDriverVersion)));

	// Sort out the daqhwinfo for the ports
	// This calculates the total number of lines that we have available. We do this first so we know how many
	// different ports we have in total.
	// NOTE: Advantech hardware has either all configurable lines, or no configurable lines!
	if (m_configLines > 0)	
	{
		RETURN_HRESULT(_DaqHwInfo->put_MemberValue(CComBSTR(L"totallines"), CComVariant(m_configLines)));
	}
	else
	{
		RETURN_HRESULT(_DaqHwInfo->put_MemberValue(CComBSTR(L"totallines"), CComVariant((m_inputLines + m_outputLines))));
	}

	// Set the rest of the port info
	CComVariant var;
	
	// Here we create the SafeArray we are going to use to set all port values.        
	SAFEARRAY *ps = SafeArrayCreateVector(VT_I4, 0, m_ports );
	if (ps==NULL) 
	{
		return E_FAIL;
	}
	// set the data type and values
	V_VT(&var)=VT_ARRAY | VT_I4;
	V_ARRAY(&var)=ps;
	TSafeArrayAccess <long> ar(&var);  // used to access the array
	
	// These hold the number of ports supported by the device...
	m_numInPorts = 0;	
	int numOutPorts = 0;
	int numConfPorts = 0;
	
	// NOTE: The line IDs are returned as 0 -> 7 for port1 and 0 -> 7 for port2. For the 1710 and 818
	//		 port2 corresponds to the hi byte ie. lines 8 -> 15.
	// PortMasks defined in advantechUtil.h
	int position = 0;
	if ((m_inputLines + m_outputLines)/m_ports == 8 || m_configLines/m_ports == 8) // If ports are 8 lines wide...
	{
		m_numInPorts = m_inputLines/8;  
		numOutPorts = m_outputLines/8;
		numConfPorts = m_configLines/8;	

		// Set up PortLineMasks here
		int numPorts = max((m_numInPorts + numOutPorts) ,m_configLines/8);
		//for (int i=0; i < (m_numInPorts + numOutPorts); i++)
		for (int i=0; i < (numPorts); i++)
		{ 
			ar[position] = portMask8; 
			position++;
		}
	}
	else if ((m_inputLines + m_outputLines)/m_ports == 16)	// This for PCL730, has ports 16 lines wide
	{
		m_numInPorts = m_inputLines/16;  
		numOutPorts = m_outputLines/16;

		// Set up PortLineMasks here
		for (int i=0; i < (m_numInPorts + numOutPorts); i++) 
		{ 
			ar[position] = portMask16; 
			position++;
		}
	}
	else if (m_inputLines/m_ports == 5) // This for PCL833, has one port of 5 lines
	{
		m_numInPorts = 1;
		// Set up PortLineMasks here
		ar[0] = portMask5;
	}
	else // Else its a PCL735, has one port of 8 lines and another of 4 lines
	{
		numOutPorts = 2;
		// Set up PortLineMasks here
		ar[0] = portMask8;
		ar[1] = portMask4;
	}
	RETURN_HRESULT(_DaqHwInfo->put_MemberValue(CComBSTR(L"portlinemasks"),var) );

	// Port Directions
	// NOTE: Advantech names their ports as follows:
	//
	//			Input Ports: 0 1 2 3...
	//			Output Ports: 0 1 2 3...
	//
	//		 Here we give the Port IDs as follows (to conform to Mathworks):
	//
	//			Input Ports: 0 1
	//			Output Ports: 2 3
	//				or
	//			Configurable Ports: 0 1 2 3 4...
	position = 0;
	for (int i = 0; i < m_numInPorts; i++) // First check the input ports.
	{
		ar[position] = 0;
		position++;		
	}
	for (i = 0; i < numOutPorts; i++)
	{
		ar[position] = 1;
		position++;
	}
	for (i = 0; i < numConfPorts; i++)
	{
		ar[position] = 2;
		position++;
	}
	RETURN_HRESULT(_DaqHwInfo->put_MemberValue(CComBSTR(L"portdirections"),var));	
	
	// Port IDs
	for (i = 0; i < m_ports; i++)
		ar[i] = i;
	RETURN_HRESULT(_DaqHwInfo->put_MemberValue(CComBSTR(L"portids"),var));	
	
	// PortLineConfig 0:port 1: line
	// All will be 0 as advantech only supports port configurations...
	for (i = 0; i < m_ports; i++)
		ar[i] = 0;
	RETURN_HRESULT(_DaqHwInfo->put_MemberValue(CComBSTR(L"portlineconfig"),var));

	// If the device has configurable ports then we must set the port direction
	// to "in" for all the ports as this is the default the engine expects.
	if (numConfPorts > 0)
	{
		for (i = 0; i < m_ports; i++)
		{
			SetPortDirection(i, 0);
		}
	}
	
	return S_OK;
} // end of SetDaqHwInfo()