/******************************************************************************* Copyright (c) 1983-2016 Advantech Co., Ltd. ******************************************************************************** THIS IS AN UNPUBLISHED WORK CONTAINING CONFIDENTIAL AND PROPRIETARY INFORMATION WHICH IS THE PROPERTY OF ADVANTECH CORP., ANY DISCLOSURE, USE, OR REPRODUCTION, WITHOUT WRITTEN AUTHORIZATION FROM ADVANTECH CORP., IS STRICTLY PROHIBITED. ================================================================================ REVISION HISTORY -------------------------------------------------------------------------------- $Log: $ -------------------------------------------------------------------------------- $NoKeywords: $ */ /****************************************************************************** * * Windows Example: * StaticAO.cpp * * Example Category: * AO * * Description: * This example demonstrates how to use Static AO voltage function. * * Instructions for Running: * 1 Set the 'deviceDescription' for opening the device. * 2 Set the 'profilePath' to save the profile path of being initialized device. * 3 Set the 'channelStart' as the first channel for analog data output. * 4 Set the 'channelCount' to decide how many sequential channels to output analog data. * * I/O Connections Overview: * Please refer to your hardware reference manual. * ******************************************************************************/ #include #include #include #include #include "../inc/compatibility.h" #include "../inc/bdaqctrl.h" using namespace std; using namespace Automation::BDaq; //----------------------------------------------------------------------------------- // Configure the following parameters before running the demo //----------------------------------------------------------------------------------- #define ONE_WAVE_POINT_COUNT 512 //define how many data to makeup a waveform period. #define deviceDescription L"PCI-1724,BID#0" // 设备描述 const wchar_t* profilePath = L"../../profile/PCI-1724.xml"; // 配置文件路径 int32 channelStart = 0; // 输出数据的起始通道 int32 channelCount = 1; // 输出数据的通道数量 enum WaveStyle{ Sine, Sawtooth, Square }; // 波形类型枚举 //function GenerateWaveform: generate one waveform for each selected analog data output channel ErrorCode GenerateWaveform( InstantAoCtrl * instantAoCtrl,int32 channelStart,int32 channelCount, double * waveBuffer, int32 SamplesCount,WaveStyle style); inline void waitAnyKey() { do{SLEEP(1);} while(!kbhit()); // 等待任意键 } //----------代码作用:生成单通道波形数据---------- //----------输入参数:instantAoCtrl:InstantAoCtrl类实例;channelStart:输出数据的起始通道;channelCount:输出数据的通道数量;waveBuffer:输出波形数据缓冲区;SamplesCount:波形数据点数;style:波形类型枚举---------- //----------输出参数:返回值:成功返回Success,失败返回错误码---------- int main(int argc, char* argv[]) { ErrorCode ret = Success; // Step 1: Create a 'InstantAoCtrl' for Static AO function. InstantAoCtrl * instantAoCtrl = InstantAoCtrl::Create(); do { // Step 2: Select a device by device number or device description and specify the access mode. // in this example we use ModeWrite mode so that we can fully control the device, including configuring, sampling, etc. DeviceInformation devInfo(deviceDescription); ret = instantAoCtrl->setSelectedDevice(devInfo); // 选择设备 CHK_RESULT(ret); ret = instantAoCtrl->LoadProfile(profilePath); // 加载配置文件以初始化设备 CHK_RESULT(ret); // Step 3: Output data // Generate waveform data double *waveform = (double*)malloc( channelCount*ONE_WAVE_POINT_COUNT*sizeof(double)); // 分配内存用于波形数据 if( NULL == waveform ) { printf( "Insufficient memory available\n" ); // 检查内存分配情况 break; } ret = GenerateWaveform( instantAoCtrl,channelStart,channelCount, waveform,channelCount*ONE_WAVE_POINT_COUNT,Sine); // 生成波形 CHK_RESULT(ret); printf("\n Outputting data... any key to quit!\n"); // 输出数据提示 bool enforced = false; // 强制退出标志 do { for( int32 i = 0; i < ONE_WAVE_POINT_COUNT; i++ ) { ret = instantAoCtrl->Write(channelStart, channelCount, &waveform[channelCount*i]); // 写入数据 CHK_RESULT(ret); SLEEP(1); // 延时 cout << "当前输出数据点数:" << i << endl; // 输出提示信息 if(kbhit()) { printf("\n Static AO is over compulsorily"); // 强制结束提示 enforced = true; break; } } } while (false); free(waveform); // 释放波形数据内存 if (!enforced) { printf("\n Static AO is over, press any key to quit!\n"); // 正常结束提示 } }while(false); // Step 4: Close device and release any allocated resource. instantAoCtrl->Dispose(); // 关闭设备并释放资源 // If something wrong in this execution, print the error code on screen for tracking. if(BioFailed(ret)) // 错误处理 { wchar_t enumString[256]; AdxEnumToString(L"ErrorCode", (int32)ret, 256, enumString); // 获取错误信息 printf("Some error occurred. And the last error code is 0x%X. [%ls]\n", ret, enumString); waitAnyKey(); // 等待任意键退出 } return 0; // 返回程序状态 } ErrorCode GenerateWaveform( InstantAoCtrl * instantAoCtrl, int32 channelStart,int32 channelCount,double * waveBuffer,int32 SamplesCount,WaveStyle style) { ErrorCode ret = Success; // 初始化返回状态 int32 channel = 0; // 当前通道索引 int32 channelCountMax = 0; // 最大通道数 int32 oneWaveSamplesCount = SamplesCount/channelCount; // 每通道波形样本数量 int32 i = 0; // 循环索引 MathInterval ranges[64] ; // 通道值范围 ValueRange valRange; // 存储通道值范围 channelCountMax = instantAoCtrl->getFeatures()->getChannelCountMax(); // 获取设备最大通道数 for(i = 0;i < channelCountMax ;i++ ) { valRange = instantAoCtrl->getChannels()->getItem(i).getValueRange(); // 获取当前通道的值范围 if ( V_ExternalRefBipolar == valRange || valRange == V_ExternalRefUnipolar ) // 如果是外部参考 { if (instantAoCtrl->getFeatures()->getExternalRefAntiPolar()) { double referenceValue; // 参考值 if (valRange == V_ExternalRefBipolar) { referenceValue = instantAoCtrl->getChannels()->getItem(i).getExtRefBipolar(); // 获取双极性参考值 if (referenceValue >= 0) { ranges[i].Max = referenceValue; // 设置最大值 ranges[i].Min = 0 - referenceValue; // 设置最小值 } else { ranges[i].Max = 0 - referenceValue; ranges[i].Min = referenceValue; } } else { referenceValue = instantAoCtrl->getChannels()->getItem(i).getExtRefUnipolar(); // 获取单极性参考值 if (referenceValue >= 0) { ranges[i].Max = 0; ranges[i].Min = 0 - referenceValue; } else { ranges[i].Max = 0 - referenceValue; ranges[i].Min = 0; } } } else { double referenceValue; // 参考值 if (valRange == V_ExternalRefBipolar) { referenceValue = instantAoCtrl->getChannels()->getItem(i).getExtRefBipolar(); // 获取双极性参考值 if (referenceValue >= 0) { ranges[i].Max = referenceValue; // 设置最大值 ranges[i].Min = 0 - referenceValue; // 设置最小值 } else { ranges[i].Max = 0 - referenceValue; ranges[i].Min = referenceValue; } } else { referenceValue = instantAoCtrl->getChannels()->getItem(i).getExtRefUnipolar(); // 获取单极性参考值 if (referenceValue >= 0) { ranges[i].Max = referenceValue; // 设置最大值 ranges[i].Min = 0; } else { ranges[i].Max = 0; ranges[i].Min = referenceValue; } } } } else { ret = AdxGetValueRangeInformation( valRange,0,NULL,&ranges[i],NULL); // 获取值范围信息 if(BioFailed(ret)) { return ret; // 返回错误状态 } } } //generate waveform data and put them into the buffer which the parameter 'waveBuffer' give in, the Amplitude these waveform for(i = 0; i < oneWaveSamplesCount; i++ ) { for( int32 j = channelStart; j < channelStart+channelCount; j++ ) { //pay attention to channel rollback(when startChannel+channelCount>chNumberMax+1) channel = j%channelCountMax; // 处理通道回卷 double amplitude = (ranges[channel].Max - ranges[channel].Min) / 2; // 幅度计算 double offset = (ranges[channel].Max + ranges[channel].Min) / 2; // 偏移计算 switch ( style) // 根据波形类型生成波形数据 { case Sine: *waveBuffer++ = amplitude*(sin((double)i*2.0*( 3.14159 )/oneWaveSamplesCount )) + offset; break; case Sawtooth: if ((i >= 0) && (i < (oneWaveSamplesCount / 4.0))) { *waveBuffer++ = amplitude*( i/(oneWaveSamplesCount/4.0)) + offset; } else { if ((i >= (oneWaveSamplesCount / 4.0)) && (i < 3 * (oneWaveSamplesCount/4.0))) { *waveBuffer++ = amplitude* ((2.0*(oneWaveSamplesCount/4.0)-i)/(oneWaveSamplesCount/4.0)) + offset; } else { *waveBuffer++ = amplitude* ((i-oneWaveSamplesCount)/(oneWaveSamplesCount/4.0)) + offset; } } break; case Square: if ((i >= 0) && (i < (oneWaveSamplesCount / 2))) { *waveBuffer++ = amplitude * 1 + offset; } else { *waveBuffer++ = amplitude * (-1) + offset; } break; default: printf("invalid wave style,generate waveform error !"); // 无效波形类型提示 ret = ErrorUndefined; // 返回未定义错误 } } } return ret; // 返回状态 };