예제 #1
0
        public void verify()
        {
            task.Timing.ConfigureSampleClock("", sampleRate, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples, sampleLength);
            task.Stream.Timeout = Math.Max(10000, (int)(sampleLength / sampleRate * 1000) + 1000);
            if (aowriter != null && outputWaveArray != null)
            {
                aowriter.WriteMultiSample(false, outputWaveArray);
            }
//			if (aireader != null) aireader.ReadMultiSample(1000);
            if (dowriter != null && byteArray != null)
            {
                dowriter.WriteMultiSamplePort(false, byteArray);
            }
            task.Control(TaskAction.Verify);
        }
        public void OutputPatternAndWait(double[,] pattern)
        {
            AnalogMultiChannelWriter writer = new AnalogMultiChannelWriter(analogOutputTask.Stream);

            writer.WriteMultiSample(false, pattern);
            analogOutputTask.Start();
        }
예제 #3
0
파일: DAQ.cs 프로젝트: jingxlim/FictiveVR
        void WriteThreadRun(AutoResetEvent stop, Func <long, int, double[, ]> sampleFunction)
        {
            Task writeTask = new Task("EphysWrite");

            double[,] firstSamples = sampleFunction(0, HardwareSettings.DAQ.Rate);
            if (firstSamples.GetLength(1) != HardwareSettings.DAQ.Rate)
            {
                throw new ApplicationException("Did not receive the required number of samples");
            }
            var nChannels = firstSamples.GetLength(0);

            for (int i = 0; i < nChannels; i++)
            {
                writeTask.AOChannels.CreateVoltageChannel(HardwareSettings.DAQ.DeviceName + "/" + string.Format("AO{0}", i), "", -10, 10, AOVoltageUnits.Volts);
            }
            //Note: Can't use ai clock, since we cannot guarantee that the read thread ai task finishes *after* the write task
            //otherwise Task.Stop will block indefinitely...
            writeTask.Timing.ConfigureSampleClock("", HardwareSettings.DAQ.Rate, SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples);
            writeTask.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger("ai/StartTrigger ", DigitalEdgeStartTriggerEdge.Rising);
            writeTask.Stream.WriteRegenerationMode = WriteRegenerationMode.DoNotAllowRegeneration;
            AnalogMultiChannelWriter dataWriter = new AnalogMultiChannelWriter(writeTask.Stream);

            dataWriter.WriteMultiSample(false, firstSamples);
            writeTask.Start();
            _writeThreadReady.Set();
            long start_sample = HardwareSettings.DAQ.Rate;

            try
            {
                while (!stop.WaitOne(50))
                {
                    double[,] samples = sampleFunction(start_sample, HardwareSettings.DAQ.Rate / 5);
                    if (samples == null)
                    {
                        break;
                    }
                    dataWriter.WriteMultiSample(false, samples);
                    start_sample += HardwareSettings.DAQ.Rate / 5;
                }
                System.Diagnostics.Debug.WriteLine("Left write loop");
            }
            finally
            {
                writeTask.Stop();
                writeTask.Dispose();
            }
        }
예제 #4
0
        public void Write()
        {
            try {
                string[] channelNameList = DaqSystem.Local.GetPhysicalChannels(PhysicalChannelTypes.AO, PhysicalChannelAccess.External);
                if (channelNameList.Length > 0)
                {
                    Task task1 = new Task();
                    task1.AOChannels.CreateVoltageChannel(channelNameList[0], "Voltage1", 0, 10, AOVoltageUnits.Volts);
                    task1.AOChannels.CreateVoltageChannel(channelNameList[1], "Voltage2", 0, 10, AOVoltageUnits.Volts);
                    task1.AOChannels.CreateVoltageChannel(channelNameList[2], "Voltage3", 0, 10, AOVoltageUnits.Volts);
                    task1.Timing.ConfigureSampleClock("", 100, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples);
                    task1.Control(TaskAction.Verify);
                    Task task2 = new Task();
                    task2.AOChannels.CreateVoltageChannel(channelNameList[0], "Voltage1", 0, 10, AOVoltageUnits.Volts);
                    task2.AOChannels.CreateVoltageChannel(channelNameList[1], "Voltage2", 0, 10, AOVoltageUnits.Volts);
                    task2.AOChannels.CreateVoltageChannel(channelNameList[2], "Voltage3", 0, 10, AOVoltageUnits.Volts);
                    task2.Timing.ConfigureSampleClock("", 100, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples);
                    task2.Control(TaskAction.Verify);

                    AnalogMultiChannelWriter aowriter1 = new AnalogMultiChannelWriter(task1.Stream);
                    AnalogMultiChannelWriter aowriter2 = new AnalogMultiChannelWriter(task2.Stream);

                    double[,] wave = new double[3, 1000];
                    for (int i = 0; i < 3; i++)
                    {
                        for (int j = 0; j < 1000; j++)
                        {
                            wave[i, j] = 0.001 * (1000 - j);
                        }
                    }

                    Console.WriteLine("Task is ready");
                    aowriter1.WriteMultiSample(false, wave);
                    task1.Control(TaskAction.Start);
                    Console.ReadKey();
                    task1.Control(TaskAction.Stop);
                    task1.Control(TaskAction.Unreserve);
                    Console.WriteLine("Task1 is released");
                    aowriter2.WriteMultiSample(false, wave);
                    task1.Control(TaskAction.Start);
                    Console.ReadKey();
                    task1.Control(TaskAction.Stop);
                    task1.Control(TaskAction.Unreserve);
                    Console.ReadKey();
                }
            } catch (DaqException e) {
                Console.Out.WriteLine(e.Message);
            }
        }
예제 #5
0
 private void zap()
 {
     //lock (this)
     //{
     stimAnalogWriter.WriteMultiSample(true, sp.analogPulse);
     //if (Properties.Settings.Default.StimPortBandwidth == 32)
     stimDigitalWriter.WriteMultiSamplePort(true, sp.digitalData);
     //else if (Properties.Settings.Default.StimPortBandwidth == 8)
     //    stimDigitalWriter.WriteMultiSamplePort(true, StimPulse.convertTo8Bit(sp.digitalData));
     stimDigitalTask.WaitUntilDone();
     stimAnalogTask.WaitUntilDone();
     stimAnalogTask.Stop();
     stimDigitalTask.Stop();
     //}
 }
        /// <summary>
        /// This method creates analog and digital output buffers for daqMx cards. Note that the daqmx library seems to only support
        /// either analog OR digital on a given card at one time. Despite the fact that this method will create both types of buffers,
        /// it will probably throw some daqMX level exceptions if asked to create both analog and digital buffers for the same device.
        /// </summary>
        /// <param name="deviceName"></param>
        /// <param name="deviceSettings"></param>
        /// <param name="sequence"></param>
        /// <param name="settings"></param>
        /// <param name="usedDigitalChannels">digital channels which reside on this server.</param>
        /// <param name="usedAnalogChannels">analog channels which reside on this server</param>
        /// <returns></returns>
        public static Task createDaqMxTask(string deviceName, DeviceSettings deviceSettings, SequenceData sequence, 
            SettingsData settings, Dictionary<int, HardwareChannel> usedDigitalChannels, Dictionary<int, HardwareChannel> usedAnalogChannels,
            ServerSettings serverSettings, out long expectedSamplesGenerated)
        {
            expectedSamplesGenerated = 0;

            Task task = new Task(deviceName + " output task");

            List<int> analogIDs;
            List<HardwareChannel> analogs;
            Dictionary<int, int[]> port_digital_IDs;
            List<int> usedPortNumbers;

            // Parse and create channels.
            parseAndCreateChannels(deviceName,deviceSettings, usedDigitalChannels, usedAnalogChannels, task, out analogIDs, out analogs, out port_digital_IDs, out usedPortNumbers);

            if (analogIDs.Count != 0)
            {
                if (deviceSettings.UseCustomAnalogTransferSettings)
                {
                    task.AOChannels.All.DataTransferMechanism = deviceSettings.AnalogDataTransferMechanism;
                    task.AOChannels.All.DataTransferRequestCondition = deviceSettings.AnalogDataTransferCondition;
                }
            }
            if (usedPortNumbers.Count != 0)
            {
                if (deviceSettings.UseCustomDigitalTransferSettings)
                {
                    task.DOChannels.All.DataTransferMechanism = deviceSettings.DigitalDataTransferMechanism;
                    task.DOChannels.All.DataTransferRequestCondition = deviceSettings.DigitalDataTransferCondition;
                }
            }

            // ok! now create the buffers

            #region NON variable timebase buffer
            if (deviceSettings.UsingVariableTimebase == false)
            {
                // non "variable timebase" buffer creation

                double timeStepSize = 1.0 / (double)deviceSettings.SampleClockRate;
                int nBaseSamples = sequence.nSamples(timeStepSize);

                // for reasons that are utterly stupid and frustrating, the DAQmx libraries seem to prefer sample
                // buffers with lengths that are a multiple of 4. (otherwise they, on occasion, depending on the parity of the
                // number of channels, throw exceptions complaining.
                // thus we add a few filler samples at the end of the sequence which parrot back the last sample.

                int nFillerSamples = 4 - nBaseSamples % 4;
                if (nFillerSamples == 4)
                    nFillerSamples = 0;

                int nSamples = nBaseSamples + nFillerSamples;

                if (deviceSettings.MySampleClockSource == DeviceSettings.SampleClockSource.DerivedFromMaster)
                {
                    task.Timing.ConfigureSampleClock("", deviceSettings.SampleClockRate, deviceSettings.ClockEdge, SampleQuantityMode.FiniteSamples, nSamples);
                }
                else
                {
                    task.Timing.ConfigureSampleClock(deviceSettings.SampleClockExternalSource, deviceSettings.SampleClockRate, deviceSettings.ClockEdge, SampleQuantityMode.FiniteSamples, nSamples);
                }
                if (deviceSettings.MasterTimebaseSource != "" && deviceSettings.MasterTimebaseSource != null)
                {
                    task.Timing.MasterTimebaseSource = deviceSettings.MasterTimebaseSource.ToString();
                }

                // Analog first...

                if (analogIDs.Count != 0)
                {
                    double[,] analogBuffer;
                    double[] singleChannelBuffer;
                    try
                    {
                        analogBuffer = new double[analogs.Count, nSamples];
                        singleChannelBuffer = new double[nSamples];
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Unable to allocate analog buffer for device " + deviceName + ". Reason: " + e.Message + "\n" + e.StackTrace);
                    }

                    for (int i = 0; i < analogIDs.Count; i++)
                    {
                        int analogID = analogIDs[i];

                        if (settings.logicalChannelManager.Analogs[analogID].TogglingChannel)
                        {
                            DaqMxTaskGenerator.getAnalogTogglingBuffer(singleChannelBuffer);
                        }
                        else if (settings.logicalChannelManager.Analogs[analogID].overridden)
                        {
                            for (int j = 0; j < singleChannelBuffer.Length; j++)
                            {
                                singleChannelBuffer[j] = settings.logicalChannelManager.Analogs[analogID].analogOverrideValue;
                            }
                        }
                        else
                        {
                            sequence.computeAnalogBuffer(analogIDs[i], timeStepSize, singleChannelBuffer);
                        }

                        for (int j = 0; j < nBaseSamples; j++)
                        {
                            analogBuffer[i, j] = singleChannelBuffer[j];
                        }
                        for (int j = nBaseSamples; j < nSamples; j++)
                        {
                            analogBuffer[i, j] = analogBuffer[i, j - 1];
                        }
                    }

                    singleChannelBuffer = null;
                    System.GC.Collect();

                    AnalogMultiChannelWriter writer = new AnalogMultiChannelWriter(task.Stream);

                    writer.WriteMultiSample(false, analogBuffer);
                    // analog cards report the exact number of generated samples. for non-variable timebase this is nSamples
                    expectedSamplesGenerated = nSamples;

                }

                if (usedPortNumbers.Count != 0)
                {
                    byte[,] digitalBuffer;
                    bool[] singleChannelBuffer;

                    try
                    {
                        digitalBuffer = new byte[usedPortNumbers.Count, nSamples];
                        singleChannelBuffer = new bool[nSamples];
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Unable to allocate digital buffer for device " + deviceName + ". Reason: " + e.Message + "\n" + e.StackTrace);
                    }

                    for (int i = 0; i < usedPortNumbers.Count; i++)
                    {
                        int portNum = usedPortNumbers[i];
                        byte digitalBitMask = 1;
                        for (int lineNum = 0; lineNum < 8; lineNum++)
                        {
                            int digitalID = port_digital_IDs[portNum][lineNum];
                            if (digitalID != -1)
                            {
                                if (settings.logicalChannelManager.Digitals[digitalID].TogglingChannel)
                                {
                                    getDigitalTogglingBuffer(singleChannelBuffer);
                                }
                                else if (settings.logicalChannelManager.Digitals[digitalID].overridden)
                                {
                                    for (int j = 0; j < singleChannelBuffer.Length; j++)
                                    {
                                        singleChannelBuffer[j] = settings.logicalChannelManager.Digitals[digitalID].digitalOverrideValue;
                                    }
                                }
                                else
                                {

                                    sequence.computeDigitalBuffer(digitalID, timeStepSize, singleChannelBuffer);
                                }
                                // byte digitalBitMask = (byte)(((byte) 2)^ ((byte)lineNum));
                                for (int j = 0; j < nBaseSamples; j++)
                                {
                                    // copy the bit value into the digital buffer byte.
                                    if (singleChannelBuffer[j])
                                        digitalBuffer[i, j] |= digitalBitMask;
                                }

                            }
                            digitalBitMask = (byte)(digitalBitMask << 1);
                        }
                        for (int j = nBaseSamples; j < nSamples; j++)
                        {
                            digitalBuffer[i, j] = digitalBuffer[i, j - 1];
                        }
                    }
                    singleChannelBuffer = null;
                    System.GC.Collect();
                    DigitalMultiChannelWriter writer = new DigitalMultiChannelWriter(task.Stream);
                    writer.WriteMultiSamplePort(false, digitalBuffer);
                    /// Digital cards report the number of generated samples as a multiple of 4
                    expectedSamplesGenerated = nSamples;
                }
            }
            #endregion
            #region Variable timebase buffer creation
            else // variable timebase buffer creation...
            {

                double timeStepSize = 1.0 / (double)deviceSettings.SampleClockRate;

                TimestepTimebaseSegmentCollection timebaseSegments =
            sequence.generateVariableTimebaseSegments(serverSettings.VariableTimebaseType,
                                            timeStepSize);

                int nBaseSamples = timebaseSegments.nSegmentSamples();

                nBaseSamples++; // add one sample for the dwell sample at the end of the buffer

                // for reasons that are utterly stupid and frustrating, the DAQmx libraries seem to prefer sample
                // buffers with lengths that are a multiple of 4. (otherwise they, on occasion, depending on the parity of the
                // number of channels, throw exceptions complaining.
                // thus we add a few filler samples at the end of the sequence which parrot back the last sample.

                int nFillerSamples = 4 - nBaseSamples % 4;
                if (nFillerSamples == 4)
                    nFillerSamples = 0;

                int nSamples = nBaseSamples + nFillerSamples;

                if (deviceSettings.MySampleClockSource == DeviceSettings.SampleClockSource.DerivedFromMaster)
                {
                    throw new Exception("Attempt to use a uniform sample clock with a variable timebase enabled device. This will not work. To use a variable timebase for this device, you must specify an external sample clock source.");
                }
                else
                {
                    task.Timing.ConfigureSampleClock(deviceSettings.SampleClockExternalSource, deviceSettings.SampleClockRate, deviceSettings.ClockEdge, SampleQuantityMode.FiniteSamples, nSamples);
                }

                // Analog first...

                if (analogIDs.Count != 0)
                {
                    double[,] analogBuffer;
                    double[] singleChannelBuffer;
                    try
                    {
                        analogBuffer = new double[analogs.Count, nSamples];
                        singleChannelBuffer = new double[nSamples];
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Unable to allocate analog buffer for device " + deviceName + ". Reason: " + e.Message + "\n" + e.StackTrace);
                    }

                    for (int i = 0; i < analogIDs.Count; i++)
                    {
                        int analogID = analogIDs[i];

                        if (settings.logicalChannelManager.Analogs[analogID].TogglingChannel)
                        {
                            getAnalogTogglingBuffer(singleChannelBuffer);
                        }
                        else if (settings.logicalChannelManager.Analogs[analogID].overridden)
                        {
                            for (int j = 0; j < singleChannelBuffer.Length; j++)
                            {
                                singleChannelBuffer[j] = settings.logicalChannelManager.Analogs[analogID].analogOverrideValue;
                            }
                        }
                        else
                        {
                            sequence.computeAnalogBuffer(analogIDs[i], timeStepSize, singleChannelBuffer, timebaseSegments);
                        }
                        for (int j = 0; j < nBaseSamples; j++)
                        {
                            analogBuffer[i, j] = singleChannelBuffer[j];
                        }
                        for (int j = nBaseSamples; j < nSamples; j++)
                        {
                            analogBuffer[i, j] = analogBuffer[i, j - 1];
                        }
                    }

                    singleChannelBuffer = null;
                    System.GC.Collect();

                    AnalogMultiChannelWriter writer = new AnalogMultiChannelWriter(task.Stream);

                    writer.WriteMultiSample(false, analogBuffer);
                    // Analog cards report the exact number of samples generated. for variable timebase this is nBaseSamples
                    expectedSamplesGenerated = nBaseSamples;

                }

                if (usedPortNumbers.Count != 0)
                {
                    byte[,] digitalBuffer;
                    bool[] singleChannelBuffer;

                    try
                    {
                        digitalBuffer = new byte[usedPortNumbers.Count, nSamples];
                        singleChannelBuffer = new bool[nSamples];
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Unable to allocate digital buffer for device " + deviceName + ". Reason: " + e.Message + "\n" + e.StackTrace);
                    }

                    for (int i = 0; i < usedPortNumbers.Count; i++)
                    {
                        int portNum = usedPortNumbers[i];
                        byte digitalBitMask = 1;
                        for (int lineNum = 0; lineNum < 8; lineNum++)
                        {
                            int digitalID = port_digital_IDs[portNum][lineNum];
                            if (digitalID != -1)
                            {
                                if (settings.logicalChannelManager.Digitals[digitalID].TogglingChannel)
                                {
                                    getDigitalTogglingBuffer(singleChannelBuffer);
                                }
                                else if (settings.logicalChannelManager.Digitals[digitalID].overridden)
                                {
                                    for (int j = 0; j < singleChannelBuffer.Length; j++)
                                    {
                                        singleChannelBuffer[j] = settings.logicalChannelManager.Digitals[digitalID].digitalOverrideValue;
                                    }
                                }
                                else
                                {

                                    sequence.computeDigitalBuffer(digitalID, timeStepSize, singleChannelBuffer, timebaseSegments);
                                }
                                // byte digitalBitMask = (byte)(((byte) 2)^ ((byte)lineNum));
                                for (int j = 0; j < nBaseSamples; j++)
                                {
                                    // copy the bit value into the digital buffer byte.
                                    if (singleChannelBuffer[j])
                                        digitalBuffer[i, j] |= digitalBitMask;
                                }

                            }
                            digitalBitMask = (byte)(digitalBitMask << 1);
                        }
                        for (int j = nBaseSamples; j < nSamples; j++)
                        {
                            digitalBuffer[i, j] = digitalBuffer[i, j - 1];
                        }
                    }
                    singleChannelBuffer = null;
                    System.GC.Collect();
                    DigitalMultiChannelWriter writer = new DigitalMultiChannelWriter(task.Stream);
                    writer.WriteMultiSamplePort(false, digitalBuffer);
                    // digital cards report number of samples generated up to multiple of 4
                    expectedSamplesGenerated = nSamples;
                }
            }

            #endregion

            if (deviceSettings.StartTriggerType == DeviceSettings.TriggerType.TriggerIn)
            {

                task.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger(
                    deviceSettings.TriggerInPort,
                    DigitalEdgeStartTriggerEdge.Rising);

            }

            task.Control(TaskAction.Verify);
            task.Control(TaskAction.Commit);
            task.Control(TaskAction.Reserve);

            return task;
        }
예제 #7
0
        private void button_electrolesioningStart_Click(object sender, EventArgs e)
        {
            //Change mouse cursor to waiting cursor
            this.Cursor = Cursors.WaitCursor;

            //Grab values from UI
            double voltage = Convert.ToDouble(numericUpDown_electrolesioningVoltage.Value);
            double duration = Convert.ToDouble(numericUpDown_electrolesioningDuration.Value);
            List<Int32> chList = new List<int>(listBox_electrolesioningChannels.SelectedIndices.Count);
            for (int i = 0; i < listBox_electrolesioningChannels.SelectedIndices.Count; ++i)
                chList.Add(listBox_electrolesioningChannels.SelectedIndices[i] + 1); //+1 since indices are 0-based but channels are 1-base

            //Disable buttons, so users don't try running two experiments at once
            button_electrolesioningStart.Enabled = false;
            button_electrolesioningSelectAll.Enabled = false;
            button_electrolesioningSelectNone.Enabled = false;
            button_electrolesioningStart.Refresh();

            //Refresh stim task
            stimDigitalTask.Dispose();
            stimDigitalTask = new Task("stimDigitalTask_Electrolesioning");
            if (Properties.Settings.Default.StimPortBandwidth == 32)
                stimDigitalTask.DOChannels.CreateChannel(Properties.Settings.Default.StimulatorDevice + "/Port0/line0:31", "",
                    ChannelLineGrouping.OneChannelForAllLines); //To control MUXes
            else if (Properties.Settings.Default.StimPortBandwidth == 8)
                stimDigitalTask.DOChannels.CreateChannel(Properties.Settings.Default.StimulatorDevice + "/Port0/line0:7", "",
                    ChannelLineGrouping.OneChannelForAllLines); //To control MUXes
            stimDigitalWriter = new DigitalSingleChannelWriter(stimDigitalTask.Stream);

            //Refresh pulse task
            stimPulseTask.Dispose();
            stimPulseTask = new Task("stimPulseTask");
            if (Properties.Settings.Default.StimPortBandwidth == 32)
            {
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao0", "", -10.0, 10.0, AOVoltageUnits.Volts); //Triggers
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao1", "", -10.0, 10.0, AOVoltageUnits.Volts); //Triggers
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao2", "", -10.0, 10.0, AOVoltageUnits.Volts); //Actual Pulse
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao3", "", -10.0, 10.0, AOVoltageUnits.Volts); //Timing
            }
            else if (Properties.Settings.Default.StimPortBandwidth == 8)
            {
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao0", "", -10.0, 10.0, AOVoltageUnits.Volts);
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao1", "", -10.0, 10.0, AOVoltageUnits.Volts);
            }

            stimPulseWriter = new AnalogMultiChannelWriter(stimPulseTask.Stream);

            stimPulseTask.Timing.ConfigureSampleClock("",
                StimPulse.STIM_SAMPLING_FREQ, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples);
            stimPulseTask.Timing.SamplesPerChannel = 2;

            stimDigitalTask.Control(TaskAction.Verify);
            stimPulseTask.Control(TaskAction.Verify);

            //For each channel, deliver lesioning pulse
            for (int i = 0; i < chList.Count; ++i)
            {
                int channel = chList[i];
                UInt32 data = StimPulse.channel2MUX((double)channel);

                //Setup digital waveform, open MUX channel
                stimDigitalWriter.WriteSingleSamplePort(true, data);
                stimDigitalTask.WaitUntilDone();
                stimDigitalTask.Stop();

                //Write voltage to channel, wait duration, stop
                stimPulseWriter.WriteMultiSample(true, new double[,] { { 0, 0 }, { 0, 0 }, { voltage, voltage }, { 0, 0 } });
                stimPulseTask.WaitUntilDone();
                stimPulseTask.Stop();
                Thread.Sleep((int)(Math.Round(duration * 1000))); //Convert to ms
                stimPulseWriter.WriteMultiSample(true, new double[,] { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } });
                stimPulseTask.WaitUntilDone();
                stimPulseTask.Stop();

                //Close MUX
                stimDigitalWriter.WriteSingleSamplePort(true, 0);
                stimDigitalTask.WaitUntilDone();
                stimDigitalTask.Stop();
            }

            bool[] fData = new bool[Properties.Settings.Default.StimPortBandwidth];
            stimDigitalWriter.WriteSingleSampleMultiLine(true, fData);
            stimDigitalTask.WaitUntilDone();
            stimDigitalTask.Stop();

            button_electrolesioningSelectAll.Enabled = true;
            button_electrolesioningSelectNone.Enabled = true;
            button_electrolesioningStart.Enabled = true;

            //Now, destroy the objects we made
            updateSettings();
            this.Cursor = Cursors.Default;
        }
예제 #8
0
        private void TimedMove(double __dCycleTime, double[,] __dCoordinates, int[] __iLevels, bool master, bool continuous)
        {
            Stopwatch watch = new Stopwatch();

            watch.Start();
            _logger.Debug("Start:" + watch.ElapsedMilliseconds.ToString());
            int _iSamplesPerChannel = __dCoordinates.Length / 3;

            // Prepare the stage control task for writing as many samples as necessary to complete Move.
            this.Configure(__dCycleTime, _iSamplesPerChannel, master, continuous);

            AnalogMultiChannelWriter writerA = new AnalogMultiChannelWriter(this.m_daqtskMoveStage.Stream);
            DigitalSingleChannelWriter writerD = new DigitalSingleChannelWriter(this.m_daqtskLineTrigger.Stream);

            try
            {
                // Perform the actual AO write.
                writerA.WriteMultiSample(false, __dCoordinates);
                writerD.WriteMultiSamplePort(false, __iLevels);
                _logger.Debug("End write:" + watch.ElapsedMilliseconds.ToString());

                // Start all four tasks in the correct order. Global sync should be last.
                this.m_daqtskLineTrigger.Start();
                this.m_daqtskMoveStage.Start();
                if (this.m_bMaster && this.m_sampleClock != null)
                {
                    this.m_sampleClock.Start(this.m_samplePeriod);
                }
            }

            catch (Exception ex)
            {
                _logger.Error("Something went wrong! : \r\n", ex);
                m_daqtskMoveStage.Stop();
            }
        }
예제 #9
0
        public int Configure_Start_Single_Measurement(Parameters Parameters_Instance
                                                      )
        {
            StopTask(); // ensure clear tasks before measurement

            string ParametersFileName = Parameters_Instance.Output_File + ".json";

            using (System.IO.StreamWriter file =
                       new System.IO.StreamWriter(ParametersFileName))
            {
                file.Write(JsonConvert.SerializeObject(Parameters_Instance, Formatting.Indented));
            }

            _Parameters_Instance = Parameters_Instance;
            if (_Parameters_Instance.NumberOfSamples == "Infinite")
            {
                Number_Of_Samples_Reqired     = -1;
                Is_Number_Of_Samples_Infinite = true;
            }
            else
            {
                Is_Number_Of_Samples_Infinite = false;
                try
                {
                    Number_Of_Samples_Reqired = int.Parse(_Parameters_Instance.NumberOfSamples);
                } catch (Exception)
                {
                    StopTask();
                    MessageBox.Show("Number of samples is not an integer number or 'Infinite'.");
                    return(1);
                }
            }
            Number_Of_Samples_Measured = 0;

            // Find output data format in case of text output
            if (Parameters_Instance.Input_Channel_Value_Save_Format.Substring(0, 4).ToLower() == "text")
            {
                int Index2 = Parameters_Instance.Input_Channel_Value_Save_Format.LastIndexOf(")");
                int Index1 = Parameters_Instance.Input_Channel_Value_Save_Format.IndexOf("(");
                Input_Channel_Value_Save_Format_Syntax = Parameters_Instance.Input_Channel_Value_Save_Format.Substring(Index1 + 1, Index2 - Index1 - 1);
                MainWindow.WindowInstance.Dispatcher.BeginInvoke(new MainWindow.Append_Log_Delegate(MainWindow.WindowInstance.Append_Log),
                                                                 "Output syntax:" + Input_Channel_Value_Save_Format_Syntax + "\n"
                                                                 );
            }

            // Sync pulse
            double Sync_PulseVoltage            = +4.9; // [V]
            double Sync_IdileVoltage            = 0.0;
            int    NumberOfSamples_During_Pulse = 10;
            double WritingRate_Pulse            = NumberOfSamples_During_Pulse / Parameters_Instance.Pulse_Width;


            double[,] Output_Data = new double[2, NumberOfSamples_During_Pulse + 1];
            for (int i = 0; i < NumberOfSamples_During_Pulse; i++)
            {
                Output_Data[0, i] = Sync_PulseVoltage;
                Output_Data[1, i] = Parameters_Instance.Pulse_Voltage;
            }
            Output_Data[0, NumberOfSamples_During_Pulse] = Sync_IdileVoltage;
            Output_Data[1, NumberOfSamples_During_Pulse] = Parameters_Instance.Reverse_Voltage;

            try
            {
                // Create the master and slave tasks
                inputTask  = new Task("InputTask");
                outputTask = new Task("OutputTask");

                // Configure both tasks with the values selected on the UI. #SyncTask
                inputTask.AIChannels.CreateVoltageChannel(Parameters_Instance.Input_Channel,
                                                          "InputChannel",
                                                          AITerminalConfiguration.Differential,
                                                          Parameters_Instance.Input_Channel_MinVoltage,
                                                          Parameters_Instance.Input_Channel_MaxVoltage,
                                                          AIVoltageUnits.Volts);

                outputTask.AOChannels.CreateVoltageChannel(Parameters_Instance.Sync_Channel,
                                                           "",
                                                           Convert.ToDouble(0.0),
                                                           Convert.ToDouble(5.0),
                                                           AOVoltageUnits.Volts);
                outputTask.AOChannels.CreateVoltageChannel(Parameters_Instance.Output_Channel,
                                                           "",
                                                           Parameters_Instance.Output_Channel_MinVoltage,
                                                           Parameters_Instance.Output_Channel_MaxVoltage,
                                                           AOVoltageUnits.Volts);

                // Output pulse
                inputTask.Timing.ConfigureSampleClock("",
                                                      Parameters_Instance.Sampling_Rate,
                                                      SampleClockActiveEdge.Rising,
                                                      SampleQuantityMode.ContinuousSamples,
                                                      Parameters_Instance.BufferSize);
                outputTask.Timing.ConfigureSampleClock("",
                                                       WritingRate_Pulse,
                                                       SampleClockActiveEdge.Rising,
                                                       SampleQuantityMode.FiniteSamples,
                                                       NumberOfSamples_During_Pulse + 1);

                // Set up the start trigger
                DigitalEdgeStartTriggerEdge Input_triggerEdge = DigitalEdgeStartTriggerEdge.Falling;
                inputTask.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger(Parameters_Instance.Trigger_Channel,
                                                                            Input_triggerEdge);

                // Verify the tasks
                inputTask.Control(TaskAction.Verify);
                outputTask.Control(TaskAction.Verify);

                // Write data to each output channel
                Output_Writer = new AnalogMultiChannelWriter(outputTask.Stream);
                Output_Writer.WriteMultiSample(false, Output_Data);

                inputTask.Start();

                inputCallback = new AsyncCallback(InputRead);
                Input_Reader  = new AnalogSingleChannelReader(inputTask.Stream);
                //// Use SynchronizeCallbacks to specify that the object
                //// marshals callbacks across threads appropriately.
                Input_Reader.SynchronizeCallbacks = true;
                Input_Reader.BeginReadMultiSample(Parameters_Instance.BufferSize, inputCallback, inputTask);

                // Generate Sync pulse

                //syncTask.Start();
                outputTask.Start();

                MainWindow.WindowInstance.Dispatcher.BeginInvoke(new MainWindow.Append_Log_Delegate(MainWindow.WindowInstance.Append_Log),
                                                                 "Done: Configure_Start " + Number_Of_measurements_Measured_string + "\n"
                                                                 );
                //inputTask.WaitUntilDone();
            }
            catch (Exception ex)
            {
                StopTask();
                MessageBox.Show(ex.Message);
                return(1);
            }
            return(0);
        }
예제 #10
0
        void daqTask2_EveryNSamplesWritten(object sender, EveryNSamplesWrittenEventArgs e)
        {
            try
            {
                if (logTrackingData && file != null)
                {
                    file.Write(dcOffsetX + " " + dcOffsetY + " ");
                }

                int theta = (int)(360 - (phase - numericUpDown1.Value)) % 180;


                if (logTrackingData && file != null)
                {
                    file.WriteLine(dcOffsetX + " " + dcOffsetY);
                }

                // dc offsets
                double filtdc = 0.6;
                thetaOff = ((double)numericUpDown1.Value * Math.PI / 180.0);
                double dx = dcOffsetX, dy = dcOffsetY;
                double threshold1 = 6.5, threshold2 = 1;

                double ct = Math.Cos(thetaOff);
                double st = Math.Sin(thetaOff);

                double tmpx = dx;
                dx = ct * dx + st * dy;
                dy = st * tmpx - ct * dy;

                dx = filtdc * (dx) + (1 - filtdc) * prevDcX;
                dy = filtdc * (dy) + (1 - filtdc) * prevDcY;

                if (dx < -1 * threshold1)
                {
                    dx = -1 * threshold1;
                }
                else if (dx > threshold1)
                {
                    dx = threshold1;
                }

                if (dy < -1 * threshold1)
                {
                    dy = -1 * threshold1;
                }
                else if (dy > threshold1)
                {
                    dy = threshold1;
                }

                dx      = Math.Round(dx, 3);
                dy      = Math.Round(dy, 3);
                prevDcX = dx;
                prevDcY = dy;

                int count = 0, i = sampleIndex, j = sampleIndex2;
                while (count <= samplePerChannel - 1)
                {
                    outWave[0, count] = waveX[theta][i] + dx;
                    outWave[1, count] = waveY[theta][i] + dy;
                    i++;
                    if (i >= ZX1[ZX1.Length - 3])
                    {
                        i = ZX1[1];
                    }
                    j++;
                    if (i >= ZX2[ZX2.Length - 3])
                    {
                        j = ZX2[1];
                    }
                    count++;
                }

                sampleIndex  = i;
                sampleIndex2 = j;

                //AnalogWaveform<double>[] waves = { AnalogWaveform<double>.FromArray1D(X), AnalogWaveform<double>.FromArray1D(Y) };
                //writer.WriteWaveform<double>(true, waves);
                writer.WriteMultiSample(true, outWave);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
 public void OutputPatternAndWait(double[,] pattern)
 {
     AnalogMultiChannelWriter writer = new AnalogMultiChannelWriter(analogOutputTask.Stream);
     writer.WriteMultiSample(false, pattern);
     analogOutputTask.Start();
 }
예제 #12
0
        private void WriteAnalog(IDictionary<Channel, double[]> output, int nsamples)
        {
            var data = new double[output.Count, nsamples];
            var chans = DAQTasks.AOChannels.Cast<AOChannel>().ToList();

            foreach (var o in output)
            {
                int chanIndex = chans.FindIndex(c => c.PhysicalName == o.Key.PhysicalName);
                for (int i = 0; i < o.Value.Count(); i++)
                {
                    data[chanIndex, i] = o.Value[i];
                }
            }

            var writer = new AnalogMultiChannelWriter(DAQTasks.AOStream);
            writer.WriteMultiSample(false, data);
        }
예제 #13
0
        public void Write()
        {
            try {
                string[] channelNameList = DaqSystem.Local.GetPhysicalChannels(PhysicalChannelTypes.AO, PhysicalChannelAccess.External);
                if (channelNameList.Length > 0) {
                    Task task1 = new Task();
                    task1.AOChannels.CreateVoltageChannel(channelNameList[0], "Voltage1", 0, 10, AOVoltageUnits.Volts);
                    task1.AOChannels.CreateVoltageChannel(channelNameList[1], "Voltage2", 0, 10, AOVoltageUnits.Volts);
                    task1.AOChannels.CreateVoltageChannel(channelNameList[2], "Voltage3", 0, 10, AOVoltageUnits.Volts);
                    task1.Timing.ConfigureSampleClock("", 100, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples);
                    task1.Control(TaskAction.Verify);
                    Task task2 = new Task();
                    task2.AOChannels.CreateVoltageChannel(channelNameList[0], "Voltage1", 0, 10, AOVoltageUnits.Volts);
                    task2.AOChannels.CreateVoltageChannel(channelNameList[1], "Voltage2", 0, 10, AOVoltageUnits.Volts);
                    task2.AOChannels.CreateVoltageChannel(channelNameList[2], "Voltage3", 0, 10, AOVoltageUnits.Volts);
                    task2.Timing.ConfigureSampleClock("", 100, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples);
                    task2.Control(TaskAction.Verify);

                    AnalogMultiChannelWriter aowriter1 = new AnalogMultiChannelWriter(task1.Stream);
                    AnalogMultiChannelWriter aowriter2 = new AnalogMultiChannelWriter(task2.Stream);

                    double[,] wave = new double[3, 1000];
                    for (int i = 0; i < 3; i++)
                    {
                        for (int j = 0; j < 1000; j++)
                        {
                            wave[i,j] = 0.001*(1000-j);
                        }
                    }

                    Console.WriteLine("Task is ready");
                    aowriter1.WriteMultiSample(false, wave);
                    task1.Control(TaskAction.Start);
                    Console.ReadKey();
                    task1.Control(TaskAction.Stop);
                    task1.Control(TaskAction.Unreserve);
                    Console.WriteLine("Task1 is released");
                    aowriter2.WriteMultiSample(false, wave);
                    task1.Control(TaskAction.Start);
                    Console.ReadKey();
                    task1.Control(TaskAction.Stop);
                    task1.Control(TaskAction.Unreserve);
                    Console.ReadKey();
                }
            } catch (DaqException e) {
                Console.Out.WriteLine(e.Message);
            }
        }
예제 #14
0
        //call this method after changing stimulation settings, or finishing a stimulation experiment
        //includes code to set dc offsets back to zero
        private void updateStim()
        {
            lock (this)
            {
                bool placedzeros = false;

                if (stimPulseTask != null || stimDigitalTask != null)
                {
                    try
                    {
                        // If we were ruuning a closed loop or open-loop protocol, this will zero the outputs
                        double[,] AnalogBuffer = new double[stimPulseTask.AOChannels.Count, STIMBUFFSIZE]; // buffer for analog channels
                        UInt32[] DigitalBuffer = new UInt32[STIMBUFFSIZE];

                        stimPulseTask.Stop();
                        stimDigitalTask.Stop();

                        stimPulseWriter.WriteMultiSample(true, AnalogBuffer);
                        stimDigitalWriter.WriteMultiSamplePort(true, DigitalBuffer);

                        stimPulseTask.WaitUntilDone(20);
                        stimDigitalTask.WaitUntilDone(20);

                        stimPulseTask.Stop();
                        stimDigitalTask.Stop();
                        placedzeros = true;
                    }
                    catch (Exception ex)
                    {
                        placedzeros = false;
                    }
                }
                if (stimDigitalTask != null)
                {
                    stimDigitalTask.Dispose();
                    stimDigitalTask = null;
                }
                if (stimPulseTask != null)
                {
                    stimPulseTask.Dispose();
                    stimPulseTask = null;
                }

                if (Properties.Settings.Default.UseStimulator)
                {
                    stimPulseTask   = new Task("stimPulseTask");
                    stimDigitalTask = new Task("stimDigitalTask");
                    if (Properties.Settings.Default.StimPortBandwidth == 32)
                    {
                        stimDigitalTask.DOChannels.CreateChannel(Properties.Settings.Default.StimulatorDevice + "/Port0/line0:31", "",
                                                                 ChannelLineGrouping.OneChannelForAllLines); //To control MUXes
                    }
                    else if (Properties.Settings.Default.StimPortBandwidth == 8)
                    {
                        stimDigitalTask.DOChannels.CreateChannel(Properties.Settings.Default.StimulatorDevice + "/Port0/line0:7", "",
                                                                 ChannelLineGrouping.OneChannelForAllLines); //To control MUXes
                    }
                    if (Properties.Settings.Default.StimPortBandwidth == 32)
                    {
                        stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao0", "", -10.0, 10.0, AOVoltageUnits.Volts); //Triggers
                        stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao1", "", -10.0, 10.0, AOVoltageUnits.Volts); //Triggers
                        stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao2", "", -10.0, 10.0, AOVoltageUnits.Volts); //Actual Pulse
                        stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao3", "", -10.0, 10.0, AOVoltageUnits.Volts); //Timing
                    }
                    else if (Properties.Settings.Default.StimPortBandwidth == 8)
                    {
                        stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao0", "", -10.0, 10.0, AOVoltageUnits.Volts);
                        stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao1", "", -10.0, 10.0, AOVoltageUnits.Volts);
                    }

                    if (Properties.Settings.Default.UseCineplex)
                    {
                        stimPulseTask.Timing.ReferenceClockSource = videoTask.Timing.ReferenceClockSource;
                        stimPulseTask.Timing.ReferenceClockRate   = videoTask.Timing.ReferenceClockRate;
                    }
                    else
                    {
                        stimPulseTask.Timing.ReferenceClockSource = "OnboardClock";
                        //stimPulseTask.Timing.ReferenceClockRate = 10000000.0; //10 MHz timebase
                    }
                    stimDigitalTask.Timing.ConfigureSampleClock("100kHzTimebase", STIM_SAMPLING_FREQ,
                                                                SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples);
                    stimPulseTask.Timing.ConfigureSampleClock("100kHzTimebase", STIM_SAMPLING_FREQ,
                                                              SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples);
                    stimDigitalTask.SynchronizeCallbacks = false;
                    stimPulseTask.SynchronizeCallbacks   = false;

                    stimDigitalWriter = new DigitalSingleChannelWriter(stimDigitalTask.Stream);
                    stimPulseWriter   = new AnalogMultiChannelWriter(stimPulseTask.Stream);

                    stimPulseTask.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger(
                        "/" + Properties.Settings.Default.StimulatorDevice + "/PFI6", DigitalEdgeStartTriggerEdge.Rising);

                    stimDigitalTask.Control(TaskAction.Verify);
                    stimPulseTask.Control(TaskAction.Verify);

                    //Check to ensure one of the I/V buttons is checked
                    if (!radioButton_impCurrent.Checked && !radioButton_impVoltage.Checked)
                    {
                        radioButton_impCurrent.Checked            = true;
                        radioButton_impVoltage.Checked            = false;
                        radioButton_stimCurrentControlled.Checked = true;
                        radioButton_stimVoltageControlled.Checked = false;
                    }

                    if (Properties.Settings.Default.UseStimulator)
                    {
                        stimIvsVTask = new Task("stimIvsV");

                        stimIvsVTask.DOChannels.CreateChannel(Properties.Settings.Default.StimIvsVDevice + "/Port1/line0", "",
                                                              ChannelLineGrouping.OneChannelForAllLines);
                        stimIvsVWriter = new DigitalSingleChannelWriter(stimIvsVTask.Stream);
                        //stimIvsVTask.Timing.ConfigureSampleClock("100kHztimebase", 100000,
                        //    SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples);
                        stimIvsVTask.Control(TaskAction.Verify);
                        //byte[] b_array;
                        //if (radioButton_impCurrent.Checked)
                        //    b_array = new byte[5] { 255, 255, 255, 255, 255 };
                        //else
                        //    b_array = new byte[5] { 0, 0, 0, 0, 0 };
                        //DigitalWaveform wfm = new DigitalWaveform(5, 8, DigitalState.ForceDown);
                        //wfm = NationalInstruments.DigitalWaveform.FromPort(b_array);
                        //stimIvsVWriter.WriteWaveform(true, wfm);
                        if (radioButton_impCurrent.Checked)
                        {
                            stimIvsVWriter.WriteSingleSampleSingleLine(true, true);
                        }
                        else
                        {
                            stimIvsVWriter.WriteSingleSampleSingleLine(true, false);
                        }
                        stimIvsVTask.WaitUntilDone();
                        stimIvsVTask.Stop();
                        stimIvsVTask.Dispose();

                        if (!placedzeros)                                                                      //try again
                        {
                            double[,] AnalogBuffer = new double[stimPulseTask.AOChannels.Count, STIMBUFFSIZE]; // buffer for analog channels
                            UInt32[] DigitalBuffer = new UInt32[STIMBUFFSIZE];

                            stimPulseTask.Stop();
                            stimDigitalTask.Stop();

                            stimPulseWriter.WriteMultiSample(true, AnalogBuffer);
                            stimDigitalWriter.WriteMultiSamplePort(true, DigitalBuffer);

                            //stimPulseTask.Start();

                            //stimDigitalTask.Start();
                            //stimPulseTask.WaitUntilDone();
                            stimPulseTask.Stop();
                            stimDigitalTask.Stop();
                        }
                    }

                    button_stim.Enabled                       = true;
                    button_stimExpt.Enabled                   = true;
                    openLoopStart.Enabled                     = true;
                    radioButton_impCurrent.Enabled            = true;
                    radioButton_impVoltage.Enabled            = true;
                    radioButton_stimCurrentControlled.Enabled = true;
                    radioButton_stimVoltageControlled.Enabled = true;
                    button_impedanceTest.Enabled              = true;
                }
                else
                {
                    button_stim.Enabled                       = false;
                    button_stimExpt.Enabled                   = false;
                    openLoopStart.Enabled                     = false;
                    radioButton_impCurrent.Enabled            = false;
                    radioButton_impVoltage.Enabled            = false;
                    radioButton_stimCurrentControlled.Enabled = false;
                    radioButton_stimVoltageControlled.Enabled = false;
                    button_impedanceTest.Enabled              = false;
                }
            }
            Console.WriteLine("updateStim");
        }
예제 #15
0
        //call this method after changing stimulation settings, or finishing a stimulation experiment
        //includes code to set dc offsets back to zero
        private void updateStim()
        {
            lock (this)
            {
                bool placedzeros = false;

                if (stimPulseTask != null || stimDigitalTask != null)
                {
                    try
                    {
                        // If we were ruuning a closed loop or open-loop protocol, this will zero the outputs
                        double[,] AnalogBuffer = new double[stimPulseTask.AOChannels.Count, STIMBUFFSIZE]; // buffer for analog channels
                        UInt32[] DigitalBuffer = new UInt32[STIMBUFFSIZE];

                        stimPulseTask.Stop();
                        stimDigitalTask.Stop();

                        stimPulseWriter.WriteMultiSample(true, AnalogBuffer);
                        stimDigitalWriter.WriteMultiSamplePort(true, DigitalBuffer);

                        stimPulseTask.WaitUntilDone(20);
                        stimDigitalTask.WaitUntilDone(20);

                        stimPulseTask.Stop();
                        stimDigitalTask.Stop();
                        placedzeros = true;
                    }
                    catch (Exception ex)
                    {
                        placedzeros = false;
                    }
                }
                if (stimDigitalTask != null)
                {
                    stimDigitalTask.Dispose();
                    stimDigitalTask = null;
                }
                if (stimPulseTask != null)
                {
                    stimPulseTask.Dispose();
                    stimPulseTask = null;
                }

                if (Properties.Settings.Default.UseStimulator)
                {
                    stimPulseTask = new Task("stimPulseTask");
                    stimDigitalTask = new Task("stimDigitalTask");
                    if (Properties.Settings.Default.StimPortBandwidth == 32)
                        stimDigitalTask.DOChannels.CreateChannel(Properties.Settings.Default.StimulatorDevice + "/Port0/line0:31", "",
                            ChannelLineGrouping.OneChannelForAllLines); //To control MUXes
                    else if (Properties.Settings.Default.StimPortBandwidth == 8)
                        stimDigitalTask.DOChannels.CreateChannel(Properties.Settings.Default.StimulatorDevice + "/Port0/line0:7", "",
                            ChannelLineGrouping.OneChannelForAllLines); //To control MUXes
                    if (Properties.Settings.Default.StimPortBandwidth == 32)
                    {
                        stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao0", "", -10.0, 10.0, AOVoltageUnits.Volts); //Triggers
                        stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao1", "", -10.0, 10.0, AOVoltageUnits.Volts); //Triggers
                        stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao2", "", -10.0, 10.0, AOVoltageUnits.Volts); //Actual Pulse
                        stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao3", "", -10.0, 10.0, AOVoltageUnits.Volts); //Timing
                    }
                    else if (Properties.Settings.Default.StimPortBandwidth == 8)
                    {
                        stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao0", "", -10.0, 10.0, AOVoltageUnits.Volts);
                        stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao1", "", -10.0, 10.0, AOVoltageUnits.Volts);
                    }

                    if (Properties.Settings.Default.UseCineplex)
                    {
                        stimPulseTask.Timing.ReferenceClockSource = videoTask.Timing.ReferenceClockSource;
                        stimPulseTask.Timing.ReferenceClockRate = videoTask.Timing.ReferenceClockRate;
                    }
                    else
                    {
                        stimPulseTask.Timing.ReferenceClockSource = "OnboardClock";
                        //stimPulseTask.Timing.ReferenceClockRate = 10000000.0; //10 MHz timebase
                    }
                    stimDigitalTask.Timing.ConfigureSampleClock("100kHzTimebase", STIM_SAMPLING_FREQ,
                       SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples);
                    stimPulseTask.Timing.ConfigureSampleClock("100kHzTimebase", STIM_SAMPLING_FREQ,
                        SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples);
                    stimDigitalTask.SynchronizeCallbacks = false;
                    stimPulseTask.SynchronizeCallbacks = false;

                    stimDigitalWriter = new DigitalSingleChannelWriter(stimDigitalTask.Stream);
                    stimPulseWriter = new AnalogMultiChannelWriter(stimPulseTask.Stream);

                    stimPulseTask.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger(
                        "/" + Properties.Settings.Default.StimulatorDevice + "/PFI6", DigitalEdgeStartTriggerEdge.Rising);

                    stimDigitalTask.Control(TaskAction.Verify);
                    stimPulseTask.Control(TaskAction.Verify);

                    //Check to ensure one of the I/V buttons is checked
                    if (!radioButton_impCurrent.Checked && !radioButton_impVoltage.Checked)
                    {
                        radioButton_impCurrent.Checked = true;
                        radioButton_impVoltage.Checked = false;
                        radioButton_stimCurrentControlled.Checked = true;
                        radioButton_stimVoltageControlled.Checked = false;
                    }

                    if (Properties.Settings.Default.UseStimulator)
                    {
                        stimIvsVTask = new Task("stimIvsV");

                        stimIvsVTask.DOChannels.CreateChannel(Properties.Settings.Default.StimIvsVDevice + "/Port1/line0", "",
                            ChannelLineGrouping.OneChannelForAllLines);
                        stimIvsVWriter = new DigitalSingleChannelWriter(stimIvsVTask.Stream);
                        //stimIvsVTask.Timing.ConfigureSampleClock("100kHztimebase", 100000,
                        //    SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples);
                        stimIvsVTask.Control(TaskAction.Verify);
                        //byte[] b_array;
                        //if (radioButton_impCurrent.Checked)
                        //    b_array = new byte[5] { 255, 255, 255, 255, 255 };
                        //else
                        //    b_array = new byte[5] { 0, 0, 0, 0, 0 };
                        //DigitalWaveform wfm = new DigitalWaveform(5, 8, DigitalState.ForceDown);
                        //wfm = NationalInstruments.DigitalWaveform.FromPort(b_array);
                        //stimIvsVWriter.WriteWaveform(true, wfm);
                        if (radioButton_impCurrent.Checked) stimIvsVWriter.WriteSingleSampleSingleLine(true, true);
                        else stimIvsVWriter.WriteSingleSampleSingleLine(true, false);
                        stimIvsVTask.WaitUntilDone();
                        stimIvsVTask.Stop();
                        stimIvsVTask.Dispose();

                        if (!placedzeros)//try again
                        {

                            double[,] AnalogBuffer = new double[stimPulseTask.AOChannels.Count, STIMBUFFSIZE]; // buffer for analog channels
                            UInt32[] DigitalBuffer = new UInt32[STIMBUFFSIZE];

                            stimPulseTask.Stop();
                            stimDigitalTask.Stop();

                            stimPulseWriter.WriteMultiSample(true, AnalogBuffer);
                            stimDigitalWriter.WriteMultiSamplePort(true, DigitalBuffer);

                            //stimPulseTask.Start();

                            //stimDigitalTask.Start();
                            //stimPulseTask.WaitUntilDone();
                            stimPulseTask.Stop();
                            stimDigitalTask.Stop();

                        }
                    }

                    button_stim.Enabled = true;
                    button_stimExpt.Enabled = true;
                    openLoopStart.Enabled = true;
                    radioButton_impCurrent.Enabled = true;
                    radioButton_impVoltage.Enabled = true;
                    radioButton_stimCurrentControlled.Enabled = true;
                    radioButton_stimVoltageControlled.Enabled = true;
                    button_impedanceTest.Enabled = true;
                }
                else
                {
                    button_stim.Enabled = false;
                    button_stimExpt.Enabled = false;
                    openLoopStart.Enabled = false;
                    radioButton_impCurrent.Enabled = false;
                    radioButton_impVoltage.Enabled = false;
                    radioButton_stimCurrentControlled.Enabled = false;
                    radioButton_stimVoltageControlled.Enabled = false;
                    button_impedanceTest.Enabled = false;
                }
            }
            Console.WriteLine("updateStim");
        }
예제 #16
0
        private void button_electrolesioningStart_Click(object sender, EventArgs e)
        {
            //Change mouse cursor to waiting cursor
            this.Cursor = Cursors.WaitCursor;

            //Grab values from UI
            double       voltage  = Convert.ToDouble(numericUpDown_electrolesioningVoltage.Value);
            double       duration = Convert.ToDouble(numericUpDown_electrolesioningDuration.Value);
            List <Int32> chList   = new List <int>(listBox_electrolesioningChannels.SelectedIndices.Count);

            for (int i = 0; i < listBox_electrolesioningChannels.SelectedIndices.Count; ++i)
            {
                chList.Add(listBox_electrolesioningChannels.SelectedIndices[i] + 1); //+1 since indices are 0-based but channels are 1-base
            }
            //Disable buttons, so users don't try running two experiments at once
            button_electrolesioningStart.Enabled      = false;
            button_electrolesioningSelectAll.Enabled  = false;
            button_electrolesioningSelectNone.Enabled = false;
            button_electrolesioningStart.Refresh();

            //Refresh stim task
            stimDigitalTask.Dispose();
            stimDigitalTask = new Task("stimDigitalTask_Electrolesioning");
            if (Properties.Settings.Default.StimPortBandwidth == 32)
            {
                stimDigitalTask.DOChannels.CreateChannel(Properties.Settings.Default.StimulatorDevice + "/Port0/line0:31", "",
                                                         ChannelLineGrouping.OneChannelForAllLines); //To control MUXes
            }
            else if (Properties.Settings.Default.StimPortBandwidth == 8)
            {
                stimDigitalTask.DOChannels.CreateChannel(Properties.Settings.Default.StimulatorDevice + "/Port0/line0:7", "",
                                                         ChannelLineGrouping.OneChannelForAllLines); //To control MUXes
            }
            stimDigitalWriter = new DigitalSingleChannelWriter(stimDigitalTask.Stream);

            //Refresh pulse task
            stimPulseTask.Dispose();
            stimPulseTask = new Task("stimPulseTask");
            if (Properties.Settings.Default.StimPortBandwidth == 32)
            {
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao0", "", -10.0, 10.0, AOVoltageUnits.Volts); //Triggers
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao1", "", -10.0, 10.0, AOVoltageUnits.Volts); //Triggers
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao2", "", -10.0, 10.0, AOVoltageUnits.Volts); //Actual Pulse
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao3", "", -10.0, 10.0, AOVoltageUnits.Volts); //Timing
            }
            else if (Properties.Settings.Default.StimPortBandwidth == 8)
            {
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao0", "", -10.0, 10.0, AOVoltageUnits.Volts);
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao1", "", -10.0, 10.0, AOVoltageUnits.Volts);
            }

            stimPulseWriter = new AnalogMultiChannelWriter(stimPulseTask.Stream);

            stimPulseTask.Timing.ConfigureSampleClock("",
                                                      StimPulse.STIM_SAMPLING_FREQ, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples);
            stimPulseTask.Timing.SamplesPerChannel = 2;


            stimDigitalTask.Control(TaskAction.Verify);
            stimPulseTask.Control(TaskAction.Verify);

            //For each channel, deliver lesioning pulse
            for (int i = 0; i < chList.Count; ++i)
            {
                int    channel = chList[i];
                UInt32 data    = StimPulse.channel2MUX((double)channel);

                //Setup digital waveform, open MUX channel
                stimDigitalWriter.WriteSingleSamplePort(true, data);
                stimDigitalTask.WaitUntilDone();
                stimDigitalTask.Stop();

                //Write voltage to channel, wait duration, stop
                stimPulseWriter.WriteMultiSample(true, new double[, ] {
                    { 0, 0 }, { 0, 0 }, { voltage, voltage }, { 0, 0 }
                });
                stimPulseTask.WaitUntilDone();
                stimPulseTask.Stop();
                Thread.Sleep((int)(Math.Round(duration * 1000))); //Convert to ms
                stimPulseWriter.WriteMultiSample(true, new double[, ] {
                    { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }
                });
                stimPulseTask.WaitUntilDone();
                stimPulseTask.Stop();

                //Close MUX
                stimDigitalWriter.WriteSingleSamplePort(true, 0);
                stimDigitalTask.WaitUntilDone();
                stimDigitalTask.Stop();
            }

            bool[] fData = new bool[Properties.Settings.Default.StimPortBandwidth];
            stimDigitalWriter.WriteSingleSampleMultiLine(true, fData);
            stimDigitalTask.WaitUntilDone();
            stimDigitalTask.Stop();

            button_electrolesioningSelectAll.Enabled  = true;
            button_electrolesioningSelectNone.Enabled = true;
            button_electrolesioningStart.Enabled      = true;

            //Now, destroy the objects we made
            updateSettings();
            this.Cursor = Cursors.Default;
        }
        /// <summary>
        /// This method creates analog and digital output buffers for daqMx cards. Note that the daqmx library seems to only support
        /// either analog OR digital on a given card at one time. Despite the fact that this method will create both types of buffers,
        /// it will probably throw some daqMX level exceptions if asked to create both analog and digital buffers for the same device.
        /// </summary>
        /// <param name="deviceName"></param>
        /// <param name="deviceSettings"></param>
        /// <param name="sequence"></param>
        /// <param name="settings"></param>
        /// <param name="usedDigitalChannels">digital channels which reside on this server.</param>
        /// <param name="usedAnalogChannels">analog channels which reside on this server</param>
        /// <returns></returns>
        public static Task createDaqMxTask(string deviceName, DeviceSettings deviceSettings, SequenceData sequence,
                                           SettingsData settings, Dictionary <int, HardwareChannel> usedDigitalChannels, Dictionary <int, HardwareChannel> usedAnalogChannels,
                                           ServerSettings serverSettings, out long expectedSamplesGenerated)
        {
            expectedSamplesGenerated = 0;

            Task task = new Task(deviceName + " output task");



            List <int>              analogIDs;
            List <HardwareChannel>  analogs;
            Dictionary <int, int[]> port_digital_IDs;
            List <int>              usedPortNumbers;

            // Parse and create channels.
            parseAndCreateChannels(deviceName, deviceSettings, usedDigitalChannels, usedAnalogChannels, task, out analogIDs, out analogs, out port_digital_IDs, out usedPortNumbers);



            if (analogIDs.Count != 0)
            {
                if (deviceSettings.UseCustomAnalogTransferSettings)
                {
                    task.AOChannels.All.DataTransferMechanism        = deviceSettings.AnalogDataTransferMechanism;
                    task.AOChannels.All.DataTransferRequestCondition = deviceSettings.AnalogDataTransferCondition;
                }
            }
            if (usedPortNumbers.Count != 0)
            {
                if (deviceSettings.UseCustomDigitalTransferSettings)
                {
                    task.DOChannels.All.DataTransferMechanism        = deviceSettings.DigitalDataTransferMechanism;
                    task.DOChannels.All.DataTransferRequestCondition = deviceSettings.DigitalDataTransferCondition;
                }
            }

            // ok! now create the buffers

            #region NON variable timebase buffer
            if (deviceSettings.UsingVariableTimebase == false)
            {
                // non "variable timebase" buffer creation


                double timeStepSize = Common.getPeriodFromFrequency(deviceSettings.SampleClockRate);
                int    nBaseSamples = sequence.nSamples(timeStepSize);

                // for reasons that are utterly stupid and frustrating, the DAQmx libraries seem to prefer sample
                // buffers with lengths that are a multiple of 4. (otherwise they, on occasion, depending on the parity of the
                // number of channels, throw exceptions complaining.
                // thus we add a few filler samples at the end of the sequence which parrot back the last sample.

                int nFillerSamples = 4 - nBaseSamples % 4;
                if (nFillerSamples == 4)
                {
                    nFillerSamples = 0;
                }

                int nSamples = nBaseSamples + nFillerSamples;

                if (deviceSettings.MySampleClockSource == DeviceSettings.SampleClockSource.DerivedFromMaster)
                {
                    task.Timing.ConfigureSampleClock("", deviceSettings.SampleClockRate, deviceSettings.ClockEdge, SampleQuantityMode.FiniteSamples, nSamples);
                }
                else
                {
                    task.Timing.ConfigureSampleClock(deviceSettings.SampleClockExternalSource, deviceSettings.SampleClockRate, deviceSettings.ClockEdge, SampleQuantityMode.FiniteSamples, nSamples);
                }
                if (deviceSettings.MasterTimebaseSource != "" && deviceSettings.MasterTimebaseSource != null)
                {
                    task.Timing.MasterTimebaseSource = deviceSettings.MasterTimebaseSource.ToString();
                }



                // Analog first...

                if (analogIDs.Count != 0)
                {
                    double[,] analogBuffer;
                    double[] singleChannelBuffer;
                    try
                    {
                        analogBuffer        = new double[analogs.Count, nSamples];
                        singleChannelBuffer = new double[nSamples];
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Unable to allocate analog buffer for device " + deviceName + ". Reason: " + e.Message + "\n" + e.StackTrace);
                    }

                    for (int i = 0; i < analogIDs.Count; i++)
                    {
                        int analogID = analogIDs[i];

                        if (settings.logicalChannelManager.Analogs[analogID].TogglingChannel)
                        {
                            DaqMxTaskGenerator.getAnalogTogglingBuffer(singleChannelBuffer);
                        }
                        else if (settings.logicalChannelManager.Analogs[analogID].overridden)
                        {
                            for (int j = 0; j < singleChannelBuffer.Length; j++)
                            {
                                singleChannelBuffer[j] = settings.logicalChannelManager.Analogs[analogID].analogOverrideValue;
                            }
                        }
                        else
                        {
                            sequence.computeAnalogBuffer(analogIDs[i], timeStepSize, singleChannelBuffer);
                        }

                        for (int j = 0; j < nBaseSamples; j++)
                        {
                            analogBuffer[i, j] = singleChannelBuffer[j];
                        }
                        for (int j = nBaseSamples; j < nSamples; j++)
                        {
                            analogBuffer[i, j] = analogBuffer[i, j - 1];
                        }
                    }

                    singleChannelBuffer = null;
                    System.GC.Collect();


                    AnalogMultiChannelWriter writer = new AnalogMultiChannelWriter(task.Stream);

                    writer.WriteMultiSample(false, analogBuffer);
                    // analog cards report the exact number of generated samples. for non-variable timebase this is nSamples
                    expectedSamplesGenerated = nSamples;
                }


                if (usedPortNumbers.Count != 0)
                {
                    byte[,] digitalBuffer;
                    bool[] singleChannelBuffer;

                    try
                    {
                        digitalBuffer       = new byte[usedPortNumbers.Count, nSamples];
                        singleChannelBuffer = new bool[nSamples];
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Unable to allocate digital buffer for device " + deviceName + ". Reason: " + e.Message + "\n" + e.StackTrace);
                    }

                    for (int i = 0; i < usedPortNumbers.Count; i++)
                    {
                        int  portNum        = usedPortNumbers[i];
                        byte digitalBitMask = 1;
                        for (int lineNum = 0; lineNum < 8; lineNum++)
                        {
                            int digitalID = port_digital_IDs[portNum][lineNum];
                            if (digitalID != -1)
                            {
                                if (settings.logicalChannelManager.Digitals[digitalID].TogglingChannel)
                                {
                                    getDigitalTogglingBuffer(singleChannelBuffer);
                                }
                                else if (settings.logicalChannelManager.Digitals[digitalID].overridden)
                                {
                                    for (int j = 0; j < singleChannelBuffer.Length; j++)
                                    {
                                        singleChannelBuffer[j] = settings.logicalChannelManager.Digitals[digitalID].digitalOverrideValue;
                                    }
                                }
                                else
                                {
                                    sequence.computeDigitalBuffer(digitalID, timeStepSize, singleChannelBuffer);
                                }
                                // byte digitalBitMask = (byte)(((byte) 2)^ ((byte)lineNum));
                                for (int j = 0; j < nBaseSamples; j++)
                                {
                                    // copy the bit value into the digital buffer byte.
                                    if (singleChannelBuffer[j])
                                    {
                                        digitalBuffer[i, j] |= digitalBitMask;
                                    }
                                }
                            }
                            digitalBitMask = (byte)(digitalBitMask << 1);
                        }
                        for (int j = nBaseSamples; j < nSamples; j++)
                        {
                            digitalBuffer[i, j] = digitalBuffer[i, j - 1];
                        }
                    }
                    singleChannelBuffer = null;
                    System.GC.Collect();
                    DigitalMultiChannelWriter writer = new DigitalMultiChannelWriter(task.Stream);
                    writer.WriteMultiSamplePort(false, digitalBuffer);
                    /// Digital cards report the number of generated samples as a multiple of 4
                    expectedSamplesGenerated = nSamples;
                }
            }
            #endregion
            #region Variable timebase buffer creation
            else // variable timebase buffer creation...
            {
                double timeStepSize = Common.getPeriodFromFrequency(deviceSettings.SampleClockRate);

                TimestepTimebaseSegmentCollection timebaseSegments =
                    sequence.generateVariableTimebaseSegments(serverSettings.VariableTimebaseType,
                                                              timeStepSize);

                int nBaseSamples = timebaseSegments.nSegmentSamples();

                nBaseSamples++; // add one sample for the dwell sample at the end of the buffer

                // for reasons that are utterly stupid and frustrating, the DAQmx libraries seem to prefer sample
                // buffers with lengths that are a multiple of 4. (otherwise they, on occasion, depending on the parity of the
                // number of channels, throw exceptions complaining.
                // thus we add a few filler samples at the end of the sequence which parrot back the last sample.

                int nFillerSamples = 4 - nBaseSamples % 4;
                if (nFillerSamples == 4)
                {
                    nFillerSamples = 0;
                }

                int nSamples = nBaseSamples + nFillerSamples;

                if (deviceSettings.MySampleClockSource == DeviceSettings.SampleClockSource.DerivedFromMaster)
                {
                    throw new Exception("Attempt to use a uniform sample clock with a variable timebase enabled device. This will not work. To use a variable timebase for this device, you must specify an external sample clock source.");
                }
                else
                {
                    task.Timing.ConfigureSampleClock(deviceSettings.SampleClockExternalSource, deviceSettings.SampleClockRate, deviceSettings.ClockEdge, SampleQuantityMode.FiniteSamples, nSamples);
                }


                // Analog first...

                if (analogIDs.Count != 0)
                {
                    double[,] analogBuffer;
                    double[] singleChannelBuffer;
                    try
                    {
                        analogBuffer        = new double[analogs.Count, nSamples];
                        singleChannelBuffer = new double[nSamples];
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Unable to allocate analog buffer for device " + deviceName + ". Reason: " + e.Message + "\n" + e.StackTrace);
                    }

                    for (int i = 0; i < analogIDs.Count; i++)
                    {
                        int analogID = analogIDs[i];

                        if (settings.logicalChannelManager.Analogs[analogID].TogglingChannel)
                        {
                            getAnalogTogglingBuffer(singleChannelBuffer);
                        }
                        else if (settings.logicalChannelManager.Analogs[analogID].overridden)
                        {
                            for (int j = 0; j < singleChannelBuffer.Length; j++)
                            {
                                singleChannelBuffer[j] = settings.logicalChannelManager.Analogs[analogID].analogOverrideValue;
                            }
                        }
                        else
                        {
                            sequence.computeAnalogBuffer(analogIDs[i], timeStepSize, singleChannelBuffer, timebaseSegments);
                        }
                        for (int j = 0; j < nBaseSamples; j++)
                        {
                            analogBuffer[i, j] = singleChannelBuffer[j];
                        }
                        for (int j = nBaseSamples; j < nSamples; j++)
                        {
                            analogBuffer[i, j] = analogBuffer[i, j - 1];
                        }
                    }

                    singleChannelBuffer = null;
                    System.GC.Collect();


                    AnalogMultiChannelWriter writer = new AnalogMultiChannelWriter(task.Stream);

                    writer.WriteMultiSample(false, analogBuffer);
                    // Analog cards report the exact number of samples generated. for variable timebase this is nBaseSamples
                    expectedSamplesGenerated = nBaseSamples;
                }


                if (usedPortNumbers.Count != 0)
                {
                    byte[,] digitalBuffer;
                    bool[] singleChannelBuffer;

                    try
                    {
                        digitalBuffer       = new byte[usedPortNumbers.Count, nSamples];
                        singleChannelBuffer = new bool[nSamples];
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Unable to allocate digital buffer for device " + deviceName + ". Reason: " + e.Message + "\n" + e.StackTrace);
                    }

                    for (int i = 0; i < usedPortNumbers.Count; i++)
                    {
                        int  portNum        = usedPortNumbers[i];
                        byte digitalBitMask = 1;
                        for (int lineNum = 0; lineNum < 8; lineNum++)
                        {
                            int digitalID = port_digital_IDs[portNum][lineNum];
                            if (digitalID != -1)
                            {
                                if (settings.logicalChannelManager.Digitals[digitalID].TogglingChannel)
                                {
                                    getDigitalTogglingBuffer(singleChannelBuffer);
                                }
                                else if (settings.logicalChannelManager.Digitals[digitalID].overridden)
                                {
                                    for (int j = 0; j < singleChannelBuffer.Length; j++)
                                    {
                                        singleChannelBuffer[j] = settings.logicalChannelManager.Digitals[digitalID].digitalOverrideValue;
                                    }
                                }
                                else
                                {
                                    sequence.computeDigitalBuffer(digitalID, timeStepSize, singleChannelBuffer, timebaseSegments);
                                }
                                // byte digitalBitMask = (byte)(((byte) 2)^ ((byte)lineNum));
                                for (int j = 0; j < nBaseSamples; j++)
                                {
                                    // copy the bit value into the digital buffer byte.
                                    if (singleChannelBuffer[j])
                                    {
                                        digitalBuffer[i, j] |= digitalBitMask;
                                    }
                                }
                            }
                            digitalBitMask = (byte)(digitalBitMask << 1);
                        }
                        for (int j = nBaseSamples; j < nSamples; j++)
                        {
                            digitalBuffer[i, j] = digitalBuffer[i, j - 1];
                        }
                    }
                    singleChannelBuffer = null;
                    System.GC.Collect();
                    DigitalMultiChannelWriter writer = new DigitalMultiChannelWriter(task.Stream);
                    writer.WriteMultiSamplePort(false, digitalBuffer);
                    // digital cards report number of samples generated up to multiple of 4
                    expectedSamplesGenerated = nSamples;
                }
            }

            #endregion

            if (deviceSettings.StartTriggerType == DeviceSettings.TriggerType.TriggerIn)
            {
                task.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger(
                    deviceSettings.TriggerInPort,
                    DigitalEdgeStartTriggerEdge.Rising);
            }

            task.Control(TaskAction.Verify);
            task.Control(TaskAction.Commit);
            task.Control(TaskAction.Reserve);


            return(task);
        }
예제 #18
0
        void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            //Measure each channel
            for (int c = 0; c < numChannels && !bgWorker.CancellationPending; ++c)
            {
                UInt32 MuxData = StimPulse.channel2MUX(Convert.ToDouble(startChannel + c));

                //Setup digital waveform, open MUX channel
                stimDigitalWriter.WriteSingleSamplePort(true, MuxData);
                stimDigitalTask.WaitUntilDone();
                stimDigitalTask.Stop();

                double numPeriodsUsed = numPeriods;
                for (int f = 0; f < freqs.GetLength(0) && !bgWorker.CancellationPending; ++f)
                {
                    //Update progress bars
                    bgWorker.ReportProgress(100 * (f + (c * freqs.Length)) / (numChannels * freqs.Length), new double[] { startChannel + c, freqs[f] });

                    //Create test wave
                    double numSeconds = 1 / freqs[f];
                    if (numSeconds * numPeriods < 0.1)
                    {
                        numPeriodsUsed = Math.Ceiling(0.1 * freqs[f]);
                    }
                    SineSignal testWave       = new SineSignal(freqs[f], commandVoltage); //Generate a 100 mV sine wave at 1000 Hz
                    double[]   testWaveValues = testWave.Generate(IMPEDANCE_SAMPLING_RATE, (long)Math.Round(numSeconds * (double)IMPEDANCE_SAMPLING_RATE));

                    int size = Convert.ToInt32(numSeconds * IMPEDANCE_SAMPLING_RATE);
                    double[,] analogPulse = new double[4, size];

                    for (int i = 0; i < size; ++i)
                    {
                        analogPulse[0 + 2, i] = testWaveValues[i];
                    }

                    impedanceRecord.Timing.SamplesPerChannel = (long)(numPeriodsUsed * size);
                    stimAnalogTask.Timing.SamplesPerChannel  = (long)(numPeriodsUsed * size); //Do numperiods cycles of sine wave

                    //Deliver pulse
                    stimAnalogWriter.WriteMultiSample(true, analogPulse);
                    double[] data = impedanceReader.ReadMultiSample((int)(numPeriodsUsed * size));

                    #region Calculate Impedance
                    //Remove DC offset
                    double mData = 0.0;
                    for (int i = 0; i < data.Length; ++i)
                    {
                        mData += data[i];
                    }
                    mData /= data.Length;
                    for (int i = 0; i < data.Length; ++i)
                    {
                        data[i] -= mData;
                    }

                    //Filter data with Butterworth, if checked
                    if (useBandpassFilter)
                    {
                        ButterworthBandpassFilter bwfilt = new ButterworthBandpassFilter(1, IMPEDANCE_SAMPLING_RATE, freqs[f] - freqs[f] / 4, freqs[f] + freqs[f] / 4);
                        data = bwfilt.FilterData(data);
                    }

                    //Use matched filter to reduce noise, if checked (slow)
                    if (useMatchedFilter)
                    {
                        SineSignal wave = new SineSignal(freqs[f], 1.0); //Create a sine wave at test frequency of amplitude 1
                        double[]   h;                                    //filter
                        //If data is very long, subsample by an order of magnitude
                        if (data.Length > 1E6)
                        {
                            double[] dataNew = new double[(int)Math.Floor((double)data.Length / 10)];
                            for (int i = 0; i < dataNew.Length; ++i)
                            {
                                dataNew[i] = data[i * 10];
                            }
                            data    = dataNew;
                            dataNew = null;
                            h       = wave.Generate(IMPEDANCE_SAMPLING_RATE / 10, (long)Math.Round((double)IMPEDANCE_SAMPLING_RATE / (freqs[f] * 10))); //Generate one period
                        }

                        else
                        {
                            h = wave.Generate(IMPEDANCE_SAMPLING_RATE, (long)Math.Round((double)IMPEDANCE_SAMPLING_RATE / freqs[f])); //Generate one period
                        }
                        wave = null;
                        //Compute filter power
                        double phh = 0.0;
                        for (int i = 0; i < h.Length; ++i)
                        {
                            phh += h[i] * h[i];
                        }
                        //Normalize filter so power is 1
                        for (int i = 0; i < h.Length; ++i)
                        {
                            h[i] /= phh;
                        }

                        //sw.Start();
                        double[] x = NationalInstruments.Analysis.Dsp.SignalProcessing.Convolve(data, h);
                        //sw.Stop();
                        //TimeSpan ts = sw.Elapsed;
                        //System.Diagnostics.Debug.WriteLine("ms = " + ts.Milliseconds + "\t s = " + ts.Seconds + "\t min = " + ts.Minutes);

                        int offset = (int)(h.Length * 0.5);
                        for (int i = 0; i < data.Length; ++i)
                        {
                            data[i] = x[i + offset];                                   //Take center values
                        }
                    }

                    double rms = rootMeanSquared(data);

                    if (isCurrentControlled)  //Current-controlled
                    {
                        impedance[c][f] = rms / (0.707106704695506 * commandVoltage / RCurr);
                        //Account for 6.8 MOhm resistor in parallel
                        impedance[c][f] = 1.0 / (1.0 / impedance[c][f] - 1.0 / 6800000.0);
                    }
                    else  //Voltage-controlled
                    {
                        double gain = 1.0 + (49400.0 / RGain); //Based on LT in-amp
                        impedance[c][f] = (0.707106704695506 * commandVoltage) / ((rms / gain) / RMeas);
                    }
                    #endregion

                    //Wait until recording and stim are finished
                    stimAnalogTask.WaitUntilDone();
                    impedanceRecord.WaitUntilDone();
                    stimAnalogTask.Stop();
                    impedanceRecord.Stop();
                }

                //De-select channel on mux
                stimDigitalWriter.WriteSingleSamplePort(true, 0);
                stimDigitalTask.WaitUntilDone();
                stimDigitalTask.Stop();

                //Notify that channel is done
                if (alertChannelFinished != null)
                {
                    alertChannelFinished(this, c, startChannel + c, impedance, freqs);
                }
            }
            //Reset muxes
            bool[] fData = new bool[Properties.Settings.Default.StimPortBandwidth];
            stimDigitalWriter.WriteSingleSampleMultiLine(true, fData);
            stimDigitalTask.WaitUntilDone();
            stimDigitalTask.Stop();
        }