Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Terrible control code.
- // TKA 06/2019 r0-alpha
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using Ivi.Visa;
- using NationalInstruments.Visa;
- using Thorlabs.MotionControl.DeviceManagerCLI;
- using Thorlabs.MotionControl.GenericMotorCLI;
- using Thorlabs.MotionControl.GenericMotorCLI.ControlParameters;
- using Thorlabs.MotionControl.GenericMotorCLI.AdvancedMotor;
- using Thorlabs.MotionControl.GenericMotorCLI.Settings;
- using Thorlabs.MotionControl.Benchtop.BrushlessMotorCLI;
- namespace scopecontrol
- {
- class Program
- {
- static void Main(string[] args)
- {
- // Initalize the oscilloscope object
- String stage_serial = "73878478";
- Console.ReadLine();
- DeviceManagerCLI.BuildDeviceList();
- ScopeInterface tek_mso_54 = new ScopeInterface();
- ScanConfiguration demoScan = new ScanConfiguration();
- tek_mso_54.Resource = "USB0::0x0699::0x0522::C013000::INSTR";
- tek_mso_54.ConnectResource();
- tek_mso_54.InitalizeInterface();
- demoScan.ConfigureScanStdIO();
- demoScan.CalculateRunupDistance(0.75);
- demoScan.GeneratePositionsForMove();
- // Start Microscope Stage Bullshit Here....
- StageInterface MLS203 = new StageInterface(stage_serial);
- MLS203.HomeStages();
- /********************
- Main Scanning Loop
- ********************/
- // Add the DC-Offset A+B and A-B Waveforms
- tek_mso_54.SendCommand("MATH:ADDN \"MATH1\";:MATH:MATH1:DEFINE \"CH1 + CH2\"");
- tek_mso_54.SendCommand("MATH:ADDN \"MATH2\";:MATH:MATH2:DEFINE \"CH1 - CH2\"");
- tek_mso_54.SendCommand("DIS:GLO:MATH1:STATE 0;:DIS:GLO:MATH2:STATE 0");
- //tek_mso_54.SendCommand("MATH:");
- // Add the measurement badges for A+B and A-B
- tek_mso_54.SendCommand("MEASU:ADDMEAS MEAN;:MEASU:MEAS1:SOU1 MATH1;:MEASU:MEAS1:LAB \"DC A+B\"" +
- ";:MEASU:MEAS1:MEASR:MIN 0.0E-3;:MEASU:MEAS1:MEASR:MAX 300.0E-3");
- tek_mso_54.SendCommand("MEASU:ADDMEAS MEAN;:MEASU:MEAS2:SOU1 MATH2;:MEASU:MEAS2:LAB \"DC A-B\"" +
- ";:MEASU:MEAS2:MEASR:MIN -10.0E-3;:MEASU:MEAS2:MEASR:MAX 10.0E-3");
- tek_mso_54.SendCommand("MEASU:ADDMEAS MEAN;:MEASU:MEAS3:SOU1 CH3;:MEASU:MEAS3:LAB \"DC-A\"" +
- ";:MEASU:MEAS3:MEASR:MIN 0.0E-3;:MEASU:MEAS3:MEASR:MAX 125.0E-3");
- tek_mso_54.SendCommand("MEASU:ADDMEAS MEAN;:MEASU:MEAS4:SOU1 CH4;:MEASU:MEAS4:LAB \"DC-B\"" +
- ";:MEASU:MEAS4:MEASR:MIN 0.0E-3;:MEASU:MEAS4:MEASR:MAX 125.0E-3");
- tek_mso_54.SendCommand("MEASU:ADDMEAS FREQUENCY;:MEASU:MEAS5:SOU1 CH1;:MEASU:MEAS5:LAB \"RF FRQ\"");
- tek_mso_54.SendCommand("MEASU:ADDMEAS ACRMS;:MEASU:MEAS6:SOU1 CH1;:MEASU:MEAS6:LAB \"RF RMS\"");
- Console.ReadLine();
- for (int i = 0; i<demoScan.RequiredRows; i++)
- {
- Console.WriteLine("Line {0}: Moving to {1},{2}.", i, demoScan.TourPoints[i,0].ToString("N3"), demoScan.TourPoints[i,1].ToString("N3"));
- MLS203.MoveStage(demoScan.TourPoints[i, 0], demoScan.TourPoints[i, 1], demoScan.ScanVelocity);
- Console.WriteLine("Line {0}: Adding runup acceleration distance of {1}mm.", i, demoScan.AccelDistanceRequired.ToString("N3"));
- MLS203.MoveStage(demoScan.TourPoints[i, 0], (demoScan.TourPoints[i, 1] - demoScan.AccelDistanceRequired), demoScan.ScanVelocity);
- if(i==0)
- {
- Console.WriteLine("SCAN PREP: Align the detector so SAWs are being generated...");
- Console.WriteLine("SCAN PREP: Once enter is pressed, the cycle can only be aborted by hard shutdown.");
- // Setup the scope to auto-acquire so the user can tweak the alignment....
- tek_mso_54.SendCommand("ACQ:STOPA RUNST;:TRIG:A:MOD AUTO;:ACQ:STATE 1");
- Console.ReadLine();
- tek_mso_54.SendCommand("ACQ:STATE 0;:TRIG:A:MOD NORM");
- }
- // Setup the Oscilloscope for the impending scan.
- tek_mso_54.SendCommand("ACQ:STATE 0;:ACQ:MODE SAM;:ACQ:SEQ:MOD " + demoScan.TotalPoints.ToString() +";:ACQ:STOPA SEQ;");
- tek_mso_54.SendCommand("HOR:FAST:STATE 1;:HOR:FAST:COUN " + demoScan.TotalPoints.ToString() + ";:HOR:FAST:SUMF:STATE OFF");
- // AFG Commands to simulate photodiode trigger signal
- Console.WriteLine("AFG: Starting Function Generator. 20kHz. 0-0.750V Sine, High-Z.");
- tek_mso_54.SendCommand("AFG:OUTP:STATE 0;:AFG:FUNC SINE;:AFG:LOWL 0.0;:AFG:HIGHL 0.750;:AFG:OUTP:LOA:IMPED HIGHZ;:AFG:OUTP:STATE 1");
- tek_mso_54.SendCommand("ACQ:STATE 1");
- Console.WriteLine("Line {0}: Moving to {1},{2}. Scanning Line.", i, demoScan.TourPoints[i, 2].ToString("N3"), demoScan.TourPoints[i, 3].ToString("N3"));
- MLS203.MoveStage(demoScan.TourPoints[i, 2], demoScan.TourPoints[i, 3], demoScan.ScanVelocity);
- tek_mso_54.SendCommand("AFG:OUTP:STATE 0");
- for(int j = 0; j < demoScan.TotalPoints; j++)
- {
- tek_mso_54.SendCommand("HOR:FAST:SELECTED " + j.ToString());
- Console.WriteLine("Dumping Curves to PC...");
- // Setup Encoding
- Console.WriteLine(tek_mso_54.SendQuery("DATA:SOURCE:AVAILABLE?"));
- Console.WriteLine("Continue?");
- Console.ReadLine();
- tek_mso_54.SendCommand("DATA:SOURCE CH1;:DATA:START 1;:DATA:END 10;:WFMOUTPRE:ENCDG ASCII");
- tek_mso_54.SendCommand(":CURVE?");
- var theCurve = tek_mso_54.SessionHandle.RawIO.Read(1024);
- Console.WriteLine("Transfer Complete, please press Return to see data...");
- Console.ReadLine();
- Console.WriteLine(theCurve);
- }
- Console.ReadLine();
- }
- Console.ReadLine();
- tek_mso_54.DisconnectResource();
- Console.ReadLine();
- }
- }
- public class ScopeInterface
- {
- private String resource_id;
- public bool IsConnected { get; set; }
- bool verbose;
- public MessageBasedSession SessionHandle = null;
- public ResourceManager SessionRM = null;
- public ScopeInterface()
- {
- this.resource_id = "Not initialized";
- this.IsConnected = false;
- this.verbose = true;
- return;
- }
- public String Resource
- {
- get { return resource_id; }
- set { this.resource_id = value; }
- }
- public void ConnectResource()
- {
- if(this.verbose)
- {
- Console.WriteLine("Attempting to open MessageBasedSession to " + this.resource_id);
- this.SessionRM = new ResourceManager();
- try
- {
- this.SessionHandle = (MessageBasedSession)this.SessionRM.Open(this.resource_id);
- if(this.verbose)
- {
- Console.WriteLine("Connected to: " + this.resource_id + " successfully...");
- this.IsConnected = true;
- }
- } catch (Exception exp)
- {
- Console.WriteLine(exp.Message);
- }
- }
- }
- public void DisconnectResource()
- {
- if(verbose)
- {
- Console.WriteLine("Disconnecting from resource " + this.resource_id);
- }
- this.SessionHandle.Dispose();
- this.IsConnected = false;
- }
- public void SendCommand(String _command)
- {
- if(IsConnected)
- {
- try
- {
- this.SessionHandle.TimeoutMilliseconds = 5000;
- this.SessionHandle.SendEndEnabled = true;
- this.SessionHandle.TerminationCharacterEnabled = true;
- this.SessionHandle.FormattedIO.WriteLine(_command);
- return;
- } catch (Exception exp)
- {
- Console.WriteLine(exp.Message);
- Console.ReadLine();
- return;
- }
- } else
- {
- Console.WriteLine("Not connected...");
- Console.ReadLine();
- return;
- }
- }
- public String SendQuery(String _command)
- {
- if (IsConnected)
- {
- try
- {
- if (verbose)
- {
- Console.WriteLine("Sending " + _command + " to " + this.resource_id);
- }
- this.SessionHandle.TimeoutMilliseconds = 7500;
- this.SessionHandle.FormattedIO.WriteLine(_command);
- String response = this.SessionHandle.FormattedIO.ReadLine();
- return response;
- }
- catch (Exception exp)
- {
- Console.WriteLine(exp.Message);
- Console.ReadLine();
- return "-1";
- }
- }
- else
- {
- Console.WriteLine("Not connected...");
- Console.ReadLine();
- return "-1";
- }
- }
- public void InitalizeInterface()
- {
- Console.WriteLine("******************************************");
- Console.WriteLine("* INITIALIZING OSCILLOSCOPE *");
- Console.WriteLine("* TEK MSO54 ON USB3 *");
- Console.WriteLine("* RESOURCE ID: *");
- Console.WriteLine("* " + this.resource_id + " *");
- Console.WriteLine("******************************************");
- Console.WriteLine("\nClearing oscilloscope...");
- this.SendCommand("*RST");
- Console.WriteLine(this.SendQuery("*OPC?"));
- // Stop Acquisition
- this.SendCommand("ACQUIRE:STATE STOP");
- // Setup Channels
- this.SendCommand("DIS:GLO:CH1:STATE 1;:DIS:GLO:CH2:STATE 1;:DIS:GLO:CH3:STATE 1;:DIS:GLO:CH4:STATE 1");
- // Setup Impedances and Bandwidths
- this.SendCommand("CH1:COUP AC;:CH2:COUP AC;:CH3:COUP DC;:CH4:COUP DC");
- this.SendCommand("CH1:TER 1.0E+6;:CH2:TER 1.0E+6");
- this.SendCommand("CH1:BAN 250E+6;:CH2:BAN 250E+6;:CH3:BAN 20E+6;:CH4:BAN 20E+6");
- // Setup Axes
- this.SendCommand("CH1:SCA 100.0E-3;:CH2:SCA 500.0E-3;:CH3:SCA 40.0E-3;:CH4:SCA 40.0E-3");
- this.SendCommand("HOR:MODE:SCA 20.0E-9;:HOR:POS 10");
- // Setup
- // Normal Trigger Mode (aka, don't make rando triggers)
- // Use the A-trigger, use Channel 2, Trigger at 800mV Rising Edge.
- this.SendCommand("TRIG:A:MODE:NORM");
- this.SendCommand("TRIG:A:EDGE:SOU CH2;:TRIG:A:EDGE:SLO RIS;");
- this.SendCommand("TRIG:A:LEV:CH2 0.500E+0");
- // Label Axes
- this.SendCommand("CH1:LAB:NAM \"SAW\";:CH2:LAB:NAM \"Optotrigger\";:CH3:LAB:NAM \"DC Offset-A\";:CH4:LAB:NAM \"DC Offset-B\"");
- Console.WriteLine("********************************");
- Console.WriteLine("* OSCILLOSCOPE SETUP COMPLETED *");
- Console.WriteLine("********************************");
- Console.WriteLine("Press Enter to continue initalizing hardware...");
- Console.ReadLine();
- }
- }
- public class StageInterface
- {
- public BenchtopBrushlessMotor StageMotor;
- public BrushlessMotorChannel XAxis;
- public BrushlessMotorChannel YAxis;
- public MotorConfiguration XAxisConfig;
- public MotorConfiguration YAxisConfig;
- public bool IsHomed;
- public bool IsConnected;
- public bool IsEnabled;
- public String SerialNumber;
- public int MovementTimeout = 10000;
- public int PollingInterval = 100;
- public decimal StageAccel { get; set; }
- public StageInterface(String serial)
- {
- this.IsHomed = false;
- this.IsConnected = false;
- this.IsEnabled = false;
- this.MovementTimeout = 15000;
- this.PollingInterval = 100;
- this.StageAccel = 2500.0m;
- this.SerialNumber = serial;
- try
- {
- Console.WriteLine("MICROSCOPE: Initalizing StageObject and AxesObjects...");
- this.StageMotor = BenchtopBrushlessMotor.CreateBenchtopBrushlessMotor(this.SerialNumber);
- Console.WriteLine("MICROSCOPE: Attempting to connect to " + this.SerialNumber + "....");
- this.StageMotor.Connect(this.SerialNumber);
- this.IsConnected = true;
- Console.WriteLine("MICROSCOPE: Connected! Assigning and configuring X/Y axes...");
- this.XAxis = this.StageMotor.GetChannel(1);
- this.YAxis = this.StageMotor.GetChannel(2);
- if ((!this.XAxis.IsSettingsInitialized()) || (!this.YAxis.IsSettingsInitialized()))
- {
- XAxis.WaitForSettingsInitialized(this.MovementTimeout);
- YAxis.WaitForSettingsInitialized(this.MovementTimeout);
- }
- Thread.Sleep(200);
- Console.WriteLine("MICROSCOPE: Beginning polling at " + this.PollingInterval + "ms...");
- this.XAxis.StartPolling(this.PollingInterval);
- this.YAxis.StartPolling(this.PollingInterval);
- Console.WriteLine("MICROSCOPE: Generating X/Y Axes MotorConfigurations to enable encoder <-> mm conversions...");
- this.XAxisConfig = this.XAxis.LoadMotorConfiguration(this.XAxis.DeviceID);
- this.YAxisConfig = this.YAxis.LoadMotorConfiguration(this.YAxis.DeviceID);
- Thread.Sleep(250);
- this.XAxis.SetTriggerSwitches((byte)HardwareTriggeringSettings.TriggerOutputEnable.MaxVelocityHI);
- this.YAxis.SetTriggerSwitches((byte)HardwareTriggeringSettings.TriggerOutputEnable.MaxVelocityHI);
- this.XAxis.EnableDevice();
- this.YAxis.EnableDevice();
- Thread.Sleep(250);
- this.IsEnabled = true;
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.Message);
- return;
- }
- }
- public void HomeStages()
- {
- Console.WriteLine("MICROSCOPE: Homing X-Axis...");
- this.XAxis.Home(this.MovementTimeout);
- Console.WriteLine("MICROSCOPE: Homing Y-Axis...");
- this.YAxis.Home(this.MovementTimeout);
- return;
- }
- public void MoveStage(decimal desired_x, decimal desired_y, decimal desired_v, bool _verby = false)
- {
- this.XAxis.SetVelocityParams(desired_v, this.StageAccel);
- this.YAxis.SetVelocityParams(desired_v, this.StageAccel);
- // Do the XAxis move first, the move YAxis. Kick move out to individual thread
- // so you can poll with the main thread.
- bool xMoveFinished = false;
- bool yMoveFinished = false;
- Task xMoveWorker = Task.Factory.StartNew(() =>
- {
- this.XAxis.MoveTo(desired_x, this.MovementTimeout);
- xMoveFinished = true;
- });
- while (!xMoveFinished)
- {
- if (_verby)
- {
- Console.WriteLine("Moving\tX: " + this.XAxis.Position + "mm\tY: " + this.YAxis.Position + "mm");
- }
- Thread.Sleep(this.PollingInterval);
- }
- Task yMoveWorker = Task.Factory.StartNew(() =>
- {
- this.YAxis.MoveTo(desired_y, this.MovementTimeout);
- yMoveFinished = true;
- });
- while (!yMoveFinished)
- {
- if (_verby)
- {
- Console.WriteLine("Moving\tX: " + this.XAxis.Position + "mm\tY: " + this.YAxis.Position + "mm");
- }
- Thread.Sleep(this.PollingInterval);
- }
- }
- }
- public class ScanConfiguration
- {
- public decimal XOrigin { get; set; }
- public decimal YOrigin { get; set; }
- public decimal XDelta { get; set; }
- public decimal YDelta { get; set; }
- public decimal StepOver { get; set; }
- public decimal ScanVelocity { get; set; }
- public int LaserFrequency { get; set; }
- public decimal AccelDistanceRequired { get; set; }
- public decimal StageAccelerationValue { get; set; }
- public decimal PositionResolution { get; set; }
- public decimal[,] TourPoints;
- public int TaintedPoints { get; set; }
- public int LineLength { get; set; }
- public int RequiredRows { get; set; }
- public int TotalPoints { get; set; }
- public int TotalScanPoints { get; set; }
- public int GoodPoints { get; set; }
- public ScanConfiguration()
- {
- this.StepOver = 0.100m;
- this.ScanVelocity = 200.0m;
- this.LaserFrequency = 20000;
- this.StageAccelerationValue = 2500.00m;
- return;
- }
- public void ConfigureScanStdIO()
- {
- Console.WriteLine("Enter the x-origin coordinate in mm: ");
- String _xOStr = Console.ReadLine();
- this.XOrigin = decimal.Parse(_xOStr);
- Console.WriteLine("ScanConfiguration.XOrigin: " + this.XOrigin + "mm.");
- Console.WriteLine("Enter the y-origin coordinate in mm: ");
- String _yOStr = Console.ReadLine();
- this.YOrigin = decimal.Parse(_yOStr);
- Console.WriteLine("ScanConfiguration.YOrigin: " + this.YOrigin + "mm.");
- Console.WriteLine("Enter the x-delta length in mm: ");
- String _xDStr = Console.ReadLine();
- this.XDelta = decimal.Parse(_xDStr);
- Console.WriteLine("ScanConfiguration.XDelta: " + this.XDelta + "mm.");
- Console.WriteLine("Enter the y-delta length in mm: ");
- String _yDStr = Console.ReadLine();
- this.YDelta = decimal.Parse(_yDStr);
- Console.WriteLine("ScanConfiguration.YDelta: " + this.YDelta + "mm.");
- Console.WriteLine("OTHER CONFIGURATION SETTINGS SET IN THE CLASS:");
- Console.WriteLine("----------------------------------------------");
- Console.WriteLine("ScanConfiguration.StepOver: " + this.StepOver + "mm.\t\tScanConfiguration.ScanVelocity: " + this.ScanVelocity + "mm/s.");
- Console.WriteLine("ScanConfiguration.LaserFrequency: " + this.LaserFrequency + "Hz.\tScanConfiguration.StageAccelerationValue: " + this.StageAccelerationValue + "mm/s2.");
- Console.WriteLine("Configuration completed. Scanpath can now be generated.");
- Console.WriteLine("Press enter to continue...");
- Console.ReadLine();
- return;
- }
- public void CalculateRunupDistance(double deratingFactor = 1.0)
- {
- decimal _baseDistance = (this.ScanVelocity / this.StageAccelerationValue);
- this.AccelDistanceRequired = _baseDistance / (decimal)deratingFactor;
- Console.WriteLine("SCAN CONFIG: For a={0}mm/s2, v={1}mm/s.",
- this.StageAccelerationValue.ToString("N2"), this.ScanVelocity.ToString("N2"));
- Console.WriteLine("SCAN CONFIG: An additional {0}mm, minimum is required. Your derate is {1}.",
- _baseDistance.ToString("N3"), deratingFactor.ToString("N3"));
- Console.WriteLine("SCAN CONFIG: Using the selected derate, {0}mm has been added to the beginning of the scan.",
- this.AccelDistanceRequired.ToString("N3"));
- this.TaintedPoints = (int)Math.Ceiling((this.AccelDistanceRequired / this.ScanVelocity) * this.LaserFrequency);
- this.GoodPoints = (int)Math.Ceiling((this.XDelta / this.ScanVelocity) * this.LaserFrequency);
- this.TotalPoints = this.GoodPoints + this.TaintedPoints;
- Console.WriteLine("SCAN CONFIG: This will taint the first {0} points of the dataset. They will be marked as unreliable.", this.TaintedPoints);
- this.PositionResolution = this.ScanVelocity / this.LaserFrequency;
- Console.WriteLine("SCAN CONFIG: A linescan will consist of {0} points, including {1} tainted, at a position resolution of {2}mm.",
- this.TotalPoints, this.TaintedPoints, this.PositionResolution.ToString("N3"));
- this.RequiredRows = (int)Math.Ceiling(this.YDelta / this.StepOver);
- this.TotalPoints = (this.GoodPoints + this.TaintedPoints);
- this.TotalScanPoints = this.TotalPoints * this.RequiredRows;
- Console.WriteLine("SCAN CONFIG: {0} rows will be acquired. Total acquisition is {1} positions.", this.RequiredRows, this.TotalScanPoints);
- Console.ReadLine();
- }
- public void GeneratePositionsForMove()
- {
- int _totalPoints = 2 * this.RequiredRows;
- this.TourPoints = new decimal[_totalPoints, 4];
- for(int i=0; i<this.RequiredRows; i++)
- {
- decimal _xStart = this.XOrigin + i * this.StepOver;
- decimal _yStart = this.YOrigin;
- decimal _yEnd = this.YOrigin + this.YDelta;
- this.TourPoints[i, 0] = _xStart;
- this.TourPoints[i, 1] = _yStart;
- this.TourPoints[i, 2] = _xStart;
- this.TourPoints[i, 3] = _yEnd;
- Console.WriteLine("Line {0}: Start: {1},{2}\tEnd:{3},{4}", i, _xStart.ToString("N3"), _yStart.ToString("N3"),
- _xStart.ToString("N3"), _yEnd.ToString("N3"));
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement