//---------------------------------------------------------------------------- // // Function : Acquire data // // Description : Acquire data from board, optionally saving data to file. // //---------------------------------------------------------------------------- static public unsafe bool AcquireData(IntPtr boardHandle) { // TODO: Select the number of pre-trigger samples per record UInt32 preTriggerSamples = 1024; // TODO: Select the number of post-trigger samples per record UInt32 postTriggerSamples = 1024; // TODO: Specify the number of records to acquire to on-board memory UInt32 recordsPerCapture = 100; // TODO: Select the amount of time, in seconds, to wait for the // acquisiton to complete to on-board memory. int timeout_ms = 10 * 1000; // TODO: Select which channels to capture (A, B, or both) UInt32 channelMask = AlazarAPI.CHANNEL_A | AlazarAPI.CHANNEL_B; // TODO: Select if you wish to save the sample data to a file bool saveData = false; // Calculate the number of enabled channels from the channel mask UInt32 channelCount = 0; switch (channelMask) { case AlazarAPI.CHANNEL_A: case AlazarAPI.CHANNEL_B: channelCount = 1; break; case AlazarAPI.CHANNEL_A | AlazarAPI.CHANNEL_B: channelCount = 2; break; default: Console.WriteLine("Error: Invalid channel mask -- {0}", channelMask); return(false); } // Get the sample size in bits, and the on-board memory size in samples per channel Byte bitsPerSample; UInt32 maxSamplesPerChannel; UInt32 retCode = AlazarAPI.AlazarGetChannelInfo(boardHandle, &maxSamplesPerChannel, &bitsPerSample); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarGetChannelInfo failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // Calculate the size of each DMA buffer in bytes UInt32 bytesPerSample = ((UInt32)bitsPerSample + 7) / 8; UInt32 samplesPerRecord = preTriggerSamples + postTriggerSamples; UInt32 bytesPerRecord = bytesPerSample * samplesPerRecord; // Calculate the size of a record buffer in bytes // Note that the buffer must be at least 16 samples larger than the transfer size UInt32 bytesPerBuffer = bytesPerSample * (samplesPerRecord + 0); // Configure the record size retCode = AlazarAPI.AlazarSetRecordSize( boardHandle, preTriggerSamples, postTriggerSamples ); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarSetRecordSize failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // Configure the number of records in the acquisition retCode = AlazarAPI.AlazarSetRecordCount(boardHandle, recordsPerCapture); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarSetRecordCount failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // Arm the board to wait for a trigger event to begin the acquisition retCode = AlazarAPI.AlazarStartCapture(boardHandle); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarStartCapture failed -- " + AlazarAPI.AlazarErrorToText(retCode)); return(false); } // Wait for the board to capture all records to on-board memory Console.WriteLine("Capturing {0} record ... press any key to abort", recordsPerCapture); int startTickCount = System.Environment.TickCount; int timeoutTickCount = startTickCount + timeout_ms; bool success = true; while (AlazarAPI.AlazarBusy(boardHandle) != 0 && success == true) { if (System.Environment.TickCount > timeoutTickCount) { Console.WriteLine("Error: Capture timeout after {0} ms", timeout_ms); success = false; } else if (System.Console.KeyAvailable == true) { Console.WriteLine("Acquisition aborted"); success = false; } else { System.Threading.Thread.Sleep(10); } } if (!success) { // Abort the acquisition retCode = AlazarAPI.AlazarAbortCapture(boardHandle); if (retCode != AlazarAPI.ApiSuccess) { Console.WriteLine("Error: AlazarAbortCapture failed -- " + AlazarAPI.AlazarErrorToText(retCode)); } return(false); } // The board captured all records to on-board memory double captureTime_sec = ((double)(System.Environment.TickCount - startTickCount)) / 1000; double recordsPerSec; if (captureTime_sec > 0) { recordsPerSec = recordsPerCapture / captureTime_sec; } else { recordsPerSec = 0; } Console.WriteLine("Captured {0} records in {1:N3} sec ({2:N3} records / sec)", recordsPerCapture, captureTime_sec, recordsPerSec); FileStream fs = null; startTickCount = System.Environment.TickCount; UInt64 bytesTransferred = 0; try { // Create a data file if required if (saveData) { fs = File.Create(@"data.bin"); } // Allocate memory for one record byte[] buffer = new byte[bytesPerBuffer + 16]; // Cast byte array to short array ByteToShortArray byteToShortArray = new ByteToShortArray(); byteToShortArray.bytes = buffer; fixed(short *pBuffer = byteToShortArray.shorts) { // Transfer the records from on-board memory to our buffer Console.WriteLine("Transferring {0} records ... press any key to cancel", recordsPerCapture); UInt32 record; for (record = 0; record < recordsPerCapture; record++) { for (int channel = 0; channel < channelCount; channel++) { // Find the current channel Id UInt32 channelId; if (channelCount == 1) { if ((channelMask & AlazarAPI.CHANNEL_A) != 0) { channelId = AlazarAPI.CHANNEL_A; } else { channelId = AlazarAPI.CHANNEL_B; } } else { if (channel == 0) { channelId = AlazarAPI.CHANNEL_A; } else { channelId = AlazarAPI.CHANNEL_B; } } // Transfer one full record from on-board memory to our buffer retCode = AlazarAPI.AlazarRead( boardHandle, channelId, pBuffer, (int)bytesPerSample, (int)record + 1, -((int)preTriggerSamples), samplesPerRecord ); if (retCode != AlazarAPI.ApiSuccess) { throw new System.Exception("Error: AlazarRead record -- " + AlazarAPI.AlazarErrorToText(retCode)); } bytesTransferred += bytesPerRecord; // TODO: Process record here. // // A 12-bit sample code is stored in the most significant bits // of // in each 16-bit sample value. // // Sample codes are unsigned by default. As a result: // - a sample code of 0x0000 represents a negative full scale // input signal. // - a sample code of 0x8000 represents a ~0V signal. // - a sample code of 0xFFFF represents a positive full scale // input signal. if (saveData) { // Write record to file fs.Write(buffer, 0, (int)bytesPerRecord); } } // If a key was pressed, then stop processing records. if (Console.KeyAvailable == true) { throw new System.Exception("Error: Transfer aborted"); } } } } catch (Exception exception) { Console.WriteLine(exception.ToString()); success = false; } finally { // Close the data file if (fs != null) { fs.Close(); } } // Display results double transferTime_sec = ((double)(System.Environment.TickCount - startTickCount)) / 1000; double bytesPerSec; if (transferTime_sec > 0) { bytesPerSec = bytesTransferred / transferTime_sec; } else { bytesPerSec = 0; } Console.WriteLine("Transferred {0} bytes ({1:G4} bytes per sec)", bytesTransferred, bytesPerSec); return(success); }