Beispiel #1
0
        private void buttonLoadInternal_Click(object sender, EventArgs e)
        {
            string filename = textBoxFileName.Text;

            //Define a double array with half a gaussian to create a waveform object
            double[] dataTmp = { 0.000003726653172, 0.000006113567966, 0.000009929504306, 0.000015966783898, 0.000025419346516,
                                 0.000040065297393, 0.000062521503775, 0.000096593413722, 0.000147748360232, 0.000223745793721,
                                 0.000335462627903, 0.000497955421503, 0.000731802418880, 0.001064766236668, 0.001533810679324,
                                 0.002187491118183, 0.003088715408237, 0.004317840007633, 0.005976022895006, 0.008188701014374,
                                 0.011108996538242, 0.014920786069068, 0.019841094744370, 0.026121409853918, 0.034047454734599,
                                 0.043936933623407, 0.056134762834134, 0.071005353739637, 0.088921617459386, 0.110250525304485,
                                 0.135335283236613, 0.164474456577155, 0.197898699083615, 0.235746076555864, 0.278037300453194,
                                 0.324652467358350, 0.375311098851400, 0.429557358210739, 0.486752255959972, 0.546074426639710,
                                 0.606530659712633, 0.666976810858475, 0.726149037073691, 0.782704538241868, 0.835270211411272,
                                 0.882496902584595, 0.923116346386636, 0.955997481833100, 0.980198673306755, 0.995012479192682 };

            // Create a waveform object from a data vector
            SD_Wave tmpWaveform = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, 50, dataTmp);

            // Load the waveform object on the module memory
            int status = module.waveformLoad(tmpWaveform, WFinModuleCount);

            // Update the loaded waveform visualization textbox and counter
            if (status >= 0)
            {
                textBoxWFModuleList.Text = textBoxWFModuleList.Text + "WF#:" + WFinModuleCount.ToString() + " => Inertnal (Half-Gaussian)" + "\r\n";
                WFinModuleCount++;
            }
            labelWaveformsInModule.Text = "Waveforms in Module: " + WFinModuleCount.ToString();
        }
Beispiel #2
0
        private void buttonDWGstrobeOutWithTrigger_Click(object sender, EventArgs e)
        {
            // Config the Output Bus 0 in pins 0 to 15 of Port 0
            moduleDIO.busConfig(SD_DIO_Bus.DIO_OUTPUT_BUS0, 0, 0, 15);

            // Config the Strobe 0
            moduleDIO.busSamplingConfig(SD_DIO_Bus.DIO_OUTPUT_BUS0, 0, SD_Strobe.STROBE_ON, SD_Strobe.STROBE_EDGERISE, 0, 0, SD_DebouncingTypes.DEBOUNCING_NONE);

            //Config pins 0 to 15 of Port 0 as output
            moduleDIO.IOdirectionConfig(0x000000000000FFFF, SD_PinDirections.DIR_OUT);

            // Create waveforms objects in PC RAM from waveforms files
            SD_Wave waveId1 = new SD_Wave("W:\\Waveforms_Demo\\Alberto\\DigitalTest_32samples.txt");
            SD_Wave waveId2 = new SD_Wave("W:\\Waveforms_Demo\\Alberto\\DigitalTest_48samples.txt");

            if (waveId1.getStatus() < 0 || waveId1.getStatus() < 0)
            {
                printToConsole("Error opening waveform File\n");
                runPause();
                // Waves will be freed by garbage colletor
                return;
            }

            // Erase all waveforms from module memory and load waveforms waveId1 and waveId2 in position nWave1 and nWave2
            moduleDIO.waveformFlush();
            moduleDIO.waveformLoad(waveId1, 0);
            moduleDIO.waveformLoad(waveId2, 1);

            // Flush channel waveform queue
            moduleDIO.DWGflush(nChannel);

            // Queue waveforms nWave1 and nWave2 in nChannel
            moduleDIO.DWGqueueWaveform(nChannel, 0, SD_TriggerModes.AUTOTRIG, 0, 1, 1);
            moduleDIO.DWGqueueWaveform(nChannel, 1, SD_TriggerModes.VIHVITRIG, 0, 1, 1);

            printToConsole("Module configuration successfull. Press any key to start the DWG.");
            runPause();

            moduleDIO.DWGstart(nChannel);

            printToConsole("DWG started. Press any key to send a VI/HVI trigger.");
            runPause();

            moduleDIO.DWGtrigger(nChannel);

            printToConsole("Press any key to stop the DWG.");
            runPause();

            moduleDIO.DWGstop(nChannel);

            printToConsole("DWG Stopped. Press any key to finish.");
            runPause();
        }
Beispiel #3
0
        private void buttonTestFrequencyModulation_Click(object sender, EventArgs e)
        {
            // Create a waveform object in PC RAM from waveform file
            SD_Wave wave = new SD_Wave("..\\..\\..\\..\\..\\..\\..\\Waveforms\\Gaussian.csv");

            if (wave.getStatus() < 0)
            {
                printToConsole("Error opening waveform File");
                runPause();
                return;
            }
            int nWave = 0;

            // Erase all waveforms from module memory and load the waveform waveID in position nWave
            moduleAOU.waveformFlush();
            moduleAOU.waveformLoad(wave, nWave);

            // Turn off nChannel
            moduleAOU.channelWaveShape(nChannel, SD_Waveshapes.AOU_OFF);

            // Switch off amplitude modulation and setup FM modulation
            moduleAOU.modulationAmplitudeConfig(nChannel, SD_ModulationTypes.AOU_MOD_OFF, 0);
            moduleAOU.modulationAngleConfig(nChannel, SD_ModulationTypes.AOU_MOD_FM, 10 * 1E6);                 // Deviation Gain = 10 * 1E6 (in Hz)

            // Config amplitude, frequency and shape
            moduleAOU.channelAmplitude(nChannel, 1.0);                                                   // 1 Volts Peak
            moduleAOU.channelFrequency(nChannel, 10E6);                                                  // 10 MHz
            moduleAOU.channelWaveShape(nChannel, SD_Waveshapes.AOU_SINUSOIDAL);

            // Flush channel waveform queue
            moduleAOU.AWGflush(nChannel);

            // Queue waveform nWave in nChannel
            moduleAOU.AWGqueueWaveform(nChannel, nWave, SD_TriggerModes.AUTOTRIG, 0, 0, 1);

            printToConsole("Module configuration successfull. Press CONTINUE to start the AWG");
            runPause();

            moduleAOU.AWGstart(nChannel);

            printToConsole("AWG started. Press CONTINUE to stop the AWG.");
            runPause();

            moduleAOU.AWGstop(nChannel);

            printToConsole("AWG Stopped. Press CONTINUE to finish.");
            runPause();
        }
Beispiel #4
0
        private void buttonLoadWaveform_Click(object sender, EventArgs e)
        {
            string filename = textBoxFileName.Text;

            // Create a waveform object from a waveform file to load it later to the module memory
            SD_Wave tmpWaveform = new SD_Wave(filename);

            // Load the waveform in the waveform object to the module memory
            int status = module.waveformLoad(tmpWaveform, WFinModuleCount);

            // Update the loaded waveform visualization textbox and counter
            if (status >= 0)
            {
                textBoxWFModuleList.Text = textBoxWFModuleList.Text + "WF#:" + WFinModuleCount.ToString() + " => " + filename + "\r\n";
                WFinModuleCount++;
            }
            labelWaveformsInModule.Text = "Waveforms in Module: " + WFinModuleCount.ToString();
        }
        public HW_STATUS_RETURNS ScanControlInitialize(double x_amp, double y_amp, double[] Xarray_vol, double[] Yarray_vol, int[] Xarray_index, int[] Yarray_index, double delay, int recording_rate)
        {
            int status;
            // Channel 1 for y scan and channel 2 for x scan

            //Create an instance of the AOU module
            SD_AOU moduleAOU  = new SD_AOU();
            string ModuleName = "M3201A";
            int    nChassis   = 1;
            int    nSlot      = 7;

            if ((status = moduleAOU.open(ModuleName, nChassis, nSlot)) < 0)
            {
                Console.WriteLine("Error openning the Module 'M3201A', make sure the slot and chassis are correct. Aborting...");
                Console.ReadKey();

                return(HW_STATUS_RETURNS.HW_SUCCESS);
            }

            // Config amplitude and setup AWG in channels 1 and 2,
            moduleAOU.channelAmplitude(1, y_amp);
            moduleAOU.channelWaveShape(1, SD_Waveshapes.AOU_AWG);
            moduleAOU.channelAmplitude(2, x_amp);
            moduleAOU.channelWaveShape(2, SD_Waveshapes.AOU_AWG);
            moduleAOU.waveformFlush();

            // Convert array into list

            xpoints = new List <double>();
            ypoints = new List <double>();
            xindex  = new List <int>();
            yindex  = new List <int>();

            xpoints.Clear();
            ypoints.Clear();
            xindex.Clear();
            yindex.Clear();
            xpoints = Xarray_vol.ToList();
            ypoints = Yarray_vol.ToList();
            xindex  = Xarray_index.ToList();
            yindex  = Yarray_index.ToList();

            // Set external trigger as input
            moduleAOU.triggerIOdirection(SD_TriggerDirections.AOU_TRG_IN);
            // Config trigger as external trigger and rising edge
            moduleAOU.AWGtriggerExternalConfig(1, SD_TriggerExternalSources.TRIGGER_EXTERN, SD_TriggerBehaviors.TRIGGER_RISE);
            moduleAOU.AWGtriggerExternalConfig(2, SD_TriggerExternalSources.TRIGGER_EXTERN, SD_TriggerBehaviors.TRIGGER_RISE);
            // flush both channels
            status = moduleAOU.AWGflush(1);
            status = moduleAOU.AWGflush(2);


            int WFinModuleCount = 0;


            /// load waveform for channel 2 (X)
            for (int ix = 0; ix < xpoints.Count; ix++)
            {
                // with 16 reps when generate wave form, AWG generates the desired scan pattern, not sure why
                // var tmpWaveform_X = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, new double[] { xpoints[ix], xpoints[ix], xpoints[ix], xpoints[ix], xpoints[ix], xpoints[ix], xpoints[ix], xpoints[ix], xpoints[ix], xpoints[ix], xpoints[ix], xpoints[ix], xpoints[ix], xpoints[ix], xpoints[ix], xpoints[ix] });
                var tmpWaveform_X = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, new double[] { xpoints[ix], xpoints[ix] });
                status = moduleAOU.waveformLoad(tmpWaveform_X, WFinModuleCount, 1);       // padding option 1 is used to maintain ending voltage after each WaveForm
                if (status < 0)
                {
                    Console.WriteLine("Error while loading " + ix + " point from x array");
                }
                WFinModuleCount++;
            }
            // queue x channel, for x, WFinModuleCount is the same as ix
            for (int ix = 0; ix < xindex.Count; ix++)
            {
                // loop x array
                status = moduleAOU.AWGqueueWaveform(2, xindex[ix], SD_TriggerModes.EXTTRIG, 0, 1, 4);// AWG, waveform#, trigger, delay, cycle,prescaler
                if (status < 0)
                {
                    Console.WriteLine("Error while queuing " + ix + " point from x array");
                }
            }

            /// load waveform for channel 1 (Y)

            for (int iy = 0; iy < ypoints.Count; iy++)
            {
                //    var tmpWaveform_Y = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, new double[] { ypoints[iy], ypoints[iy], ypoints[iy], ypoints[iy], ypoints[iy], ypoints[iy], ypoints[iy], ypoints[iy], ypoints[iy], ypoints[iy], ypoints[iy], ypoints[iy], ypoints[iy], ypoints[iy], ypoints[iy], ypoints[iy] });
                var tmpWaveform_Y = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, new double[] { ypoints[iy], ypoints[iy] });

                status = moduleAOU.waveformLoad(tmpWaveform_Y, WFinModuleCount, 1);       // padding option 1 is used to maintain ending voltage after each WaveForm
                if (status < 0)
                {
                    Console.WriteLine("Error while loading " + iy + " point from y array, error code " + status);
                }
                WFinModuleCount++;
            }
            // queue waveform for channel 1
            for (int iy = 0; iy < yindex.Count; iy++)
            {
                // use external trigger and cycles for Y channel
                status = moduleAOU.AWGqueueWaveform(1, yindex[iy] + xpoints.Count, SD_TriggerModes.EXTTRIG_CYCLE, 0, xindex.Count, 4);// AWG, waveform#, trigger, delay, cycle,prescaler
                if (status < 0)
                {
                    Console.WriteLine("Error while queuing " + iy + " point from y array, error code " + status);
                }
            }

            // y protection waveform runs only once
            var protWaveform_Y = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, new double[] { -0.99, -0.99 });

            status = moduleAOU.waveformLoad(protWaveform_Y, WFinModuleCount, 1);  // use pos xpoints.Count + ypoints.Count at waveform pool, can be shared by both x and y
            if (status < 0)
            {
                Console.WriteLine("Error while loading protection point from y array, error code " + status);
            }
            status = moduleAOU.AWGqueueWaveform(1, xpoints.Count + ypoints.Count, SD_TriggerModes.EXTTRIG, 0, 2, 4095);// AWG, waveform#, trigger, delay, cycle, prescaler
            if (status < 0)
            {
                Console.WriteLine("Error while queuing protection point from y array, error code " + status);
            }


            // Configure X channel to cyclic mode, Y to single shot
            moduleAOU.AWGqueueConfig(1, 0);
            moduleAOU.AWGqueueConfig(2, 1);


            Console.WriteLine("Scanning in traditional way with " + Xarray_index.Count() + " by " + Yarray_index.Count() + " beam positions.");
            // Start both channel and wait for triggers
            moduleAOU.AWGstart(1);
            moduleAOU.AWGstart(2);  // after AWGstart(2), AWGisRunning(2) = 1, AWGnWFplaying(2) = 0, same for channel 1, there might be 1 px offset
            Console.WriteLine("Now running on x and y " + moduleAOU.AWGnWFplaying(1) + "----" + moduleAOU.AWGnWFplaying(2));
            #region previous scheme to jump on Y channel

            // determine how long to pause after each jump based on frame rate

            /*int pause_ms = 1;
             * double frametime = 1000 / (double)recording_rate;
             * if (frametime > 1)
             * {
             *  pause_ms = (int)Math.Ceiling(frametime);
             * }
             * int ncycle = 0;
             *         Console.WriteLine("Now on Y channel " + moduleAOU.AWGnWFplaying(1) + " Now on X channel: " + moduleAOU.AWGnWFplaying(2) + "_" + moduleAOU.AWGisRunning(2));
             *         while (moduleAOU.AWGnWFplaying(2) == 0)   // x channel may not be at zero when no trigger come, replace with AWGisRunning
             *         {
             *             // Empty loop wait for trigger to come
             *         }
             *
             *         // Now cycle start
             *         Console.WriteLine("Now on Y channel " + moduleAOU.AWGnWFplaying(1) + " Now on X channel " + moduleAOU.AWGnWFplaying(2));
             *         ncycle++;   // ncycle=1, currently working on cycle 1
             *
             *
             *
             *         while (ncycle < yindex.Count())
             *         {
             *             if(moduleAOU.AWGnWFplaying(2)==xindex.Count()-1)
             *             {
             *                 ncycle++;
             *                 moduleAOU.AWGtrigger(1);
             *                 Console.WriteLine("Jump to cycle " + ncycle + " now on Y channel: " + moduleAOU.AWGnWFplaying(1) + " now on X channel : " + moduleAOU.AWGnWFplaying(2));
             *                 System.Threading.Thread.Sleep(pause_ms * 2);
             *             }
             *         }
             *         moduleAOU.AWGtrigger(1);    // trigger y to protection position and stop x scan
             *         Console.WriteLine("Now on Y channel " + moduleAOU.AWGnWFplaying(1));
             *         moduleAOU.AWGstop(2);
             *         System.Threading.Thread.Sleep(5000);    // sleep 5 secs with beam in protection position for user to block beam and stop acquisition
             */
            #endregion
            while (moduleAOU.AWGnWFplaying(1) != xpoints.Count + ypoints.Count)
            {
            }
            Console.WriteLine("Acquisition finished, stop camera now");
            moduleAOU.AWGstop(2);
            moduleAOU.AWGstop(1);


            return(HW_STATUS_RETURNS.HW_SUCCESS);
        }
Beispiel #6
0
        // Called by SetScanParameter to generate WaveForm and queue to AWG
        private int prepareScan()
        {
            int     status;
            SD_Wave tmpWaveform;

            module.waveformFlush();

            // Remove all waveform from the channel 1 queue
            status = module.AWGflush(1);
            if (status >= 0)
            {
                c1WFinQueueCount = 0;
            }
            else
            {
                return(1);
            }

            // Remove all waveform from the channel 2 queue
            status = module.AWGflush(2);
            if (status >= 0)
            {
                c2WFinQueueCount = 0;
            }
            else
            {
                return(1);
            }
            // set trigger direction to input
            module.triggerIOdirection(SD_TriggerDirections.AOU_TRG_IN);
            // set trigger configuration to external, rising edge
            module.AWGtriggerExternalConfig(1, SD_TriggerExternalSources.TRIGGER_EXTERN, SD_TriggerBehaviors.TRIGGER_RISE);

            // set wave shape and amplitude
            module.channelAmplitude(1, y_amp);                          // 1.2 Volts Peak
            module.channelWaveShape(1, SD_Waveshapes.AOU_AWG);
            module.channelAmplitude(2, x_amp);                          // 1.2 Volts Peak
            module.channelWaveShape(2, SD_Waveshapes.AOU_AWG);

            // generate waveforms.
            // Notes: waveform number is from 0 to y_length-1 for y direction, then frm y_length to y_length + x_length -1;
            // Note2: SD_wave must have even amount of points to enable padding option 1
            WFinModuleCount = 0;
            for (int j = 0; j < ypoints.Count; j++)
            {
                tmpWaveform = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, new double[] { ypoints[j], ypoints[j] });

                status = module.waveformLoad(tmpWaveform, WFinModuleCount, 1);
                if (status >= 0)
                {
                    WFinModuleCount++;
                }
                else
                {
                    return(1);
                }
            }

            for (int i = 0; i < xpoints.Count; i++)
            {
                tmpWaveform = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, new double[] { xpoints[i], xpoints[i] });

                status = module.waveformLoad(tmpWaveform, WFinModuleCount, 1);
                if (status >= 0)
                {
                    WFinModuleCount++;
                }
                else
                {
                    return(1);
                }
            }

            // WFinModuleCount is one more than total number of waveforms
            if (WFinModuleCount != ypoints.Count + xpoints.Count)
            {
                return(1);
            }

            // Queue the waveform into the channel queue
            for (int j = 0; j < ypoints.Count; j++)
            {
                for (int i = 0; i < xpoints.Count; i++)
                {
                    // Queue the waveform into the channel1 queue
                    status = module.AWGqueueWaveform(1, ypoints.Count + i, SD_TriggerModes.EXTTRIG, outputdelay, 1, 0); // cnannel1, waveform num, trigger (auto=0, ext=5), start delay, cycle, prescaleer
                    if (status >= 0)
                    {
                        c1WFinQueueCount++;
                    }
                    else
                    {
                        return(1);
                    }
                    // Queue the waveform into the channel2 queue
                    status = module.AWGqueueWaveform(2, j, SD_TriggerModes.EXTTRIG, outputdelay, 1, 0); // cnannel, waveform num, trigger (auto=0, ext=5), start delay, cycle, prescaleer
                    if (status >= 0)
                    {
                        c2WFinQueueCount++;
                    }
                    else
                    {
                        return(1);
                    }
                }
            }

            // check quequed waveform number
            if ((c1WFinQueueCount != c2WFinQueueCount) || (c1WFinQueueCount != ypoints.Count + xpoints.Count) || (c2WFinQueueCount != ypoints.Count + xpoints.Count))
            {
                return(1);
            }

            return(0);
        }
Beispiel #7
0
        private void buttonTestWaveformContinuous_Click(object sender, EventArgs e)
        {
            // Create a waveform object in PC RAM from waveform file
            SD_Wave wave = new SD_Wave("..\\..\\..\\..\\..\\..\\..\\Waveforms\\Triangular.csv");

            if (wave.getStatus() < 0)
            {
                printToConsole("Error opening waveform File");
                return;
            }
            int nWave = 0;

            // Switch off angle modulation and Amplitude modulation
            moduleAOU.modulationAngleConfig(nChannel, SD_ModulationTypes.AOU_MOD_OFF, 0);
            moduleAOU.modulationAmplitudeConfig(nChannel, SD_ModulationTypes.AOU_MOD_OFF, 0);

            // Erase all waveforms from module memory and load the waveform waveID in position nWave
            moduleAOU.waveformFlush();
            moduleAOU.waveformLoad(wave, nWave);

            // Config amplitude and setup AWG in nChannel
            moduleAOU.channelAmplitude(nChannel, 1.2);                                   // 1.2 Volts Peak
            moduleAOU.channelWaveShape(nChannel, SD_Waveshapes.AOU_AWG);

            // Flush channel waveform queue
            moduleAOU.AWGflush(nChannel);

            // Queue waveform nWave in nChannel
            moduleAOU.AWGqueueWaveform(nChannel, nWave, SD_TriggerModes.AUTOTRIG, 0, 0, 0);  // Cycles = 0

            printToConsole("Module configuration successfull. Press CONTINUE to start the AWG");
            runPause();

            moduleAOU.AWGstart(nChannel);

            printToConsole("AWG started. Press CONTINUE to pause the AWG.");
            runPause();

            moduleAOU.AWGpause(nChannel);

            printToConsole("AWG paused. Press CONTINUE to resume the AWG.");
            runPause();

            moduleAOU.AWGresume(nChannel);

            printToConsole("AWG resumed. Press CONTINUE to stop the AWG.");
            runPause();

            moduleAOU.AWGstop(nChannel);

            printToConsole("AWG stopped. Press CONTINUE to start the AWG.");
            runPause();

            moduleAOU.AWGstart(nChannel);

            printToConsole("AWG started. Press CONTINUE to stop the AWG.");
            runPause();

            moduleAOU.AWGstop(nChannel);

            printToConsole("AWG Stopped. Press CONTINUE to finish.");
            runPause();
        }
Beispiel #8
0
        private void buttonTestMultipleWaveforms_Click(object sender, EventArgs e)
        {
            clearConsole();

            int nWave1 = 0;
            int nWave2 = 1;

            // Create a waveform object in PC RAM from waveform file
            SD_Wave wave1 = new SD_Wave("..\\..\\..\\..\\..\\..\\..\\Waveforms\\Triangular.csv");
            SD_Wave wave2 = new SD_Wave("..\\..\\..\\..\\..\\..\\..\\Waveforms\\Gaussian.csv");

            if (wave1.getStatus() < 0 || wave2.getStatus() < 0)
            {
                printToConsole("Error opening waveform File");
                return;
            }

            // Erase all waveforms from module memory and load waveforms waveId1 and waveId2 in positions nWave1 and nWave2
            moduleAOU.waveformFlush();
            moduleAOU.waveformLoad(wave1, nWave1);
            moduleAOU.waveformLoad(wave2, nWave2);

            // Turn off nChannel
            moduleAOU.channelWaveShape(nChannel, SD_Waveshapes.AOU_OFF);

            // Switch off angle modulation and Amplitude modulation
            moduleAOU.modulationAngleConfig(nChannel, SD_ModulationTypes.AOU_MOD_OFF, 0);
            moduleAOU.modulationAmplitudeConfig(nChannel, SD_ModulationTypes.AOU_MOD_OFF, 0);

            // Config amplitude and setup AWG in nChannel
            moduleAOU.channelAmplitude(nChannel, 1.2);                  // 1.2 Volts Peak
            moduleAOU.channelWaveShape(nChannel, SD_Waveshapes.AOU_AWG);

            // Flush channel waveform queue
            moduleAOU.AWGflush(nChannel);

            // Queue waveforms nWave1 and nWave2 in nChannel
            moduleAOU.AWGqueueWaveform(nChannel, nWave1, SD_TriggerModes.AUTOTRIG, 0, 1, 0);
            moduleAOU.AWGqueueWaveform(nChannel, nWave2, SD_TriggerModes.AUTOTRIG, 0, 2, 0);

            printToConsole("Module configuration successfull. Press CONTINUE to start the AWG");
            runPause();

            moduleAOU.AWGstart(nChannel);

            printToConsole("AWG started. Press CONTINUE to stop the AWG.");
            runPause();

            moduleAOU.AWGstop(nChannel);

            printToConsole("AWG Stopped. Press CONTINUE to start the AWG.");
            runPause();

            moduleAOU.AWGstart(nChannel);

            printToConsole("AWG started. Press CONTINUE to restart the AWG.");
            runPause();

            moduleAOU.AWGstart(nChannel);

            printToConsole("AWG started. Press CONTINUE to stop the AWG.");
            runPause();

            moduleAOU.AWGstop(nChannel);

            printToConsole("AWG Stopped. Press CONTINUE to finish.");
            runPause();
        }
Beispiel #9
0
        private void buttonTestWaveformTrigger_Click(object sender, EventArgs e)
        {
            clearConsole();

            // Create a waveform object in PC RAM from waveform file
            SD_Wave wave1 = new SD_Wave("..\\..\\..\\..\\..\\..\\..\\Waveforms\\Triangular.csv");
            SD_Wave wave2 = new SD_Wave("..\\..\\..\\..\\..\\..\\..\\Waveforms\\Gaussian.csv");

            if (wave1.getStatus() < 0 || wave2.getStatus() < 0)
            {
                printToConsole("Error opening waveform File");
                return;
            }

            int nWave1 = 0;
            int nWave2 = 1;

            // Erase all waveforms from module memory and load waveforms waveId1 and waveId2 in position nWave1 and nWave2
            moduleAOU.waveformFlush();
            moduleAOU.waveformLoad(wave1, nWave1);
            moduleAOU.waveformLoad(wave2, nWave2);

            // Turn off nChannel
            moduleAOU.channelWaveShape(nChannel, SD_Waveshapes.AOU_OFF);

            // Switch off angle modulation and Amplitude modulation
            moduleAOU.modulationAngleConfig(nChannel, SD_ModulationTypes.AOU_MOD_OFF, 0);
            moduleAOU.modulationAmplitudeConfig(nChannel, SD_ModulationTypes.AOU_MOD_OFF, 0);

            // Config amplitude and setup AWG in nChannel
            moduleAOU.channelAmplitude(nChannel, 1.2);                           // 1.2 Volts Peak
            moduleAOU.channelWaveShape(nChannel, SD_Waveshapes.AOU_AWG);

            // Set external trigger as input
            moduleAOU.triggerIOdirection(SD_TriggerDirections.AOU_TRG_IN);

            // Config trigger as external trigger and rising edge
            moduleAOU.AWGtriggerExternalConfig(nChannel, SD_TriggerExternalSources.TRIGGER_EXTERN, SD_TriggerBehaivors.TRIGGER_RISE);

            // Flush channel waveform queue
            moduleAOU.AWGflush(nChannel);

            // Queue waveform nWave1 with VI/HVI trigger and delay of 50ns from the trigger
            moduleAOU.AWGqueueWaveform(nChannel, nWave1, SD_TriggerModes.VIHVITRIG, 50, 1, 0);

            // Queue waveform nWave1 with external trigger and delay of 100ns from the trigger
            moduleAOU.AWGqueueWaveform(nChannel, nWave1, SD_TriggerModes.EXTTRIG, 100, 1, 0);

            // Queue waveforms nWave1 and nWave2 with differents trigger and delay of 200ns from the trigger and between them
            moduleAOU.AWGqueueWaveform(nChannel, nWave2, SD_TriggerModes.EXTTRIG, 200, 1, 0);
            moduleAOU.AWGqueueWaveform(nChannel, nWave1, SD_TriggerModes.AUTOTRIG, 280, 1, 0);

            printToConsole("External trigger configurated.\nModule configuration successfull, Press CONTINUE to start the AWG");
            runPause();

            moduleAOU.AWGstart(nChannel);

            printToConsole("AWG started. Waiting for the triggers. Press CONTINUE to send a VI/HVI trigger.");
            runPause();

            moduleAOU.AWGtrigger(nChannel);

            printToConsole("Waiting for two external triggers. Press CONTINUE to stop the AWG.");
            runPause();

            moduleAOU.AWGstop(nChannel);

            printToConsole("AWG Stopped. Test Finished.");
        }
Beispiel #10
0
        public HW_STATUS_RETURNS ScanControlInitialize(double x_amp, double y_amp, double[] Xarray_vol, double[] Yarray_vol, int[] Xarray_index, int[] Yarray_index, double delay, int recording_rate, int Option2D, int Nmultiframes)
        {
            int status;
            // Channel 1 for y scan and channel 2 for x scan

            //Create an instance of the AOU module
            SD_AOU moduleAOU  = new SD_AOU();
            string ModuleName = "M3201A";
            int    nChassis   = 1;
            int    nSlot      = 7;
            int    modelID;

            if ((modelID = moduleAOU.open(ModuleName, nChassis, nSlot)) < 0)
            {
                System.Windows.Forms.MessageBox.Show("The scan system is not successfully initialized. Restart the control box and then resstart computer. If still not solved, talk to Jingrui.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                Console.WriteLine("Error openning the Module 'M3201A', make sure the slot and chassis are correct. Aborting...");
                Console.ReadKey();

                return(HW_STATUS_RETURNS.HW_SUCCESS);
            }

            // Determine prescaling factor and number of samples per step to use
            // according to Benjamin Bammels suggestion, use 5% to 10% longer frame time on AWG compared to DE frame integration time

            int nSamples;
            int Prescaling;

            nSamples   = (int)Math.Ceiling(1e8 / recording_rate / 4095);
            nSamples   = (nSamples / 5) * 5;
            Prescaling = (int)Math.Ceiling(1e8 / recording_rate / nSamples);
            while (Prescaling > 1.02e8 / recording_rate / nSamples || nSamples == 0 || Prescaling > 4095)
            {
                nSamples   = nSamples + 5;
                Prescaling = (int)Math.Ceiling(1e8 / recording_rate / nSamples);
            }

            int TriggerDelay;

            TriggerDelay = (int)Math.Floor((1e-8 * Prescaling * nSamples - 1 / recording_rate) * 1e9);    // difference between scan cycle and camera integration time in ns
            if (TriggerDelay > 25000)
            {
                TriggerDelay = 25000 / 10;
            }
            else
            {
                TriggerDelay = TriggerDelay / 10;
            }

            // For global shutter mode, set trigger signal delay to 10000, move beam when reading data

            // 4/28/2021 check with chenyu about trigger delay time Benjamin suggested: 203.8us so  the value here should be 20380
            // from timing for DE-16 global shutter modes with high gain, no CDS

            // 6/1/2021 the delay time of global offchip CDS mode 123 is 526.2, 144.6, 45.3 us
            TriggerDelay = 0;  // Maximum is 65535 according to Keysight

            Console.WriteLine("Precaling factor " + Prescaling + " will be used with " + nSamples + " for each beam position.");
            Console.WriteLine("Trigger delay by " + TriggerDelay * 10 + " ns from beam position movement.");

            // Config amplitude and setup AWG in channels 1 and 2, 3, 4
            moduleAOU.channelAmplitude(1, x_amp);
            moduleAOU.channelWaveShape(1, SD_Waveshapes.AOU_AWG);
            moduleAOU.channelAmplitude(2, y_amp);
            moduleAOU.channelWaveShape(2, SD_Waveshapes.AOU_AWG);
            moduleAOU.channelAmplitude(3, 0.5);
            moduleAOU.channelWaveShape(3, SD_Waveshapes.AOU_AWG);
            moduleAOU.channelAmplitude(4, 0.25); // 0.5 get to ~8-9v edge,
            moduleAOU.channelWaveShape(4, SD_Waveshapes.AOU_AWG);
            moduleAOU.waveformFlush();

            // Convert array into list

            xpoints = new List <double>();
            ypoints = new List <double>();
            xindex  = new List <int>();
            yindex  = new List <int>();

            xpoints.Clear();
            ypoints.Clear();
            xindex.Clear();
            yindex.Clear();

            xpoints = Xarray_vol.ToList();
            ypoints = Yarray_vol.ToList();
            xindex  = Xarray_index.ToList();
            yindex  = Yarray_index.ToList();

            status = moduleAOU.AWGflush(1);
            Console.WriteLine("Status for channel 1 " + status);
            status = moduleAOU.AWGflush(2);
            Console.WriteLine("Status for channel 2 " + status);
            status = moduleAOU.AWGflush(3);
            Console.WriteLine("Status for channel 3 " + status);
            status = moduleAOU.AWGflush(4);
            Console.WriteLine("Status for channel 4 " + status);



            #region X scan generation

            // Generate and queue waveform for X channel on waveform #0 (channel 2)
            var Waveform_X = new double[nSamples * xindex.Count()];
            int Count      = 0;
            // create double array for each x cycle
            for (int ix = 0; ix < xindex.Count; ix++)
            {
                for (int i = 0; i < nSamples; i++)
                {
                    Waveform_X[Count] = xpoints[xindex[xindex.Count - ix - 1]];
                    Count++;
                    //if (Count == nSamples * xindex.Count())
                    //{
                    //    break;  // End waveform generation when the waveform is full
                    //}
                }
                //if (Count == nSamples * xindex.Count())
                //{
                //    break;  // Also break the outer loop, in case the delay length is more than one beam position
                //}
            }

            //Check the size of waveform_x array
            int length_x;
            length_x = Waveform_X.Length;
            Console.WriteLine("Array length of X waveform points is" + length_x);

            #endregion

            #region Y scan generation

            //Set spectial nSamplesY and prescalingY because its variation frequency is much lower.
            int nSamplesY;
            int PrescalingY;

            nSamplesY   = (int)Math.Ceiling(1.05e8 / recording_rate * xindex.Count() / 4095);
            nSamplesY   = (nSamplesY / 5) * 5;
            PrescalingY = (int)Math.Ceiling(1.05e8 / recording_rate * xindex.Count() / nSamplesY);
            while (PrescalingY > 1.10e8 / (recording_rate / xindex.Count()) / nSamplesY || nSamplesY == 1 || TriggerDelay % (10 * PrescalingY) > 1)
            {
                nSamplesY   = nSamplesY + 5;
                PrescalingY = (int)Math.Ceiling(1.05e8 / (recording_rate / xindex.Count()) / nSamplesY);
            }

            nSamplesY = (int)Math.Ceiling((double)nSamplesY / xindex.Count()); // get back the nSamples for each position
            Console.WriteLine("Precaling factor for y scan" + PrescalingY + " will be used with " + nSamplesY + " for each beam position.");


            // Generate and queue waveform for Y channel on waveform #1 (channel 1)
            //
            var Waveform_Y = new double[nSamples * xindex.Count() * yindex.Count()];
            Count = 0;
            for (int iy = 0; iy < yindex.Count(); iy++)
            {
                for (int ix = 0; ix < xindex.Count(); ix++)
                {
                    for (int i = 0; i < nSamples; i++)
                    {
                        Waveform_Y[Count] = ypoints[yindex[yindex.Count - iy - 1]];
                        Count++;
                        //if (Count == nSamplesY * xindex.Count() * yindex.Count())
                        //{
                        //   break;  // End waveform generation when the waveform is full
                        //}
                    }
                    //if (Count == nSamplesY * xindex.Count() * yindex.Count())
                    //{
                    //    break;  // Also break outer loop
                    //}
                }
                //if (Count == nSamplesY * xindex.Count() * yindex.Count())
                //{
                //    break;  // Break outmost loop
                //}
            }

            //Check the size of waveform_y array
            int length_y;
            length_y = Waveform_Y.Length;
            Console.WriteLine("Array length of Y waveform points is" + length_y);

            #endregion

            #region generate DE trigger

            // Generate and queue waveform for DE trigger on wavefrom #2 (channel 3), same size and reps as x array
            var Waveform_DE = new double[nSamples * xindex.Count()];
            for (int ix = 0; ix < xindex.Count; ix++)
            {
                Waveform_DE[ix * nSamples] = -1;
            }

            int length_DE;
            length_DE = Waveform_DE.Length;

            #endregion

            #region generate digitizer trigger

            // Generate and queue waveform for digitizer trigger on waveform #3 (channel 4)
            // trigger signal same size as x array, run only once

            var Waveform_DIGI = new double[nSamples * xindex.Count()];
            for (int ix = 0; ix < nSamples; ix++)
            {
                Waveform_DIGI[ix] = -1; // set first nSamples points to -1 to create an single trigger
            }
            int length_DIGI;
            length_DIGI = Waveform_DIGI.Length;

            #endregion


            #region Check wave_array sized and load all the four waveforms

            double memorySizeMB = (length_x + length_y + length_DE + length_DIGI) * 8e-6;
            if (memorySizeMB < 2000)
            {
                Console.WriteLine("The total memory size of the four waveform_array is" + memorySizeMB + " MB");
            }
            else
            {
                Console.WriteLine("The total memory size of the four waveform_array is" + memorySizeMB + " MB");
                System.Windows.Forms.MessageBox.Show("Your settings exceed RAM Limitation! ", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(HW_STATUS_RETURNS.HW_OTHER);
            }

            //** X scan **//
            var SD_Waveform_X = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, Waveform_X);

            // load generated SD_wave to waveform #0
            status = moduleAOU.waveformLoad(SD_Waveform_X, 0, 1);       // padding option 1 is used to maintain ending voltage after each WaveForm
            if (status < 0)
            {
                Console.WriteLine("Error while loading x waveform");
            }
            //Console.WriteLine("X waveform size " + (double)moduleAOU.waveformGetMemorySize(0)/1000000 + " MB");

            // queue waveform into channel 1 and loop for yindex.count() times
            status = moduleAOU.AWGqueueWaveform(1, 0, SD_TriggerModes.AUTOTRIG, TriggerDelay, yindex.Count() * Nmultiframes, Prescaling); // triggerdelay in tens of ns

            if (status < 0)
            {
                Console.WriteLine("Error while queuing x waveform");
            }


            //** Y scan **//
            var SD_Waveform_Y = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, Waveform_Y);
            status = moduleAOU.waveformLoad(SD_Waveform_Y, 1, 1);       // padding option 1 is used to maintain ending voltage after each WaveForm

            if (status < 0)
            {
                Console.WriteLine("Error while loading x waveform");
            }
            //Console.WriteLine("Y waveform size " + (double)moduleAOU.waveformGetMemorySize(1)/1000000 + " MB");


            // queue waveform into channel 2 and run once
            status = moduleAOU.AWGqueueWaveform(2, 1, SD_TriggerModes.AUTOTRIG, TriggerDelay, Nmultiframes, Prescaling);

            if (status < 0)
            {
                Console.WriteLine("Error while queuing y waveform");
            }

            //** DE camera scan **//
            int Delay_DE       = 0;
            var SD_Waveform_DE = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, Waveform_DE);
            status = moduleAOU.waveformLoad(SD_Waveform_DE, 2, 1);       // padding option 1 is used to maintain ending voltage after each WaveForm

            if (status < 0)
            {
                Console.WriteLine("Error while loading DE waveform");
            }

            status = moduleAOU.AWGqueueWaveform(3, 2, SD_TriggerModes.AUTOTRIG, Delay_DE, yindex.Count() * Nmultiframes, Prescaling);
            //Console.WriteLine("Trigger waveform size " + (double)moduleAOU.waveformGetMemorySize(2)/1000000 + " MB");

            if (status < 0)
            {
                Console.WriteLine("Error while queuing camera trigger, error code " + status);
            }

            //** Digitizer camera scan **//
            int Delay_DIGI       = 0;
            var SD_Waveform_DIGI = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, Waveform_DIGI);
            status = moduleAOU.waveformLoad(SD_Waveform_DIGI, 3, 1);       // padding option 1 is used to maintain ending voltage after each WaveForm

            if (status < 0)
            {
                Console.WriteLine("Error while loading DIGI waveform");
            }

            status = moduleAOU.AWGqueueWaveform(4, 3, SD_TriggerModes.AUTOTRIG, Delay_DIGI, 1, Prescaling); // No cycle cz recordsize added.
            //Console.WriteLine("Trigger waveform size " + (double)moduleAOU.waveformGetMemorySize(3)/1000000 + " MB");

            if (status < 0)
            {
                Console.WriteLine("Error while queuing digitizer trigger, error code " + status);
            }
            #endregion


            // Configure all channels to single shot, X and trigger will automatically stop after certain amount of cycles
            moduleAOU.AWGqueueConfig(1, 0);
            moduleAOU.AWGqueueConfig(2, 0);
            moduleAOU.AWGqueueConfig(3, 0);
            moduleAOU.AWGqueueConfig(4, 0);

            // Start both channel and wait for triggers, start channel 0,1,2: 00000111 = 7; start channel 0,1,2,3: 00001111 = 15
            System.Threading.Thread.Sleep(1000);
            if (Option2D == 0)
            {
                moduleAOU.AWGstartMultiple(15);
            }
            else
            {
                moduleAOU.AWGstartMultiple(11); // don't start channel 3 for DE trigger if doing 2D scan mode
            }
            //moduleAOU.AWGstartMultiple(3);

            //// Flush channels and delete waveform onboard when type esc
            //if (Console.KeyAvailable)
            //{
            //    ConsoleKeyInfo cki = Console.ReadKey(false);
            //    if (cki.Key == ConsoleKey.Escape)
            //    {
            //        moduleAOU.waveformFlush();
            //        moduleAOU.AWGstop(1);
            //        moduleAOU.AWGstop(2);
            //        moduleAOU.AWGstop(3);
            //        moduleAOU.AWGstop(4);
            //        moduleAOU.close();
            //        Console.WriteLine("AWG stopped and module closed.");
            //    }
            //}

            if ((status = moduleAOU.close()) < 0)
            {
                Console.WriteLine("Error closing the Module 'M3201A'");
                //Console.ReadKey();

                return(HW_STATUS_RETURNS.HW_SUCCESS);
            }



            return(HW_STATUS_RETURNS.HW_SUCCESS);
        }
        public HW_STATUS_RETURNS ScanControlInitialize(double x_amp, double y_amp, double[] Xarray_vol, double[] Yarray_vol, int[] Xarray_index, int[] Yarray_index, double delay, int recording_rate, int Option2D)
        {
            int status;
            // Channel 1 for y scan and channel 2 for x scan

            //Create an instance of the AOU module
            SD_AOU moduleAOU  = new SD_AOU();
            string ModuleName = "M3201A";
            int    nChassis   = 1;
            int    nSlot      = 7;

            if ((status = moduleAOU.open(ModuleName, nChassis, nSlot)) < 0)
            {
                Console.WriteLine("Error openning the Module 'M3201A', make sure the slot and chassis are correct. Aborting...");
                Console.ReadKey();

                return(HW_STATUS_RETURNS.HW_SUCCESS);
            }

            // Determine prescaling factor and number of samples per step to use
            // according to Benjamin Bammels suggestion, use 5% to 10% longer frame time on AWG compared to DE frame integration time

            int nSamples;
            int Prescaling;

            nSamples   = (int)Math.Ceiling(1.05e8 / recording_rate / 4095);
            Prescaling = (int)Math.Ceiling(1.05e8 / recording_rate / nSamples);
            while (Prescaling > 1.10e8 / recording_rate / nSamples || nSamples == 1)
            {
                nSamples++;
                Prescaling = (int)Math.Ceiling(1.05e8 / recording_rate / nSamples);
            }

            int TriggerDelay;

            TriggerDelay = (int)Math.Floor((1e-8 * Prescaling * nSamples - 1 / recording_rate) * 1e9);    // difference between scan cycle and camera integration time in ns
            if (TriggerDelay > 25000)
            {
                TriggerDelay = 25000 / 10;
            }
            else
            {
                TriggerDelay = TriggerDelay / 10;
            }

            // For global shutter mode, set trigger signal delay to zero
            TriggerDelay = 0;

            Console.WriteLine("Precaling factor " + Prescaling + " will be used with " + nSamples + " for each beam position.");
            Console.WriteLine("Trigger delay by " + TriggerDelay * 10 + " ns from beam position movement.");

            // Config amplitude and setup AWG in channels 1 and 2,
            moduleAOU.channelAmplitude(1, y_amp);
            moduleAOU.channelWaveShape(1, SD_Waveshapes.AOU_AWG);
            moduleAOU.channelAmplitude(2, x_amp);
            moduleAOU.channelWaveShape(2, SD_Waveshapes.AOU_AWG);
            moduleAOU.channelAmplitude(3, 0.5);
            moduleAOU.channelWaveShape(3, SD_Waveshapes.AOU_AWG);
            moduleAOU.channelAmplitude(4, 0.5);
            moduleAOU.channelWaveShape(4, SD_Waveshapes.AOU_AWG);
            moduleAOU.waveformFlush();

            // Convert array into list

            xpoints = new List <double>();
            ypoints = new List <double>();
            xindex  = new List <int>();
            yindex  = new List <int>();

            xpoints.Clear();
            ypoints.Clear();
            xindex.Clear();
            yindex.Clear();

            xpoints = Xarray_vol.ToList();
            ypoints = Yarray_vol.ToList();
            xindex  = Xarray_index.ToList();
            yindex  = Yarray_index.ToList();

            status = moduleAOU.AWGflush(1);
            Console.WriteLine("Status for channel 1 " + status);
            status = moduleAOU.AWGflush(2);
            Console.WriteLine("Status for channel 2 " + status);
            status = moduleAOU.AWGflush(3);
            Console.WriteLine("Status for channel 3 " + status);
            status = moduleAOU.AWGflush(4);
            Console.WriteLine("Status for channel 4 " + status);



            #region X scan generation

            // Generate and queue waveform for X channel on waveform #0 (channel 2)

            var Waveform_X = new double[nSamples * xindex.Count()];
            int Count      = 0;
            // create double array for each x cycle
            for (int ix = 0; ix < xindex.Count; ix++)
            {
                for (int i = 0; i < nSamples; i++)
                {
                    Waveform_X[Count] = xpoints[xindex[xindex.Count - ix - 1]];
                    Count++;
                }
            }
            // generate SD_wave from array
            var SD_Waveform_X = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, Waveform_X);

            // load generated SD_wave to waveform #0
            status = moduleAOU.waveformLoad(SD_Waveform_X, 0, 1);       // padding option 1 is used to maintain ending voltage after each WaveForm
            if (status < 0)
            {
                Console.WriteLine("Error while loading x waveform");
            }
            Console.WriteLine("X waveform size " + (double)moduleAOU.waveformGetMemorySize(0) / 1000000 + " MB");

            // queue waveform into channel 2 and loop for yindex.count() times
            status = moduleAOU.AWGqueueWaveform(1, 0, SD_TriggerModes.AUTOTRIG, TriggerDelay, yindex.Count(), Prescaling);

            if (status < 0)
            {
                Console.WriteLine("Error while queuing x waveform");
            }

            #endregion

            #region Y scan generation

            // Generate and queue waveform for Y channel on waveform #1 (channel 1)

            var Waveform_Y = new double[nSamples * xindex.Count() * yindex.Count()];
            Count = 0;
            for (int iy = 0; iy < yindex.Count(); iy++)
            {
                for (int ix = 0; ix < xindex.Count(); ix++)
                {
                    for (int i = 0; i < nSamples; i++)
                    {
                        Waveform_Y[Count] = ypoints[yindex[yindex.Count - iy - 1]];
                        Count++;
                    }
                }
            }
            var SD_Waveform_Y = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, Waveform_Y);
            status = moduleAOU.waveformLoad(SD_Waveform_Y, 1, 1);       // padding option 1 is used to maintain ending voltage after each WaveForm

            if (status < 0)
            {
                Console.WriteLine("Error while loading y waveform");
            }
            Console.WriteLine("Y waveform size " + (double)moduleAOU.waveformGetMemorySize(1) / 1000000 + " MB");


            // queue waveform into channel 1 and run once
            status = moduleAOU.AWGqueueWaveform(2, 1, SD_TriggerModes.AUTOTRIG, TriggerDelay, 1, Prescaling);

            if (status < 0)
            {
                Console.WriteLine("Error while queuing y waveform");
            }

            #endregion

            #region generate DE trigger

            // Generate and queue waveform for DE trigger on wavefrom #2 (channel 3), same size and reps as x array

            var Waveform_DE = new double[nSamples * xindex.Count()];
            for (int ix = 0; ix < xindex.Count; ix++)
            {
                Waveform_DE[ix * nSamples] = -1;
            }
            var SD_Waveform_DE = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, Waveform_DE);
            status = moduleAOU.waveformLoad(SD_Waveform_DE, 2, 1);       // padding option 1 is used to maintain ending voltage after each WaveForm

            if (status < 0)
            {
                Console.WriteLine("Error while loading x waveform");
            }

            status = moduleAOU.AWGqueueWaveform(3, 2, SD_TriggerModes.AUTOTRIG, 0, yindex.Count(), Prescaling);
            Console.WriteLine("Trigger waveform size " + (double)moduleAOU.waveformGetMemorySize(2) / 1000000 + " MB");

            if (status < 0)
            {
                Console.WriteLine("Error while queuing camera trigger, error code " + status);
            }

            #endregion

            #region generate digitizer trigger

            // Generate and queue waveform for digitizer trigger on waveform #3 (channel 4)
            // trigger signal same size as x array, run only once

            var Waveform_DIGI = new double[nSamples * xindex.Count()];
            for (int ix = 0; ix < nSamples; ix++)
            {
                Waveform_DIGI[ix] = -1; // set first nSamples points to -1 to create on single trigger
            }
            var SD_Waveform_DIGI = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, Waveform_DIGI);
            status = moduleAOU.waveformLoad(SD_Waveform_DIGI, 3, 1);       // padding option 1 is used to maintain ending voltage after each WaveForm

            if (status < 0)
            {
                Console.WriteLine("Error while loading x waveform");
            }

            status = moduleAOU.AWGqueueWaveform(4, 3, SD_TriggerModes.AUTOTRIG, 0, 1, Prescaling);
            Console.WriteLine("Trigger waveform size " + (double)moduleAOU.waveformGetMemorySize(3) / 1000000 + " MB");

            if (status < 0)
            {
                Console.WriteLine("Error while queuing digitizer trigger, error code " + status);
            }

            #endregion

            // Configure all channels to single shot, X and trigger will automatically stop after certain amount of cycles
            moduleAOU.AWGqueueConfig(1, 0);
            moduleAOU.AWGqueueConfig(2, 0);
            moduleAOU.AWGqueueConfig(3, 0); // Should also be 0 here?
            moduleAOU.AWGqueueConfig(4, 0);

            // Start both channel and wait for triggers, start channel 0,1,2: 00000111 = 7; start channel 0,1,2,3: 00001111 = 15
            System.Threading.Thread.Sleep(1000);
            if (Option2D == 0)
            {
                moduleAOU.AWGstartMultiple(15);
            }
            else
            {
                moduleAOU.AWGstartMultiple(11); // don't start channel 3 for DE trigger if doing 2D scan mode
            }
            //moduleAOU.AWGstartMultiple(3);


            return(HW_STATUS_RETURNS.HW_SUCCESS);
        }
Beispiel #12
0
        public HW_STATUS_RETURNS ScanControlInitialize(double x_amp, double y_amp, double[] Xarray_vol, double[] Yarray_vol, int[] Xarray_index, int[] Yarray_index, double delay)
        {
            int status;
            // Channel 1 for y scan and channel 2 for x scan

            //Create an instance of the AOU module
            SD_AOU moduleAOU  = new SD_AOU();
            string ModuleName = "M3201A";
            int    nChassis   = 1;
            int    nSlot      = 3;

            if ((status = moduleAOU.open(ModuleName, nChassis, nSlot)) < 0)
            {
                Console.WriteLine("Error openning the Module 'M3201A', make sure the slot and chassis are correct. Aborting...");
                Console.ReadKey();

                return(HW_STATUS_RETURNS.HW_SUCCESS);
            }

            // Config amplitude and setup AWG in channels 1 and 2,
            moduleAOU.channelAmplitude(1, y_amp);
            moduleAOU.channelWaveShape(1, SD_Waveshapes.AOU_AWG);
            moduleAOU.channelAmplitude(2, x_amp);
            moduleAOU.channelWaveShape(2, SD_Waveshapes.AOU_AWG);
            moduleAOU.waveformFlush();

            // Convert array into list

            xpoints = new List <double>();
            ypoints = new List <double>();
            xindex  = new List <int>();
            yindex  = new List <int>();

            xpoints.Clear();
            ypoints.Clear();
            xindex.Clear();
            yindex.Clear();
            xpoints = Xarray_vol.ToList();
            ypoints = Yarray_vol.ToList();
            xindex  = Xarray_index.ToList();
            yindex  = Yarray_index.ToList();

            // Set external trigger as input
            moduleAOU.triggerIOdirection(SD_TriggerDirections.AOU_TRG_IN);
            // Config trigger as external trigger and rising edge
            moduleAOU.AWGtriggerExternalConfig(1, SD_TriggerExternalSources.TRIGGER_EXTERN, SD_TriggerBehaviors.TRIGGER_RISE);
            moduleAOU.AWGtriggerExternalConfig(2, SD_TriggerExternalSources.TRIGGER_EXTERN, SD_TriggerBehaviors.TRIGGER_RISE);
            // flush both channels
            status = moduleAOU.AWGflush(1);
            status = moduleAOU.AWGflush(2);


            int WFinModuleCount;


            // load waveform for channel 2 (X)
            for (WFinModuleCount = 0; WFinModuleCount < xpoints.Count; WFinModuleCount++)
            {
                // with 16 reps when generate wave form, AWG generates the desired scan pattern, not sure why
                var tmpWaveform_X = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, new double[] { xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount] }); // WaveForm has to contain even number of points to activate padding option 1
                status = moduleAOU.waveformLoad(tmpWaveform_X, WFinModuleCount, 1);                                                                                                                                                                                                                                                                                                                                                                                                                                             // padding option 1 is used to maintain ending voltage after each WaveForm
                if (status < 0)
                {
                    Console.WriteLine("Error while loading " + WFinModuleCount + " point from x array");
                }
            }
            for (WFinModuleCount = 0; WFinModuleCount < xindex.Count; WFinModuleCount++)
            {
                status = moduleAOU.AWGqueueWaveform(2, xindex[WFinModuleCount], SD_TriggerModes.EXTTRIG, 0, 1, 0);// AWG, waveform#, trigger, delay, cycle,prescaler
                if (status < 0)
                {
                    Console.WriteLine("Error while queuing " + WFinModuleCount + " point from x array");
                }

                /*if (WFinModuleCount > 1023)
                 * {
                 *  Console.WriteLine(xindex[WFinModuleCount] + " Status: " + status + "\n");
                 * }*/
            }

            // load waveform for channel 1 (Y)

            for (WFinModuleCount = 0; WFinModuleCount < ypoints.Count; WFinModuleCount++)
            {
                var tmpWaveform_Y = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, new double[] { ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount] }); // WaveForm has to contain even number of points to activate padding option 1
                status = moduleAOU.waveformLoad(tmpWaveform_Y, WFinModuleCount, 1);                                                                                                                                                                                                                                                                                                                                                                                                                                             // padding option 1 is used to maintain ending voltage after each WaveForm
                if (status < 0)
                {
                    Console.WriteLine("Error while loading " + WFinModuleCount + " point from y array, error code " + status);
                }
            }
            // queue waveform for channel 1
            for (WFinModuleCount = 0; WFinModuleCount < yindex.Count; WFinModuleCount++)
            {
                status = moduleAOU.AWGqueueWaveform(1, yindex[WFinModuleCount], SD_TriggerModes.EXTTRIG, 0, 1, 0);// AWG, waveform#, trigger, delay, cycle,prescaler
                if (status < 0)
                {
                    Console.WriteLine("Error while queuing " + WFinModuleCount + " point from y array, error code " + status);
                }
            }


            // Configure queue to only one shot
            moduleAOU.AWGqueueConfig(1, 0);
            moduleAOU.AWGqueueConfig(2, 0);

            // Start both channel and wait for triggers
            moduleAOU.AWGstart(1);
            moduleAOU.AWGstart(2);

            /*while (moduleAOU.AWGisRunning(1)==1)
             * {
             *  Console.WriteLine(moduleAOU.AWGnWFplaying(1));
             *  Thread.Sleep(10);
             * }*/

            return(HW_STATUS_RETURNS.HW_SUCCESS);
        }
        public HW_STATUS_RETURNS ScanControlInitialize(double x_amp, double y_amp, double[] Xarray_vol, double[] Yarray_vol, int[] Xarray_index, int[] Yarray_index, double delay, int recording_rate)
        {
            int    status;
            string sent;
            // Channel 1 for y scan and channel 2 for x scan

            //Create an instance of the AOU module
            SD_AOU moduleAOU  = new SD_AOU();
            string ModuleName = "M3201A";
            int    nChassis   = 1;
            int    nSlot      = 3;

            if ((status = moduleAOU.open(ModuleName, nChassis, nSlot)) < 0)
            {
                Console.WriteLine("Error openning the Module 'M3201A', make sure the slot and chassis are correct. Aborting...");
                Console.ReadKey();

                return(HW_STATUS_RETURNS.HW_SUCCESS);
            }

            // Config amplitude and setup AWG in channels 1 and 2,
            moduleAOU.channelAmplitude(1, y_amp);
            moduleAOU.channelWaveShape(1, SD_Waveshapes.AOU_AWG);
            moduleAOU.channelAmplitude(2, x_amp);
            moduleAOU.channelWaveShape(2, SD_Waveshapes.AOU_AWG);
            moduleAOU.waveformFlush();

            // Convert array into list

            xpoints = new List <double>();
            ypoints = new List <double>();
            xindex  = new List <int>();
            yindex  = new List <int>();

            xpoints.Clear();
            ypoints.Clear();
            xindex.Clear();
            yindex.Clear();
            xpoints = Xarray_vol.ToList();
            ypoints = Yarray_vol.ToList();
            xindex  = Xarray_index.ToList();
            yindex  = Yarray_index.ToList();

            // Set external trigger as input
            moduleAOU.triggerIOdirection(SD_TriggerDirections.AOU_TRG_IN);
            // Config trigger as external trigger and rising edge
            //moduleAOU.AWGtriggerExternalConfig(1, SD_TriggerExternalSources.TRIGGER_PXI, SD_TriggerBehaviors.TRIGGER_RISE);
            moduleAOU.AWGtriggerExternalConfig(2, SD_TriggerExternalSources.TRIGGER_EXTERN, SD_TriggerBehaviors.TRIGGER_RISE);
            // flush both channels
            status = moduleAOU.AWGflush(1);
            status = moduleAOU.AWGflush(2);


            int WFinModuleCount;


            // load waveform for channel 2 (X)
            for (WFinModuleCount = 0; WFinModuleCount < xpoints.Count; WFinModuleCount++)
            {
                // with 16 reps when generate wave form, AWG generates the desired scan pattern, not sure why
                var tmpWaveform_X = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, new double[] { xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount], xpoints[WFinModuleCount] }); // WaveForm has to contain even number of points to activate padding option 1
                status = moduleAOU.waveformLoad(tmpWaveform_X, WFinModuleCount, 1);                                                                                                                                                                                                                                                                                                                                                                                                                                             // padding option 1 is used to maintain ending voltage after each WaveForm
                if (status < 0)
                {
                    Console.WriteLine("Error while loading " + WFinModuleCount + " point from x array");
                }
            }
            for (WFinModuleCount = 0; WFinModuleCount < xindex.Count; WFinModuleCount++)
            {
                status = moduleAOU.AWGqueueWaveform(2, xindex[WFinModuleCount], SD_TriggerModes.EXTTRIG, 0, 1, 0);// AWG, waveform#, trigger, delay, cycle,prescaler
                if (status < 0)
                {
                    Console.WriteLine("Error while queuing " + WFinModuleCount + " point from x array");
                }

                /*if (WFinModuleCount > 1023)
                 * {
                 *  Console.WriteLine(xindex[WFinModuleCount] + " Status: " + status + "\n");
                 * }*/
            }

            // load waveform for channel 1 (Y)

            for (WFinModuleCount = 0; WFinModuleCount < ypoints.Count; WFinModuleCount++)
            {
                var tmpWaveform_Y = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, new double[] { ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount], ypoints[WFinModuleCount] }); // WaveForm has to contain even number of points to activate padding option 1
                status = moduleAOU.waveformLoad(tmpWaveform_Y, WFinModuleCount, 1);                                                                                                                                                                                                                                                                                                                                                                                                                                             // padding option 1 is used to maintain ending voltage after each WaveForm
                if (status < 0)
                {
                    Console.WriteLine("Error while loading " + WFinModuleCount + " point from y array, error code " + status);
                }
            }
            // queue waveform for channel 1
            for (WFinModuleCount = 0; WFinModuleCount < yindex.Count; WFinModuleCount++)
            {
                // use software trigger for Y channel
                status = moduleAOU.AWGqueueWaveform(1, yindex[WFinModuleCount], SD_TriggerModes.SWHVITRIG, 0, 1, 0);// AWG, waveform#, trigger, delay, cycle,prescaler
                if (status < 0)
                {
                    Console.WriteLine("Error while queuing " + WFinModuleCount + " point from y array, error code " + status);
                }
            }


            // Configure X channel to cyclic mode
            moduleAOU.AWGqueueConfig(1, 0);
            moduleAOU.AWGqueueConfig(2, 1);

            // Start both channel, x channel wait for external trigger, send software trigger to y channel
            moduleAOU.AWGstart(1);
            moduleAOU.AWGstart(2);
            moduleAOU.AWGtrigger(1);    // trigger Y channel to protection value

            // determine how long to pause after each jump based on frame rate
            int    pause_ms  = 1;
            double frametime = 1000 / (double)recording_rate;

            if (frametime > 1)
            {
                pause_ms = (int)Math.Ceiling(frametime);
            }

            int ncycle = 0;

            Console.WriteLine("Now on Y channel " + moduleAOU.AWGnWFplaying(1));
            while (moduleAOU.AWGnWFplaying(2) == 0)   // x channel may not be at zero when no trigger come, replace with AWGisRunning
            {
                // Empty loop wait for trigger to come
            }

            // Now cycle start
            moduleAOU.AWGtrigger(1); // trigger Y channel to first value
            Console.WriteLine("Now on Y channel " + moduleAOU.AWGnWFplaying(1));
            ncycle++;                // ncycle=1, currently working on cycle 1

            while ((ncycle < yindex.Count - 2) && Convert.ToBoolean(moduleAOU.AWGisRunning(2)))
            {
                while (moduleAOU.AWGnWFplaying(2) != ypoints.Count - 2)
                {
                    // empty loop wait for x channel to play last waveform
                }
                ncycle++;
                moduleAOU.AWGtrigger(1);
                Console.WriteLine("Jump to cycle " + ncycle + " now on Y channel: " + moduleAOU.AWGnWFplaying(1) + " now on X channel : " + moduleAOU.AWGnWFplaying(2));
                System.Threading.Thread.Sleep(pause_ms * 2);
                while (moduleAOU.AWGnWFplaying(2) != 0)
                {
                    // empty loop wait for x channel to play first waveform
                }
                ncycle++;
                moduleAOU.AWGtrigger(1);
                Console.WriteLine("Jump to cycle " + ncycle + " now on Y channel: " + moduleAOU.AWGnWFplaying(1) + " now on X channel : " + moduleAOU.AWGnWFplaying(2));
                System.Threading.Thread.Sleep(pause_ms * 2);
            }


            // after all cycles finished, sleep for 5 sec before stop AWG
            System.Threading.Thread.Sleep(5000);
            moduleAOU.AWGstop(1);
            moduleAOU.AWGstop(2);

            Console.Write("Both channel closed");

            return(HW_STATUS_RETURNS.HW_SUCCESS);
        }
Beispiel #14
0
        public void AWGQueueWaveform(double SystemFrequency, ref double SynchronizeFrequency, double[] waveform, ControlModule ctrlParameter, double dummyWaveformLength = 1e-6, bool useDummyWaveform = false)
        {
            try
            {
                nAWG = 1; //  100; //averaging
                double hwVer = moduleAOU.getHardwareVersion();
                if (hwVer < 4)
                {
                    nAWG = 0;
                }
                else
                {
                    nAWG = 1;
                }

                //multiple channels setting
                //int nChannels = 4;
                //int awgMask = 0;
                //for (int ii = 0; ii < nChannels; ii++)
                //    awgMask |= 1 << ii;

                //AWG reset
                moduleAOU.AWGstop(nAWG);
                moduleAOU.waveformFlush();
                moduleAOU.AWGflush(nAWG);

                Log(" > Set CLK frequency");
                //SystemFrequency = 1e6 * Convert.ToDouble(clkFreqAWG.Value);
                int setMode = 0; //0->LOW_JITTER, 1->FAST_TUNE
                this.SetAWGClockFrequency(SystemFrequency, out scalingFactor, true);
                //moduleAOU.clockSetFrequency(SystemFrequency, setMode);
                SynchronizeFrequency = moduleAOU.clockGetSyncFrequency();
                Log(" > AWG M320xA CLK Freqs");
                Log(" *** CLKsysFreq = " + SystemFrequency.ToString());
                Log(" *** CLKsyncFreq = " + SynchronizeFrequency.ToString());
                //Log("");

                //Wfm length
                //NOTE, 070519: set both RF and AWG wfm length to 1ms
                //int wfmLen = Convert.ToInt32((1e-3) * SystemFrequency);
                //Log("Queue Waveform.");
                this.AWGQueueConfig(ctrlParameter);
                //waveform
                int wfmType = SD_WaveformTypes.WAVE_ANALOG;
                int wfmNum = 0, onTime = 100; //wfmLen = 1000,
                //double[] wfmData = new double[wfmLen];
                //for (int ii = 0; ii < onTime; ii++)
                //wfmData[ii] = 1;
                SD_Wave wave = new SD_Wave(wfmType, waveform);

                Log(" *** AWG Sampling Num : " + waveform.Length.ToString());

                //SD_Wave wave = new SD_Wave(@"P:\4Francesco\ET_DPD\TestA_20000.csv"); //use this to create wfm from file
                var t = moduleAOU.waveformLoad(wave, wfmNum);//, wfmNum);

                if (!useDummyWaveform)
                {
                    t = moduleAOU.AWGqueueWaveform(nAWG, wfmNum, (int)ctrlParameter.TriggerMode, ctrlParameter.AWGTriggerDelay, ctrlParameter.repeatCycle, scalingFactor);
                }
                else
                {
                    int nDummyLength = (int)(dummyWaveformLength * SystemFrequency);
                    int mod          = nDummyLength % 16;
                    nDummyLength -= mod;
                    Log(" *** Dummy AWG Sampling Num : " + nDummyLength.ToString());
                    double[] dummyWave = new double[nDummyLength];
                    for (int i = 0; i < nDummyLength / 2; i++)
                    {
                        dummyWave[i] = 0.5;
                    }
                    for (int i = nDummyLength / 2; i < nDummyLength; i++)
                    {
                        dummyWave[i] = 0.5;
                    }
                    double[] normalDummy = Normalizer.Normalize(dummyWave);
                    SD_Wave  dWave       = new SD_Wave(wfmType, normalDummy);
                    t = moduleAOU.waveformLoad(dWave, wfmNum + 1);
                    t = moduleAOU.AWGqueueWaveform(nAWG, wfmNum + 1, (int)ctrlParameter.TriggerMode, ctrlParameter.AWGTriggerDelay, 1, scalingFactor);
                    t = moduleAOU.AWGqueueWaveform(nAWG, wfmNum, (int)AWGTRIGGERMODE.IMMEDIATE, 0, ctrlParameter.repeatCycle, scalingFactor);
                }
            }
            catch (Exception ex)
            {
                Log(ex.Message);
                throw ex;
            }
        }
        public HW_STATUS_RETURNS ScanControlInitialize(double x_amp, double y_amp, double[] Xarray_vol, double[] Yarray_vol, int[] Xarray_index, int[] Yarray_index, double delay, int recording_rate, int Option2D, int Nmultiframes)
        {
            int status;
            // Channel 1 for y scan and channel 2 for x scan

            //Create an instance of the AOU module
            SD_AOU moduleAOU  = new SD_AOU();
            string ModuleName = "M3201A";
            int    nChassis   = 1;
            int    nSlot      = 7;

            if ((status = moduleAOU.open(ModuleName, nChassis, nSlot)) < 0)
            {
                Console.WriteLine("Error openning the Module 'M3201A', make sure the slot and chassis are correct. Aborting...");
                Console.ReadKey();

                return(HW_STATUS_RETURNS.HW_SUCCESS);
            }

            // For global shutter mode, set targer trigger delay time in ns, TriggerDelay and TriggerDelayCeil set the acceptable range of dealy
            int TriggerDelay     = 0;
            int TriggerDelayCeil = 203900; // Define maximum triggger delay, otherwise the software would likely to use max Prescaling factor to satisfy the delay time

            // Determine prescaling factor and number of samples per step to use
            // According to Benjamin Bammels suggestion, use 5% to 10% longer frame time on AWG compared to DE frame integration time

            int nSamples;
            int Prescaling;

            nSamples   = (int)Math.Ceiling(1.05e8 / recording_rate / 4095);
            Prescaling = (int)Math.Ceiling(1.05e8 / recording_rate / nSamples);
            while (Prescaling > 1.10e8 / recording_rate / nSamples || nSamples == 1 || TriggerDelay % (10 * Prescaling) > 1)
            {
                nSamples++;
                Prescaling = (int)Math.Ceiling(1.05e8 / recording_rate / nSamples);
            }

            int SampleDelay;

            SampleDelay = (int)Math.Ceiling((double)TriggerDelay / 10 / (double)Prescaling);

            Console.WriteLine("Precaling factor " + Prescaling + " will be used with " + nSamples + " for each beam position.");
            Console.WriteLine("Scan delayed by " + (int)SampleDelay * Prescaling * 10 + " ns from beam position movement.");
            Console.WriteLine("Sample delayed by + " + (int)SampleDelay);

            // Config amplitude and setup AWG in channels 1 and 2,
            moduleAOU.channelAmplitude(1, y_amp);
            moduleAOU.channelWaveShape(1, SD_Waveshapes.AOU_AWG);
            moduleAOU.channelAmplitude(2, x_amp);
            moduleAOU.channelWaveShape(2, SD_Waveshapes.AOU_AWG);
            moduleAOU.channelAmplitude(3, 0.5);
            moduleAOU.channelWaveShape(3, SD_Waveshapes.AOU_AWG);
            moduleAOU.channelAmplitude(4, 0.5);
            moduleAOU.channelWaveShape(4, SD_Waveshapes.AOU_AWG);
            moduleAOU.waveformFlush();

            // Convert array into list

            xpoints = new List <double>();
            ypoints = new List <double>();
            xindex  = new List <int>();
            yindex  = new List <int>();

            xpoints.Clear();
            ypoints.Clear();
            xindex.Clear();
            yindex.Clear();

            xpoints = Xarray_vol.ToList();
            ypoints = Yarray_vol.ToList();
            xindex  = Xarray_index.ToList();
            yindex  = Yarray_index.ToList();

            status = moduleAOU.AWGflush(1);
            Console.WriteLine("Status for channel 1 " + status);
            status = moduleAOU.AWGflush(2);
            Console.WriteLine("Status for channel 2 " + status);
            status = moduleAOU.AWGflush(3);
            Console.WriteLine("Status for channel 3 " + status);
            status = moduleAOU.AWGflush(4);
            Console.WriteLine("Status for channel 4 " + status);



            #region X scan generation

            // Generate and queue waveform for X channel on waveform #0 (channel 2)
            // Currently when the waveform is full, break all loops using break, a better way would be to put the waveform get into a function and use return
            // to break all the loops.

            var Waveform_X = new double[nSamples * xindex.Count()];
            int Count      = 0;
            // Start with loop for delay cycle
            for (int i = 0; i < SampleDelay; i++)
            {
                Waveform_X[Count] = -0.5; //Start with beam outside scan region, scan region ranges from -0.5 to 0.5
                Count++;                  // Count represents the current number of points in waveform
            }
            // create double array for each x cycle
            for (int ix = 0; ix < xindex.Count; ix++)
            {
                for (int i = 0; i < nSamples; i++)
                {
                    Waveform_X[Count] = xpoints[xindex[xindex.Count - ix - 1]];
                    Count++;
                    if (Count == nSamples * xindex.Count())
                    {
                        break;  // End waveform generation when the waveform is full
                    }
                }
                if (Count == nSamples * xindex.Count())
                {
                    break;  // Also break the outer loop, in case the delay length is more than one beam position
                }
            }

            int length_x;
            length_x = Waveform_X.Length;


            #endregion

            #region Y scan generation

            //Set spectial nSamplesY and prescalingY because its variation frequency is much lower.
            int nSamplesY;
            int PrescalingY;

            nSamplesY   = (int)Math.Ceiling(1.05e8 / recording_rate * xindex.Count() / 4095);
            PrescalingY = (int)Math.Ceiling(1.05e8 / recording_rate * xindex.Count() / nSamplesY);
            while (PrescalingY > 1.10e8 / (recording_rate / xindex.Count()) / nSamplesY || nSamplesY == 1 || TriggerDelay % (10 * PrescalingY) > 1)
            {
                nSamplesY++;
                PrescalingY = (int)Math.Ceiling(1.05e8 / (recording_rate / xindex.Count()) / nSamplesY);
            }

            SampleDelay = (int)Math.Ceiling((double)TriggerDelay / 10 / (double)Prescaling);
            nSamplesY   = (int)Math.Ceiling((double)nSamplesY / xindex.Count()); // get back the nSamples for each position
            Console.WriteLine("Precaling factor for y scan" + PrescalingY + " will be used with " + nSamplesY + " for each beam position.");
            Console.WriteLine("Scan delayed by " + (int)SampleDelay * PrescalingY * 10 + " ns from beam position movement.");
            Console.WriteLine("Sample delayed by + " + (int)SampleDelay);
            // Generate and queue waveform for Y channel on waveform #1 (channel 1)

            var Waveform_Y = new double[nSamplesY * xindex.Count() * yindex.Count()];
            Count = 0;
            // Start with loop for delay cycle
            for (int i = 0; i < SampleDelay; i++)
            {
                Waveform_Y[Count] = -1; //Start with beam outside scan region, scan region ranges from -0.5 to 0.5
                Count++;
            }

            for (int iy = 0; iy < yindex.Count(); iy++)
            {
                for (int ix = 0; ix < xindex.Count(); ix++)
                {
                    for (int i = 0; i < nSamplesY; i++)
                    {
                        Waveform_Y[Count] = ypoints[yindex[yindex.Count - iy - 1]];
                        Count++;
                        if (Count == nSamplesY * xindex.Count() * yindex.Count())
                        {
                            break;  // End waveform generation when the waveform is full
                        }
                    }
                    if (Count == nSamplesY * xindex.Count() * yindex.Count())
                    {
                        break;  // Also break outer loop
                    }
                }
                if (Count == nSamplesY * xindex.Count() * yindex.Count())
                {
                    break;  // Break outmost loop
                }
            }
            int length_y;
            length_y = Waveform_Y.Length;

            #endregion

            #region generate DE trigger

            // Generate and queue waveform for DE trigger on wavefrom #2 (channel 3), same size and reps as x array

            var Waveform_DE = new double[nSamples * xindex.Count()];
            for (int ix = 0; ix < xindex.Count; ix++)
            {
                Waveform_DE[ix * nSamples] = -1;
            }
            int length_DE;
            length_DE = Waveform_DE.Length;

            #endregion

            #region generate digitizer trigger

            // Generate and queue waveform for digitizer trigger on waveform #3 (channel 4)
            // trigger signal same size as x array, run only once

            var Waveform_DIGI = new double[nSamples * xindex.Count()];
            for (int ix = 0; ix < nSamples; ix++)
            {
                Waveform_DIGI[ix + SampleDelay] = -1; // set first nSamples after SampleDelay points to -1 to create on single trigger
            }
            int length_DIGI;
            length_DIGI = Waveform_DIGI.Length;

            #endregion

            #region check wave_array sized and load all the four waveforms

            double memorySizeMB = (length_x + length_y + length_DE + length_DIGI) * 8e-6;
            if (memorySizeMB < 2000)
            {
                Console.WriteLine("The total memory size of the four waveform_array is" + memorySizeMB + " MB");
            }
            else
            {
                Console.WriteLine("The total memory size of the four waveform_array is" + memorySizeMB + " MB");
                System.Windows.Forms.MessageBox.Show("Your settings exceed RAM Limitation! ", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(HW_STATUS_RETURNS.HW_OTHER);
            }

            // x scan
            var SD_Waveform_X = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, Waveform_X);
            status = moduleAOU.waveformLoad(SD_Waveform_X, 0, 1);  // padding option 1 is used to maintain ending voltage after each WaveForm
            if (status < 0)
            {
                Console.WriteLine("Error while loading x waveform");
            }
            Console.WriteLine("X waveform size " + (double)moduleAOU.waveformGetMemorySize(0) / 1000000 + " MB");
            // queue waveform into channel 1 and loop for yindex.count() times
            status = moduleAOU.AWGqueueWaveform(1, 0, SD_TriggerModes.AUTOTRIG, 0, yindex.Count() * Nmultiframes, Prescaling);
            if (status < 0)
            {
                Console.WriteLine("Error while queuing x waveform");
            }

            //y scan
            var SD_Waveform_Y = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, Waveform_Y);
            status = moduleAOU.waveformLoad(SD_Waveform_Y, 1, 1);       // padding option 1 is used to maintain ending voltage after each WaveForm
            if (status < 0)
            {
                Console.WriteLine("Error while loading y waveform");
            }
            Console.WriteLine("Y waveform size " + (double)moduleAOU.waveformGetMemorySize(1) / 1000000 + " MB");
            // queue waveform into channel 2 and run once
            status = moduleAOU.AWGqueueWaveform(2, 1, SD_TriggerModes.AUTOTRIG, 0, Nmultiframes, Prescaling);
            if (status < 0)
            {
                Console.WriteLine("Error while queuing y waveform");
            }

            //DE camera
            var SD_Waveform_DE = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, Waveform_DE);
            status = moduleAOU.waveformLoad(SD_Waveform_DE, 2, 1);       // padding option 1 is used to maintain ending voltage after each WaveForm
            if (status < 0)
            {
                Console.WriteLine("Error while loading x waveform");
            }
            status = moduleAOU.AWGqueueWaveform(3, 2, SD_TriggerModes.AUTOTRIG, 0, yindex.Count() * Nmultiframes, Prescaling);
            Console.WriteLine("Trigger waveform size " + (double)moduleAOU.waveformGetMemorySize(2) / 1000000 + " MB");
            if (status < 0)
            {
                Console.WriteLine("Error while queuing camera trigger, error code " + status);
            }

            // Digitizer
            var SD_Waveform_DIGI = new SD_Wave(SD_WaveformTypes.WAVE_ANALOG, Waveform_DIGI);
            status = moduleAOU.waveformLoad(SD_Waveform_DIGI, 3, 1);       // padding option 1 is used to maintain ending voltage after each WaveForm
            if (status < 0)
            {
                Console.WriteLine("Error while loading x waveform");
            }
            status = moduleAOU.AWGqueueWaveform(4, 3, SD_TriggerModes.AUTOTRIG, 0, Nmultiframes, Prescaling);
            Console.WriteLine("Trigger waveform size " + (double)moduleAOU.waveformGetMemorySize(3) / 1000000 + " MB");
            if (status < 0)
            {
                Console.WriteLine("Error while queuing digitizer trigger, error code " + status);
            }

            #endregion

            // Configure all channels to single shot, X and trigger will automatically stop after certain amount of cycles
            moduleAOU.AWGqueueConfig(1, 0);
            moduleAOU.AWGqueueConfig(2, 0);
            moduleAOU.AWGqueueConfig(3, 0); // Should also be 0 here?
            moduleAOU.AWGqueueConfig(4, 0);

            // Start both channel and wait for triggers, start channel 0,1,2: 00000111 = 7; start channel 0,1,2,3: 00001111 = 15
            System.Threading.Thread.Sleep(1000);
            if (Option2D == 0)
            {
                moduleAOU.AWGstartMultiple(15);
            }
            else
            {
                moduleAOU.AWGstartMultiple(11); // don't start channel 3 for DE trigger if doing 2D scan mode
            }
            //moduleAOU.AWGstartMultiple(3);


            return(HW_STATUS_RETURNS.HW_SUCCESS);
        }