AsynchronousOneWaveformAO.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*******************************************************************************
  2. Copyright (c) 1983-2016 Advantech Co., Ltd.
  3. ********************************************************************************
  4. THIS IS AN UNPUBLISHED WORK CONTAINING CONFIDENTIAL AND PROPRIETARY INFORMATION
  5. WHICH IS THE PROPERTY OF ADVANTECH CORP., ANY DISCLOSURE, USE, OR REPRODUCTION,
  6. WITHOUT WRITTEN AUTHORIZATION FROM ADVANTECH CORP., IS STRICTLY PROHIBITED.
  7. ================================================================================
  8. REVISION HISTORY
  9. --------------------------------------------------------------------------------
  10. $Log: $
  11. --------------------------------------------------------------------------------
  12. $NoKeywords: $
  13. */
  14. /******************************************************************************
  15. *
  16. * Windows Example:
  17. * AsynchronousOneWaveformAO.cpp
  18. *
  19. * Example Category
  20. * AO
  21. * Description:
  22. * This example demonstrates how to use Asynchronous One Waveform AO function.
  23. *
  24. * Instructions for Running:
  25. * 1 Set the 'deviceDescription' for opening the device.
  26. * 2 Set the 'profilePath' to save the profile path of being initialized device.
  27. * 3 Set the 'channelStart' as the first channel for analog data output.
  28. * 4 Set the 'channelCount' to decide how many sequential channels to output analog data.
  29. *
  30. * I/O Connections Overview:
  31. * Please refer to your hardware reference manual.
  32. *
  33. ******************************************************************************/
  34. #include <stdlib.h>
  35. #include <stdio.h>
  36. #include <math.h>
  37. #include "../inc/compatibility.h"
  38. #include "../../../inc/bdaqctrl.h"
  39. using namespace Automation::BDaq;
  40. //-----------------------------------------------------------------------------------
  41. // Configure the following parameters before running the demo
  42. //-----------------------------------------------------------------------------------
  43. #define ONE_WAVE_POINT_COUNT 2048 //define how many data to makeup a waveform period.
  44. int32 samples = ONE_WAVE_POINT_COUNT;
  45. #define deviceDescription L"DemoDevice,BID#0"
  46. const wchar_t* profilePath = L"../../profile/DemoDevice.xml";
  47. int32 startChannel = 0;
  48. int32 channelCount = 10;
  49. enum WaveStyle{ Sine, Sawtooth, Square };
  50. //function GenerateWaveform: generate one waveform for each selected analog data output channel
  51. ErrorCode GenerateWaveform( BufferedAoCtrl * ,int32 ,int32 , double * , int32 ,WaveStyle );
  52. inline void waitAnyKey()
  53. {
  54. do{SLEEP(1);} while(!kbhit());
  55. }
  56. // This function is used to deal with 'Stopped' Event.
  57. void BDAQCALL OnStoppedEvent(void * sender, BfdAoEventArgs * args, void * userParam)
  58. {
  59. printf("\nBufferedAO stopped: offset = %d, count = %d\n", args->Offset, args->Count);
  60. }
  61. int main(int argc, char* argv[])
  62. {
  63. ErrorCode ret = Success;
  64. // Step 1: Create a 'BufferedAoCtrl' for buffered AO function.
  65. BufferedAoCtrl * bfdAoCtrl = BufferedAoCtrl::Create();
  66. // Step 2: Set the notification event Handler by which we can known the state of operation effectively.
  67. bfdAoCtrl->addStoppedHandler(OnStoppedEvent, NULL);
  68. do
  69. {
  70. // Step 3: Select a device by device number or device description and specify the access mode.
  71. // in this example we use ModeWrit mode so that we can fully control the device, including configuring, sampling, etc.
  72. DeviceInformation devInfo(deviceDescription);
  73. ret = bfdAoCtrl->setSelectedDevice(devInfo);
  74. CHK_RESULT(ret);
  75. ret = bfdAoCtrl->setStreaming(false);// specify the running mode: one-buffered.
  76. CHK_RESULT(ret);
  77. ret = bfdAoCtrl->LoadProfile(profilePath);//Loads a profile to initialize the device.
  78. CHK_RESULT(ret);
  79. // Step 4: Set necessary parameters.
  80. ScanChannel * scanChannel = bfdAoCtrl->getScanChannel();
  81. ret = scanChannel->setChannelStart(startChannel);
  82. CHK_RESULT(ret);
  83. ret = scanChannel->setChannelCount(channelCount);
  84. CHK_RESULT(ret);
  85. ret = scanChannel->setSamples(samples);
  86. CHK_RESULT(ret);
  87. // Step 5: Prepare the buffered AO.
  88. ret = bfdAoCtrl->Prepare();
  89. CHK_RESULT(ret);
  90. // Generate waveform data
  91. int scaledWaveFormLen = channelCount*ONE_WAVE_POINT_COUNT*sizeof(double);
  92. double* scaledWaveForm = (double*)malloc(scaledWaveFormLen);
  93. if( NULL == scaledWaveForm )
  94. {
  95. printf( "Insufficient memory available\n" );
  96. break;
  97. }
  98. ret = GenerateWaveform( bfdAoCtrl,startChannel,channelCount, scaledWaveForm,(int32)(channelCount*ONE_WAVE_POINT_COUNT),Sine);
  99. CHK_RESULT(ret);
  100. ret = bfdAoCtrl->SetData(channelCount*ONE_WAVE_POINT_COUNT,scaledWaveForm);
  101. CHK_RESULT(ret);
  102. // Step 6: Start Asynchronous One Waveform AO, 'Asynchronous' means the method returns immediately
  103. // after the Buffered AO has been started. The StoppedHandler's 'BfdAoEvent' method will be called
  104. // after the Buffered AO is completed.
  105. printf("Asynchronous Buffered AO is in progress.\n");
  106. printf("Please wait... any key to quit !\n");
  107. ret = bfdAoCtrl->Start();
  108. CHK_RESULT(ret);
  109. free(scaledWaveForm);
  110. // Step 7: Do anything you are interesting while the device is outputting data.
  111. do
  112. {
  113. // do something yourself !
  114. SLEEP(1);
  115. }while(!kbhit());
  116. // step 8: Stop the operation if it is running.
  117. ret = bfdAoCtrl->Stop(1);
  118. CHK_RESULT(ret);
  119. }while(false);
  120. // Step 9: Close device, release any allocated resource.
  121. bfdAoCtrl->Dispose();
  122. // If something wrong in this execution, print the error code on screen for tracking.
  123. if(BioFailed(ret))
  124. {
  125. wchar_t enumString[256];
  126. AdxEnumToString(L"ErrorCode", (int32)ret, 256, enumString);
  127. printf("Some error occurred. And the last error code is 0x%X. [%ls]\n", ret, enumString);
  128. waitAnyKey();// Wait any key to quit !
  129. }
  130. return 0;
  131. }
  132. ErrorCode GenerateWaveform(BufferedAoCtrl * bfdAoCtrl, int32 channelStart,int32 channelCount,double * waveBuffer,int32 SamplesCount,WaveStyle style)
  133. {
  134. ErrorCode ret = Success;
  135. int32 channel = 0;
  136. int32 channelCountMax = 0;
  137. int32 oneWaveSamplesCount = SamplesCount/channelCount;
  138. int32 i = 0;
  139. MathInterval ranges[64] ;
  140. ValueRange valRange;
  141. channelCountMax = bfdAoCtrl->getFeatures()->getChannelCountMax();
  142. for(i = 0;i < channelCountMax ;i++ )
  143. {
  144. valRange = bfdAoCtrl->getChannels()->getItem(i).getValueRange();
  145. if ( V_ExternalRefBipolar == valRange || valRange == V_ExternalRefUnipolar )
  146. {
  147. if (bfdAoCtrl->getFeatures()->getExternalRefAntiPolar())
  148. {
  149. double referenceValue;
  150. if (valRange == V_ExternalRefBipolar)
  151. {
  152. referenceValue = bfdAoCtrl->getChannels()->getItem(i).getExtRefBipolar();
  153. if (referenceValue >= 0) {
  154. ranges[i].Max = referenceValue;
  155. ranges[i].Min = 0 - referenceValue;
  156. } else {
  157. ranges[i].Max = 0 - referenceValue;
  158. ranges[i].Min = referenceValue;
  159. }
  160. }
  161. else
  162. {
  163. referenceValue = bfdAoCtrl->getChannels()->getItem(i).getExtRefUnipolar();
  164. if (referenceValue >= 0) {
  165. ranges[i].Max = 0;
  166. ranges[i].Min = 0 - referenceValue;
  167. } else {
  168. ranges[i].Max = 0 - referenceValue;
  169. ranges[i].Min = 0;
  170. }
  171. }
  172. }
  173. else
  174. {
  175. double referenceValue;
  176. if (valRange == V_ExternalRefBipolar)
  177. {
  178. referenceValue = bfdAoCtrl->getChannels()->getItem(i).getExtRefBipolar();
  179. if (referenceValue >= 0) {
  180. ranges[i].Max = referenceValue;
  181. ranges[i].Min = 0 - referenceValue;
  182. } else {
  183. ranges[i].Max = 0 - referenceValue;
  184. ranges[i].Min = referenceValue;
  185. }
  186. }
  187. else
  188. {
  189. referenceValue = bfdAoCtrl->getChannels()->getItem(i).getExtRefUnipolar();
  190. if (referenceValue >= 0) {
  191. ranges[i].Max = referenceValue;
  192. ranges[i].Min = 0;
  193. } else {
  194. ranges[i].Max = 0;
  195. ranges[i].Min = referenceValue;
  196. }
  197. }
  198. }
  199. }
  200. else {
  201. ret = AdxGetValueRangeInformation( valRange,0,NULL,&ranges[i],NULL);
  202. if(BioFailed(ret))
  203. {
  204. return ret;
  205. }
  206. }
  207. }
  208. //generate waveform data and put them into the buffer which the parameter 'waveBuffer' give in, the Amplitude these waveform
  209. for(i = 0; i < oneWaveSamplesCount; i++ )
  210. {
  211. for( int32 j = channelStart; j < channelStart+channelCount; j++ )
  212. {
  213. //pay attention to channel rollback(when startChannel+channelCount>chNumberMax+1)
  214. channel = j%channelCountMax;
  215. double amplitude = (ranges[channel].Max - ranges[channel].Min) / 2;
  216. double offset = (ranges[channel].Max + ranges[channel].Min) / 2;
  217. switch ( style)
  218. {
  219. case Sine:
  220. *waveBuffer++ = amplitude*(sin((double)i*2.0*( 3.14159 )/oneWaveSamplesCount )) + offset;
  221. break;
  222. case Sawtooth:
  223. if ((i >= 0) && (i < (oneWaveSamplesCount / 4.0)))
  224. {
  225. *waveBuffer++ = amplitude*( i/(oneWaveSamplesCount/4.0)) + offset;
  226. }
  227. else
  228. {
  229. if ((i >= (oneWaveSamplesCount / 4.0)) && (i < 3 * (oneWaveSamplesCount/4.0)))
  230. {
  231. *waveBuffer++ = amplitude* ((2.0*(oneWaveSamplesCount/4.0)-i)/(oneWaveSamplesCount/4.0)) + offset;
  232. }
  233. else
  234. {
  235. *waveBuffer++ = amplitude* ((i-oneWaveSamplesCount)/(oneWaveSamplesCount/4.0)) + offset;
  236. }
  237. }
  238. break;
  239. case Square:
  240. if ((i >= 0) && (i < (oneWaveSamplesCount / 2)))
  241. {
  242. *waveBuffer++ = amplitude * 1 + offset;
  243. }
  244. else
  245. {
  246. *waveBuffer++ = amplitude * (-1) + offset;
  247. }
  248. break;
  249. default:
  250. printf("invalid wave style,generate waveform error !");
  251. ret = ErrorUndefined;
  252. }
  253. }
  254. }
  255. return ret;
  256. };