예제 #1
0
        /// <summary>
        /// Initiate the output task writer, and apply an initial constant bias
        /// </summary>
        /// <param name="task">The output task that the writer will belong to</param>
        /// <param name="settings">The UI settings</param>
        private void InitiateOutputWriter(Task task, IVSettings settings)
        {
            //
            // generate output arrays
            //
            m_functionGenerator = new FunctionGenerator(settings.IVGeneralSettings.SamplesPerCycle,
                                                        settings.IVGeneralSettings.VoltageAmplitude,
                                                        settings.IVGeneralSettings.VoltageAmplitude);

            //
            // create the writer of the output task
            //
            writer = new AnalogSingleChannelWriter(m_outputTask.Stream);

            //
            // write static voltage
            //
            writer.WriteMultiSample(true, m_functionGenerator.ConstWave);
        }
예제 #2
0
        /// <summary>
        /// Do Cycles of closing and opening the junction, while measuring IVs
        /// </summary>
        /// <param name="settings"></param>
        /// <param name="worker"></param>
        /// <param name="e"></param>
        public void IV_AcquireData(IVSettings settings,BackgroundWorker worker, DoWorkEventArgs e)
        {
            bool isCancelled = false;
            int finalFileNumber = settings.IVGeneralSettings.CurrentFileNumber;
            double[,] dataAcquired;
            List<IDataChannel> physicalChannels = new List<IDataChannel>();

            //
            // Save this run settings if desired
            //
            SaveSettingsIfNeeded(settings, settings.IVGeneralSettings.IsFileSavingRequired, settings.IVGeneralSettings.Path);

            //
            // apply initial voltage on the EM if needed
            //
            ApplyVoltageOnElectroMagnetIfNeeded(settings.IVSteppingMethodSettings.SteppingDevice == SteppingDevice.ElectroMagnet);

            
            //
            // create the input and output tasks
            //
            m_ivInputTask = GetContinuousAITask(settings.IVGeneralSettings.SampleRate, settings.ChannelsSettings.ActiveChannels, null);
            m_ivInputTask.Stream.ReadRelativeTo = ReadRelativeTo.FirstSample;
            m_outputTask = GetContinuousAOTask(settings);

            //
            // initiate writer for the output and set initial bias
            //
            InitiateOutputWriter(m_outputTask, settings);
            
            //
            // Main loop for data aquisition
            //
            for (int i = 0; i < settings.IVGeneralSettings.TotalNumberOfCycles; i++)
            {
                //
                // Cancel the operatin if user asked for
                //
                if (worker.CancellationPending == true)
                {
                    e.Cancel = true;
                    break;
                }

                //
                // if we use EM, and we are asked to skip the first cycle (that is done by the stepper motor), 
                // move on to the next cycle.
                //
                if (i == 0 && settings.IVSteppingMethodSettings.SteppingDevice == SteppingDevice.ElectroMagnet 
                            && settings.IVSteppingMethodSettings.IsEMSkipFirstCycleEnable)
                {
                    m_stepperMotor.Shutdown();
                    continue;
                }

                //
                // Change the gain power to 5 before reaching contact
                // to ensure full contact current
                //
                m_amplifier.ChangeGain(5);

                //
                // Reach to contact before we start openning the junction
                // If we use EM and we're after the first cycle, use the EM.
                // If user asked to stop than exit
                //
                isCancelled = (settings.IVSteppingMethodSettings.SteppingDevice == SteppingDevice.ElectroMagnet && i > 0) ?
                               EMTryObtainShortCircuit(settings.IVSteppingMethodSettings.EMShortCircuitDelayTime, settings.IVGeneralSettings.ShortCircuitVoltage, worker, e) :
                               TryObtainShortCircuit(settings.IVGeneralSettings.ShortCircuitVoltage,settings.IVGeneralSettings.UseShortCircuitDelayTime,settings.IVGeneralSettings.ShortCircuitDelayTime,worker, e);
                if (isCancelled)
                {
                    break;
                }

                //
                // Configure the gain to the desired one before strating the measurement.
                // And also this is the time to switch the laser on.
                //
                int gainPower;
                Int32.TryParse(settings.IVGeneralSettings.Gain, out gainPower);
                m_amplifier.ChangeGain(gainPower);

                //
                // Start openning the junction.
                // If EM is enabled and we're after the first cycle, use the EM.
                //
                if (settings.IVSteppingMethodSettings.SteppingDevice == SteppingDevice.ElectroMagnet)
                {
                    if (i == 0)
                    {
                        //
                        // we are on the first cycle and wish to open the junction by the stepper motor.
                        //
                        ObtainOpenJunctionByStepperMotor(settings.IVGeneralSettings.TriggerVoltage, worker, e);

                        //
                        // from now on we will be using the electroMagnet, so lets turn the stepper motor off and move to the next cycle
                        //
                        m_stepperMotor.Shutdown();
                        continue;
                    }
                    else
                    {
                        //
                        // we set the votlage to triangle wave and then open the junction by the EM
                        //
                        writer.BeginWriteMultiSample(false, m_functionGenerator.TriangleWave, null, null);
                        IV_EMBeginOpenJunction(settings);
                    }
                }
                else
                {
                    //
                    // we set the voltage to triangle wave and then open the junction by stepper motor
                    //
                    writer.BeginWriteMultiSample(false, m_functionGenerator.TriangleWave, null, null);
                    IV_StepperMotorBeginOpenJunction(settings);
                }

                //
                // Start the input task.
                //
                try
                {
                    m_ivInputTask.Start();
                }
                catch (DaqException ex)
                {
                    throw new SBJException("Error occured when tryin to start DAQ input task", ex);
                }

                //
                // start reading continuously. 
                // when the junction is opened, the opening thread will change m_quitJuncctionOpeningOperation to true.
                // set dataAquired to null otherwise it saves last cycle's data. 
                //
                reader = new AnalogMultiChannelReader(m_ivInputTask.Stream);
                dataAcquired = null;
                try
                {
                    while (!m_quitJunctionOpenningOperation)
                    {
                        dataAcquired = reader.ReadMultiSample(-1);
                    }

                    if (dataAcquired != null)
                    {
                        if (settings.ChannelsSettings.ActiveChannels.Count != dataAcquired.GetLength(0))
                        {
                            throw new SBJException("Number of data channels doesn't fit the recieved data.");
                        }
                    }
                }
                catch (DaqException)
                {
                    //
                    // Probably timeout.
                    // Ignore this cycle and rerun.
                    //
                    m_ivInputTask.Stop();
                    continue;
                }

                //
                // At this point the reader has returned with all the data and we can stop the input task.
                //
                m_ivInputTask.Stop();

                //
                // if we didn't acquire any data, there's no need to save anything.
                //
                if (dataAcquired == null)
                {
                    continue;
                }

                //
                // Assign the aquired data for each channel.
                // First clear all data from previous interation.
                //                
                ClearRawData(settings.ChannelsSettings.ActiveChannels);
                AssignRawDataToChannels(settings.ChannelsSettings.ActiveChannels, dataAcquired);

                //
                // physical channel will include both simple and complex channels. 
                // 
                physicalChannels = GetChannelsForDisplay(settings.ChannelsSettings.ActiveChannels);

                //
                // calculate the physical data for each channel
                //
                GetPhysicalData(physicalChannels);

                //
                // the IV acquisition is done, we need to return the output to constant voltage for the next cycle
                //
                writer.BeginWriteMultiSample(false, m_functionGenerator.ConstWave, null, null);

                // 
                // Increase file number by one
                // Save data if needed
                //
                finalFileNumber++;
                if (settings.IVGeneralSettings.IsFileSavingRequired)
                {
                    finalFileNumber = SaveData(settings.IVGeneralSettings.Path, settings.ChannelsSettings.ActiveChannels, physicalChannels, finalFileNumber);
                }

                //
                // Signal UI we have the data
                //
                if (DataAquired != null)
                {
                    DataAquired(this, new DataAquiredEventArgs(physicalChannels, finalFileNumber));
                }     
            }

            //
            // Finish the measurement properly
            //
            if (settings.IVSteppingMethodSettings.SteppingDevice == SteppingDevice.ElectroMagnet)
            {
                m_electroMagnet.Shutdown();
            }
            m_ivInputTask.Dispose();
            m_ivInputTask = null;
            m_outputTask.Dispose();
            m_outputTask = null;
            m_stepperMotor.Shutdown();
        }
예제 #3
0
        /// <summary>
        /// Open the junction by the StepperMotor for IV acquisition.
        /// </summary>
        /// <param name="settings"></param>
        private void IV_StepperMotorOpenJunction(IVSettings settings)
        {
            int underTriggerCounts = 0;
            int numOfSteps = 0;
            double changeRateTrigger = settings.IVGeneralSettings.ShortCircuitVoltage;
            int rateTriggerCounts = 0;

            //
            // Set the direction of the movement
            // And configure the first setpper delay (shorter) - faster movement
            //
            m_stepperMotor.Direction = StepperDirection.UP;
            m_stepperMotor.Delay = settings.IVSteppingMethodSettings.StepperMotorWaitTime1;

            //
            // Read the initial voltgae before we've done anything
            //
            double initialVoltage = AnalogIn(0);
            m_quitJunctionOpenningOperation = false;

            //
            // we'll moving up until this function figures the junction is open. then it signals it
            // by changing the value of m_quitJunctionOpeningOperatin to TRUE.
            //
            while (!m_quitJunctionOpenningOperation)
            {
                m_stepperMotor.MoveSingleStep();
                numOfSteps++;
                double currentVoltage = AnalogIn(0);

                //
                // if we didn't switch to slowest rate yet
                //
                if (rateTriggerCounts >= 0)
                {
                    //
                    // check if the voltage is under the change-rate trigger. Count how many times in a row it happens.
                    //
                    if (Math.Abs(currentVoltage) < changeRateTrigger)
                    {
                        rateTriggerCounts++;
                    }
                    else
                    {
                        rateTriggerCounts = 0;
                    }

                    //
                    // if we are under the trigger for some steps in a row, switch to the slower rate.
                    //
                    if (rateTriggerCounts > 5)
                    {
                        m_stepperMotor.Delay = (int)settings.IVSteppingMethodSettings.StepperMotorWaitTime2;
                        rateTriggerCounts = -1;
                    }
                }


                //
                // check if the voltage is under the trigger. Count how many times in a row it happens.
                // correct the trigger by the preamp offset
                //
                if (Math.Abs(currentVoltage) < (Math.Abs(settings.IVGeneralSettings.TriggerVoltage) + c_preAmpOffset))
                {
                    underTriggerCounts++;
                }
                else
                {
                    underTriggerCounts = 0;
                }

                //
                // if we are under the trigger for some steps in a row, the junction is open.
                //
                if (underTriggerCounts > 4)
                {
                    m_quitJunctionOpenningOperation = true;
                }
                Thread.Sleep(m_stepperMotor.Delay);
            }
        }
예제 #4
0
 /// <summary>
 /// Get Continuous Analog Output Task
 /// </summary>
 /// <param name="settings"></param>
 /// <returns></returns>
 private Task GetContinuousAOTask(IVSettings settings)
 {
     //
     // get the properties required for the output task
     //
     ContinuousAOTaskProperties outputProperties = new ContinuousAOTaskProperties(null, settings.IVGeneralSettings.OutputUpdateRate,
                                                                                  settings.IVGeneralSettings.SamplesPerCycle,
                                                                                  settings.IVGeneralSettings.VoltageAmplitude);
     //
     // return the output task
     //
     return m_daqController.CreateContinuousAOTask(outputProperties);
 }
예제 #5
0
 /// <summary>
 /// Open the junction asynchronously by the StepperMotor for IV measurements
 /// </summary>
 /// <param name="settings"></param>
 private void IV_StepperMotorBeginOpenJunction(IVSettings settings)
 {
     IV_StepperMotorOpenJunctionMethodDelegate stepperMotorOpenJunctionDelegate = new IV_StepperMotorOpenJunctionMethodDelegate(IV_StepperMotorOpenJunction);
     AsyncCallback callback = new AsyncCallback(IV_StepperMotorEndOpenJunction);
     IAsyncResult asyncResult = stepperMotorOpenJunctionDelegate.BeginInvoke(settings, callback, stepperMotorOpenJunctionDelegate);
 }
예제 #6
0
        /// <summary>
        /// Open the junction by the ElectroMagnet for IV acquisition.
        /// If min voltage exceeded without the junction being opened, return false. 
        /// </summary>
        /// <param name="settings">The settings to be used to open the junction</param>
        private bool IV_EMOpenJunction(IVSettings settings)
        {
            int underTriggerCounts = 0;
            int numOfSteps = 0;
            double changeRateTrigger = settings.IVGeneralSettings.ShortCircuitVoltage;
            int rateTriggerCounts = 0;

            //
            // Set the direction of the movement
            // And configure the first setpper delay (shorter) - faster movement
            //
            m_electroMagnet.Direction = StepperDirection.UP;
            m_electroMagnet.Delay = settings.IVSteppingMethodSettings.EMFastDelayTime;

            //
            // Read the initial voltgae before we've done anything
            //
            double initialVoltage = AnalogIn(0);
            m_quitJunctionOpenningOperation = false;

            //
            // we'll moving up until this function figures the junction is open. then it signals it
            // by changing the value of m_quitJunctionOpeningOperatin to TRUE.
            //
            while (!m_quitJunctionOpenningOperation)
            {
                if (!m_electroMagnet.MoveSingleStep())
                {
                    //
                    // if min Votlage on EM was exceeded return false.
                    //
                    return false;
                }
                numOfSteps++;
                double currentVoltage = AnalogIn(0);

                //
                // after some steps, slower the rate
                //
                if (numOfSteps == 100)
                {
                    m_electroMagnet.Delay = (int)(0.2 * settings.IVSteppingMethodSettings.EMSlowDelayTime + 0.8 * settings.IVSteppingMethodSettings.EMFastDelayTime);
                }

                ////
                //// after more steps, slower the rate more
                ////
                //if (numOfSteps == 200)
                //{
                //    m_electroMagnet.Delay = (int)settings.ElectromagnetSettings.EMSlowDelayTime;
                //}

                //
                // if we didn't switch to slowest rate yet, and we made more than 100 steps
                //
                if ((rateTriggerCounts >= 0) && (numOfSteps > 100))
                {
                    //
                    // check if the voltage is under the rate trigger. Count how many times in a row it happens.
                    //
                    if (Math.Abs(currentVoltage) < changeRateTrigger)
                    {
                        rateTriggerCounts++;
                    }
                    else
                    {
                        rateTriggerCounts=0;
                    }

                    //
                    // if we are under the trigger for some steps in a row, switch to the slowest rate.
                    //
                    if (rateTriggerCounts > 4)
                    {
                        m_electroMagnet.Delay = (int)settings.IVSteppingMethodSettings.EMSlowDelayTime;
                        rateTriggerCounts = -1;
                    }
                }


                //
                // check if the voltage is under the trigger. Count how many times in a row it happens.
                // correct the trigger by the preamp offset
                //
                if (numOfSteps > 200 && Math.Abs(currentVoltage) < (Math.Abs(settings.IVGeneralSettings.TriggerVoltage)+c_preAmpOffset))
                {
                    underTriggerCounts++;
                }
                else
                {
                    underTriggerCounts = 0;
                }

                //
                // if we are under the trigger for some steps in a row, the junction is open.
                //
                if (underTriggerCounts > 4)
                {
                     m_quitJunctionOpenningOperation = true;
                }
                Thread.Sleep(m_electroMagnet.Delay);
            }
            return true;
        }
예제 #7
0
 /// <summary>
 /// Try open junction by the EM, by calling IV_EMOpenJunction.
 /// if min voltage exceeded without the junction being opened, do a few steps by the stepper motor, then retry EM (recursion).
 /// </summary>
 /// <param name="settings"></param>
 /// <returns></returns>
 private bool IV_EMTryOpenJunction(IVSettings settings)
 {
     //
     // if the EM reached voltage 0 without opening the junction, 
     // return to higher voltage on EM, do some steps by the stepper motor and retry opening by EM.
     //
     if (!IV_EMOpenJunction(settings))
     {
         m_electroMagnet.ReachEMVoltageGradually(m_electroMagnet.MinDelay, c_initialEMVoltage);
         MoveStepsByStepperMotor(StepperDirection.UP, 300);
         return IV_EMTryOpenJunction(settings);
     }
     return true;
 }
예제 #8
0
 /// <summary>
 /// Open the junction asynchronously by the ElectroMagnet for IV measurements
 /// </summary>
 /// <param name="settings"></param>
 private void IV_EMBeginOpenJunction(IVSettings settings)
 {
     IV_EMOpenJunctionMethodDelegate emOpenJunctionDelegate = new IV_EMOpenJunctionMethodDelegate(IV_EMTryOpenJunction);
     AsyncCallback callback = new AsyncCallback(IV_EMEndOpenJunction);
     IAsyncResult asyncResult = emOpenJunctionDelegate.BeginInvoke(settings, callback, emOpenJunctionDelegate);
 }
예제 #9
0
        /// <summary>
        /// Perform IV cycles while standing in place
        /// </summary>
        /// <param name="settings"></param>
        /// <param name="worker"></param>
        /// <param name="e"></param>
        public void IV_AcquireDataWithoutMoving(IVSettings settings, BackgroundWorker worker, DoWorkEventArgs e)
        {
            int finalFileNumber = settings.IVGeneralSettings.CurrentFileNumber;
            double[,] dataAcquired;
            List<IDataChannel> physicalChannels = new List<IDataChannel>();

            //
            // Save this run settings if desired
            //
            SaveSettingsIfNeeded(settings, settings.IVGeneralSettings.IsFileSavingRequired, settings.IVGeneralSettings.Path);

            //
            // apply initial voltage on the EM if needed
            //
            ApplyVoltageOnElectroMagnetIfNeeded(settings.IVSteppingMethodSettings.SteppingDevice == SteppingDevice.ElectroMagnet);


            //
            // create the input and output tasks
            //
            m_ivInputTask = GetContinuousAITask(settings.IVGeneralSettings.SampleRate, settings.ChannelsSettings.ActiveChannels, null);
            m_ivInputTask.Stream.ReadRelativeTo = ReadRelativeTo.FirstSample;
            m_outputTask = GetContinuousAOTask(settings);

            //
            // initiate writer for the output and set initial bias
            //
            InitiateOutputWriter(m_outputTask, settings);

            //
            // Main loop for data aquisition
            //
            for (int i = 0; i < settings.IVGeneralSettings.TotalNumberOfCycles; i++)
            {
                //
                // Cancel the operatin if user asked for
                //
                if (worker.CancellationPending == true)
                {
                    e.Cancel = true;
                    break;
                }

                m_quitRealTimeOperation = false;

                //
                // we set the votlage to triangle wave and then open the junction by the EM
                //
                writer.BeginWriteMultiSample(false, m_functionGenerator.TriangleWave, null, null);

                //
                // Start the input task.
                //
                try
                {
                    m_ivInputTask.Start();
                }
                catch (DaqException ex)
                {
                    throw new SBJException("Error occured when tryin to start DAQ input task", ex);
                }

                //
                // start reading continuously. 
                // when the junction is opened, the opening thread will change m_quitJuncctionOpeningOperation to true.
                // set dataAquired to null otherwise it saves last cycle's data. 
                //
                reader = new AnalogMultiChannelReader(m_ivInputTask.Stream);
                dataAcquired = null;
                try
                {
                    while (!m_quitRealTimeOperation)
                    {
                        try
                        {
                            dataAcquired = reader.ReadMultiSample(-1);
                        }
                        catch (DaqException)
                        {
                            continue;
                        }
                    }

                    if (dataAcquired != null)
                    {
                        if (settings.ChannelsSettings.ActiveChannels.Count != dataAcquired.GetLength(0))
                        {
                            throw new SBJException("Number of data channels doesn't fit the recieved data.");
                        }
                    }
                }
                catch (DaqException ex)
                {
                    //
                    // Probably timeout.
                    // Ignore this cycle and rerun.
                    //
                    m_ivInputTask.Stop();
                    continue;
                }

                //
                // At this point the reader has returned with all the data and we can stop the input task.
                //
                m_ivInputTask.Stop();

                //
                // if we didn't acquire any data, there's no need to save anything.
                //
                if (dataAcquired == null)
                {
                    continue;
                }

                //
                // Assign the aquired data for each channel.
                // First clear all data from previous interation.
                //                
                ClearRawData(settings.ChannelsSettings.ActiveChannels);
                AssignRawDataToChannels(settings.ChannelsSettings.ActiveChannels, dataAcquired);

                //
                // physical channel will include both simple and complex channels. 
                // 
                physicalChannels = GetChannelsForDisplay(settings.ChannelsSettings.ActiveChannels);

                //
                // calculate the physical data for each channel
                //
                GetPhysicalData(physicalChannels);

                //
                // the IV acquisition is done, we need to return the output to constant voltage for the next cycle
                //
                writer.BeginWriteMultiSample(false, m_functionGenerator.ConstWave, null, null);

                // 
                // Increase file number by one
                // Save data if needed
                //
                finalFileNumber++;
                if (settings.IVGeneralSettings.IsFileSavingRequired)
                {
                    finalFileNumber = SaveData(settings.IVGeneralSettings.Path, settings.ChannelsSettings.ActiveChannels, physicalChannels, finalFileNumber);
                }

                //
                // Signal UI we have the data
                //
                if (DataAquired != null)
                {
                    DataAquired(this, new DataAquiredEventArgs(physicalChannels, finalFileNumber));
                }
            }

            //
            // Finish the measurement properly
            //
            if (settings.IVSteppingMethodSettings.SteppingDevice == SteppingDevice.ElectroMagnet)
            {
                m_electroMagnet.Shutdown();
            }
            m_ivInputTask.Dispose();
            m_ivInputTask = null;
            m_outputTask.Dispose();
            m_outputTask = null;
            m_stepperMotor.Shutdown();
        }