/// <summary> /// GetHardwareObjects creates the Hardware objects so /// that the data acquisition can occur. /// </summary> /// <param name="mirror">The IMirror to create</param> /// <param name="potstat">The IPotentiostat to create</param> /// <param name="laser">The ILaser to create</param> private void GetHardwareObjects(ref IMirror mirror, ref IPotentiostat potstat, ref ILaser laser) { //Create the interfaces this._view.Dispatcher.Invoke(new SetWindowStatusDelegate(this.SetWindowStatus), Strings.ConnectMirror); mirror = SHArKClassFactory.CreateIMirror(); this._view.Dispatcher.Invoke(new SetWindowStatusDelegate(this.SetWindowStatus), Strings.ConnectLaser); laser = SHArKClassFactory.CreateILaser(); this._view.Dispatcher.Invoke(new SetWindowStatusDelegate(this.SetWindowStatus), Strings.ConnectPotentiostat); potstat = SHArKClassFactory.CreateIPotentiostat(); if (mirror == null || potstat == null || laser == null) { //Show the error this._view.Dispatcher.Invoke(new ShowErrorDelegate(this.ShowError), Strings.HardwareNotDetected); //Close the Tab this._view.Dispatcher.BeginInvoke(new PublishCloseEventDelegate(this.PublishCloseEvent)); //Publish the event to notify that the Spectrum //has finished this._view.Dispatcher.Invoke(new NotifySpectrumEndedDelegate(this.NotifySpectrumEnded)); //Change the Mouse cursor back this._view.Dispatcher.Invoke(new SetMouseCursorDelegate(this.SetMouseCursor), Cursors.Arrow); } }
/// <summary> /// CreateIPotentiostat returns an IPotentiostat interface /// based on the current configuration. /// </summary> /// <returns>IPotentiostat object if one is configured; NULL otherwise</returns> public static IPotentiostat CreateIPotentiostat() { //Declare a variable to return IPotentiostat rtn = null; //Try to get an RDH2Potentiostat object //try //{ // rtn = Potentiostat.RDH2Potentiostat(); //} //catch { } //Try to get a LEGOPotentiostat object if the RDH2Potentiostat //could not be created if (rtn == null) { try { rtn = new Potentiostat.LEGOPotentiostat(); } catch { } } //Return the result return(rtn); }
/// <summary> /// ShowDarkCurrentDialog opens up the DarkCurrent /// Dialog and stops the operation of the application /// until it is closed. /// </summary> /// <param name="potstat">The Potentiostat from which to retrieve dark current</param> private void ShowDarkCurrentDialog(IPotentiostat potstat) { //Create the Dialog Box and show it DarkCurrentView dcv = new DarkCurrentView(); DarkCurrentViewModel dcvm = new DarkCurrentViewModel(dcv, potstat); dcv.DataContext = dcvm; dcv.Owner = System.Windows.Window.GetWindow(this._view); dcv.ShowDialog(); }
/// <summary> /// FindHardware attempts to create the hardware objects /// and display them to the user. /// </summary> private void FindHardware(Object parameter) { //Unpack the Parameters WizardControl wizard = parameter as WizardControl; //Set the button Enable states wizard.Dispatcher.BeginInvoke(new DisableButtonsDelegate(this.DisableButtons)); //Set the Cursor on the WizardControl wizard.Dispatcher.BeginInvoke(new ChangeCursorDelegate(this.ChangeCursor), Cursors.Wait); //Create the Hardware objects IMirror mirror = SHArKClassFactory.CreateIMirror(); IPotentiostat potstat = SHArKClassFactory.CreateIPotentiostat(); ILaser laser = SHArKClassFactory.CreateILaser(); //Get the names of the hardware -- default to not found String mirrorName = Strings.DeviceNotFound; String potstatName = Strings.DeviceNotFound; String laserName = Strings.DeviceNotFound; if (mirror != null) { mirrorName = mirror.Name; mirror.Dispose(); } if (potstat != null) { potstatName = potstat.Name; potstat.Dispose(); } if (laser != null) { laserName = laser.Name; laser.Dispose(); } //Set the labels in the Page wizard.Dispatcher.BeginInvoke(new SetLabelTextDelegate(this.SetLabelText), TextBlockType.Mirror, mirrorName); wizard.Dispatcher.BeginInvoke(new SetLabelTextDelegate(this.SetLabelText), TextBlockType.Potentiostat, potstatName); wizard.Dispatcher.BeginInvoke(new SetLabelTextDelegate(this.SetLabelText), TextBlockType.Laser, laserName); //Set the Cursor on the WizardControl wizard.Dispatcher.BeginInvoke(new ChangeCursorDelegate(this.ChangeCursor), Cursors.Arrow); //Enable the buttons as necessary wizard.Dispatcher.BeginInvoke(new EnableButtonsDelegate(this.EnableButtons), wizard); //Set the flag that the Hardware has been searched for this._hardwareSearched = true; }
/// <summary> /// Default Constructor for the DarkCurrentViewModel object. /// </summary> /// <param name="view">The View that will be filled by this ViewModel</param> /// <param name="potstat">The IPotentiostat that the ViewModel uses to display data</param> public DarkCurrentViewModel(DarkCurrentView view, IPotentiostat potstat) { //Save the input in the member variables this._view = view; this._potstat = potstat; //Start the Timer going this._timer = new Timer(new TimerCallback(this.GetDarkCurrent), null, 0, 500); //Set up the Commands this.WireCommands(); }
/// <summary> /// CheckPotentiostat looks for the type of /// potentiostat in the background thread. /// </summary> /// <param name="parameter">The View that is being modified</param> private void CheckPotentiostat(Object parameter) { //Unpack the Parameters WizardControl wizard = parameter as WizardControl; //Set the button Enable states wizard.Dispatcher.Invoke(new SetButtonsEnabledDelegate(this.SetButtonsEnabled), false); //Set the Cursor on the WizardControl wizard.Dispatcher.Invoke(new ChangeCursorDelegate(this.ChangeCursor), Cursors.Wait); //Create the Hardware objects IPotentiostat potstat = SHArKClassFactory.CreateIPotentiostat(); //If the Potentiostat could be created, check the //Name and see if it is a SHArK box. Otherwise, //popup an error message. if (potstat != null) { //Set the Visibility on the TextBlock if this is //a SHArK box if (potstat.Name.ToUpper().IndexOf("SHARK") > 0) { wizard.Dispatcher.Invoke(new SetTextBlockVisibilityDelegate(this.SetTextBlockVisibility), Visibility.Visible); } //Set the MaxCurrentValue property in the NewSpectrumInfo this.NewSpectrumInfo.MaxCurrentValue = potstat.MaximumCurrent; //Clean up the potentiostat potstat.Dispose(); } else { wizard.Dispatcher.Invoke(new ShowErrorDelegate(this.ShowError), Strings.DeviceNotFound); } //Set the Cursor on the WizardControl wizard.Dispatcher.Invoke(new ChangeCursorDelegate(this.ChangeCursor), Cursors.Arrow); //Enable the buttons as necessary wizard.Dispatcher.Invoke(new SetButtonsEnabledDelegate(this.SetButtonsEnabled), true); //Set the flag that the Hardware has been searched for this._hardwareSearched = true; }
/// <summary> /// Acquire3DData is called in a separate thread to /// acquire the data set up in the NewSpectrumInfo /// object passed to the Tab. /// </summary> private void Acquire3DData() { //Set the Mouse cursor this._view.Dispatcher.Invoke(new SetMouseCursorDelegate(this.SetMouseCursor), Cursors.Wait); //Set the basic Chart Properties this._view.Dispatcher.Invoke(new SetDocumentNameDelegate(this.SetDocumentName), Path.GetFileName(this._newSpecInfo.FileName)); this._view.Dispatcher.Invoke(new SetAxisRangesDelegate(this.SetAxisRanges), this._newSpecInfo.Columns - 1, this._newSpecInfo.Rows - 1); //Set the run state on the Chart this._view.Dispatcher.Invoke(new SetRunStateDelegate(this.SetRunState), true); //Get the Hardware objects -- just return //if any of them is null IMirror mirror = null; IPotentiostat potstat = null; ILaser laser = null; this.GetHardwareObjects(ref mirror, ref potstat, ref laser); if (mirror == null || potstat == null || laser == null) { return; } //Try to run the entire Acquisition try { //Initialize the new SHArKFile ISHArKFile file = SHArKFileFactory.Create(this._newSpecInfo.FileName, true); //Set the potential on the electrode potstat.SetPotential(this._newSpecInfo.BiasPotential); //Reset the Laser to the Initial Position this._view.Dispatcher.Invoke(new SetWindowStatusDelegate(this.SetWindowStatus), Strings.ResetInitialPosition); this.SetInitialLaserPosition(mirror, this._newSpecInfo.Columns, 0); //Finally, reset the mouse cursor so that the user //can see that initial processing is over this._view.Dispatcher.Invoke(new SetMouseCursorDelegate(this.SetMouseCursor), Cursors.Arrow); //Check the Poteniostat to see if the current is too //high to start a scan -- open the box if necessary if (potstat.IsCurrentSettled == false) { this._view.Dispatcher.Invoke(new ShowDarkCurrentDialogDelegate(this.ShowDarkCurrentDialog), potstat); } //Do the acquisition while the user does not //want to Pause or Stop Int32 xIndex = 0; Int32 yIndex = this._newSpecInfo.Rows - 1; Int32 xStep = this._newSpecInfo.StepSize; while (this.IsRunning == true) { //Get the time remaining as a String TimeSpan tsRemaining = this._newSpecInfo.CalculateTimeRemaining(xIndex, yIndex); String timeRemaining = String.Format("{0:D2}:{1:D2}:{2:D2}", tsRemaining.Hours, tsRemaining.Minutes, tsRemaining.Seconds); //Set the status on the Window to show that the //scan is running this._view.Dispatcher.Invoke(new SetWindowStatusDelegate(SetWindowStatus), String.Format("{0} {1} Remaining", Strings.ScanRunning, timeRemaining)); //Get the Dark Current value from the Potentiostat Double darkCurrent = potstat.GetCurrent(this._newSpecInfo.NumberCurrentSamples); //Turn on the Laser and wait the specified amount of time laser.SetLaserState(true); Thread.Sleep(this._newSpecInfo.MillisecondsLaserOnDelay); //Acquire the data for the current point Double lightCurrent = potstat.GetCurrent(this._newSpecInfo.NumberCurrentSamples); //Add the Point to the file Point p = new Point(xIndex, yIndex, lightCurrent - darkCurrent); file.AddDataPoint(p); //Turn off the laser and wait the specified amount of time laser.SetLaserState(false); Thread.Sleep(this._newSpecInfo.MillisecondsLaserOffDelay); //Set the Point in the ObservableCollection so //that it updates the Chart this._view.Dispatcher.Invoke(new AddPointsToChartDelegate(this.AddPointsToChart), new Point[] { p }, this._newSpecInfo.MaxCurrentValue); //Determine the direction of the X-Axis movement -- //if this is an odd row (relative to starting at //this._newSpecInfo.Rows - 1), move backward xStep = this._newSpecInfo.StepSize; if ((this._newSpecInfo.Rows % 2 == 0 && yIndex % 2 == 0) || (this._newSpecInfo.Rows % 2 == 1 && yIndex % 2 == 1)) { xStep *= -1; } //Determine if the Y-Axis mirror needs to move. //If the direction is positive, move when the //X-Axis gets to Columns. Otherwise, move when //the X-Axis gets to 0. if ((xStep > 0 && xIndex == this._newSpecInfo.Columns - 1) || (xStep < 0 && xIndex == 0)) { //Move the Y-Axis Mirror mirror.Move(MirrorAxis.Y, this._newSpecInfo.StepSize); //Update the yIndex yIndex--; } //Move to the next Column if necessary if ((xStep > 0 && xIndex < this._newSpecInfo.Columns - 1) || (xStep < 0 && xIndex > 0)) { //Move to the next Column mirror.Move(MirrorAxis.X, xStep); //Update the xIndex based on the direction //of the step if (xStep > 0) { xIndex++; } else { xIndex--; } } //Check to see if the scan is finished if (yIndex == -1 && ((xStep > 0 && xIndex == this._newSpecInfo.Columns - 1) || (xStep < 0 && xIndex == 0))) { this.IsRunning = false; } //If the user has Paused the acquisition, //loop and Sleep until resumed while (this.IsPaused == true && this.IsRunning == true) { //Stop the Laser from modulating laser.SetLaserState(false); //Set the status on the Window this._view.Dispatcher.Invoke(new SetWindowStatusDelegate(this.SetWindowStatus), String.Format("{0} {1} Remaining", Strings.ScanPaused, timeRemaining)); //Sleep for a half-second Thread.Sleep(500); } } //Stop the Laser from modulating laser.SetLaserState(false); //Move the Mirror back to the Initial Position this._view.Dispatcher.Invoke(new SetWindowStatusDelegate(this.SetWindowStatus), Strings.ResetInitialPosition); this.SetInitialLaserPosition(mirror, xIndex, yIndex); } catch (System.Exception e) { //Show an error message and return this._view.Dispatcher.Invoke(new ShowErrorDelegate(this.ShowError), e.Message); return; } finally { //Clean up the Hardware objects if (mirror != null) { mirror.Dispose(); } if (potstat != null) { potstat.SetPotential(0.0); potstat.Dispose(); } if (laser != null) { laser.SetLaserState(false); laser.Dispose(); } //Publish the event to notify that the Spectrum //has finished this._view.Dispatcher.Invoke(new NotifySpectrumEndedDelegate(this.NotifySpectrumEnded)); //Reset the Window Status this._view.Dispatcher.Invoke(new SetWindowStatusDelegate(this.SetWindowStatus), String.Empty); } }