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(); }
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(); }
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(); }
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); }
// 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); }
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(); }
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(); }
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."); }
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); }
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); }
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); }