Пример #1
0
        //----------------------------------------------------------------------------
        //
        // 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);
        }