/* OscilloscopeGeneratorTrigger.cs
 *
 * This example sets up the generator to generate a 1 kHz triangle waveform, 4 Vpp.
 * It also sets up the oscilloscope to perform a block mode measurement, triggered on "Generator new period".
 * A measurement is performed and the data is written to OscilloscopeGeneratorTrigger.csv.
 *
 * Find more information on http://www.tiepie.com/LibTiePie .
 */
using System;
using System.IO;
using System.Threading;
using TiePie.LibTiePie;
class OscilloscopeGeneratorTrigger
{
    public static void Main()
    {
        // Print library information:
        PrintInfo.PrintLibraryInfo();
        // Enable network search:
        Network.AutoDetectEnabled = true;
        // Update device list:
        DeviceList.Update();
        // Try to open an oscilloscope with block measurement support and a generator in the same device:
        Oscilloscope scp = null;
        Generator gen = null;
        for (UInt32 i = 0; i < DeviceList.Count; i++)
        {
            DeviceListItem item = DeviceList.GetItemByIndex(i);
            if (item.CanOpen(DeviceType.Oscilloscope) && item.CanOpen(DeviceType.Generator))
            {
                scp = item.OpenOscilloscope();
                if ((scp.MeasureModes & Constants.MM_BLOCK) != 0)
                {
                    gen = item.OpenGenerator();
                    break;
                }
                else
                {
                    scp.Dispose();
                    scp = null;
                }
            }
        }
        if (scp != null && gen != null)
        {
            try
            {
                // Oscilloscope settings:
                // Get the number of channels:
                UInt16 channelCount = Convert.ToUInt16(scp.Channels.Count);
                // Set measure mode:
                scp.MeasureMode = MeasureMode.Block;
                // Set sample frequency:
                scp.SampleFrequency = 1e6; // 1 MHz
                // Set record length:
                scp.RecordLength = 10000; // 10 kS
                UInt64 recordLength = scp.RecordLength; // Read actual record length.
                // Set pre sample ratio:
                scp.PreSampleRatio = 0; // 0 %
                // For all channels:
                for (UInt16 ch = 0; ch < channelCount; ch++)
                {
                    OscilloscopeChannel channel = scp.Channels[ch];
                    // Enable channel to measure it:
                    channel.Enabled = true;
                    // Set range:
                    channel.Range = 8; // 8 V
                    // Set coupling:
                    channel.Coupling = Coupling.DCV; // DC Volt
                }
                // Set trigger timeout:
                scp.TriggerTimeOut = 1; // 1 s
                // Disable all channel trigger sources:
                for (UInt16 ch = 0; ch < channelCount; ch++)
                {
                    scp.Channels[ch].Trigger.Enabled = false;
                }
                // Locate trigger input:
                TriggerInput triggerInput = scp.TriggerInputs.GetById(Constants.TIID_GENERATOR_NEW_PERIOD); // or Constants.TIID_GENERATOR_START or Constants.TIID_GENERATOR_STOP
                if (triggerInput == null)
                {
                    throw new System.Exception("Unknown trigger input!");
                }
                // Enable trigger input:
                triggerInput.Enabled = true;
                // Generator settings:
                // Set signal type:
                gen.SignalType = SignalType.Triangle;
                // Set frequency:
                gen.Frequency = 1e3; // 1 kHz
                // Set amplitude:
                gen.Amplitude = 2; // 2 V
                // Set offset:
                gen.Offset = 0; // 0 V
                // Enable output:
                gen.OutputOn = true;
                // Print oscilloscope info:
                PrintInfo.PrintDeviceInfo(scp);
                // Print generator info:
                PrintInfo.PrintDeviceInfo(gen);
                // Start measurement:
                scp.Start();
                // Start signal generation:
                gen.Start();
                // Wait for measurement to complete:
                while (!scp.IsDataReady)
                {
                    Thread.Sleep(10); // 10 ms delay, to save CPU time.
                }
                // Stop generator:
                gen.Stop();
                // Disable output:
                gen.OutputOn = false;
                // Get data:
                float[][] data = scp.GetData();
                // Open file with write/update permissions:
                string filename = "OscilloscopeGeneratorTrigger.csv";
                StreamWriter file = new StreamWriter(filename, false);
                // Output CSV data:
                if (File.Exists(filename))
                {
                    // Write csv header:
                    file.Write("Sample");
                    for (UInt16 i = 0; i < channelCount; i++)
                    {
                        file.Write(string.Format(";Ch{0}", i + 1));
                    }
                    file.Write(Environment.NewLine);
                    // Write the data to csv:
                    for (UInt64 i = 0; i < recordLength; i++)
                    {
                        file.Write(i.ToString());
                        for (UInt16 ch = 0; ch < channelCount; ch++)
                        {
                            file.Write(";" + data[ch][i].ToString());
                        }
                        file.Write(Environment.NewLine);
                    }
                    Console.WriteLine("Data written to: " + filename);
                    // Close file:
                    file.Close();
                }
                else
                {
                    Console.WriteLine("Couldn't open file: " + filename);
                    Environment.Exit(1);
                }
            }
            catch (System.Exception e)
            {
                Console.WriteLine("Exception: " + e.Message);
                Environment.Exit(1);
            }
            // Close oscilloscope:
            scp.Dispose();
            scp = null;
            // Close generator:
            gen.Dispose();
            gen = null;
        }
        else
        {
            Console.WriteLine("No oscilloscope available with block measurement support!");
            Environment.Exit(1);
        }
        Environment.Exit(0);
    }
}