public DeviceAccession()
        {
            //Az attributumok elérésénél a lockhoz a szinkronizációs objektum
            lockAttributes = new object();

            DAQ = DaqSystem.Local.LoadDevice("Dev1");
            DAQ.SelfCalibrate();

            ditask = new Task();
            dotask = new Task();
            aitask = new Task();

            chLeftEnd = ditask.DIChannels.CreateChannel("Dev1/port0/line0", "Left End", ChannelLineGrouping.OneChannelForEachLine);
            chRightEnd = ditask.DIChannels.CreateChannel("Dev1/port0/line1", "Right End", ChannelLineGrouping.OneChannelForEachLine);

            chMoveToLeft = dotask.DOChannels.CreateChannel("Dev1/port1/line0", "Move to the Left", ChannelLineGrouping.OneChannelForEachLine);
            chMoveToRight = dotask.DOChannels.CreateChannel("Dev1/port1/line1", "Move to the Right", ChannelLineGrouping.OneChannelForEachLine);

            chAngle = aitask.AIChannels.CreateVoltageChannel("Dev1/ai0", "Angle", AITerminalConfiguration.Rse, -10, 10, AIVoltageUnits.Volts);
            chPosition = aitask.AIChannels.CreateVoltageChannel("Dev1/ai1", "Position", AITerminalConfiguration.Rse, -10, 10, AIVoltageUnits.Volts);

            ditask.Start();
            dotask.Start();
            aitask.Start();

            digreader = new DigitalMultiChannelReader(ditask.Stream);
            digwriter = new DigitalMultiChannelWriter(dotask.Stream);
            anreader = new AnalogMultiChannelReader(aitask.Stream);
        }
Example #2
0
 public void addDigitalOutputChannels(string[] channelNames, uint[,] digis)
 {
     byteArray=digis;
     for (int ch = 0; ch < channelNames.Length; ch++) {
         string name = channelNames[ch];
         string vname = "DO" + ch;
     //				task.DOChannels.CreateChannel(name,vname,ChannelLineGrouping.OneChannelForAllLines);
         task.DOChannels.CreateChannel(name, vname, ChannelLineGrouping.OneChannelForEachLine);
     }
     dowriter = new DigitalMultiChannelWriter(task.Stream);
 }
Example #3
0
    public void setPort(uint value)
    {
        Task      task        = new Task();
        string    devFullname = string.Format("{0}/port0/line0:3", name);
        DOChannel dochannel   = task.DOChannels.CreateChannel(devFullname, "", ChannelLineGrouping.OneChannelForEachLine);

        task.Start();
        DigitalMultiChannelWriter writer = new DigitalMultiChannelWriter(task.Stream);

        writer.BeginWriteSingleSamplePort(true, new uint[] { value& 0x01, value& 0x02, value& 0x04, value& 0x08 }, null, null);
        task.Stop();
    }
Example #4
0
        public void addDigitalOutputChannels(string[] channelNames, uint[,] digis)
        {
            byteArray = digis;
            for (int ch = 0; ch < channelNames.Length; ch++)
            {
                string name  = channelNames[ch];
                string vname = "DO" + ch;
//				task.DOChannels.CreateChannel(name,vname,ChannelLineGrouping.OneChannelForAllLines);
                task.DOChannels.CreateChannel(name, vname, ChannelLineGrouping.OneChannelForEachLine);
            }
            dowriter = new DigitalMultiChannelWriter(task.Stream);
        }
Example #5
0
 /// <summary>
 /// Perform DO task.
 /// </summary>
 /// <param name="bits">0 or 1 to write digital LOW or HIGH output.</param>
 public void DigitalWrite(params bool[] bits)
 {
     if (digitalOut != null)
     {
         try
         {
             bool[] input = new bool[digitalOut.DOChannels.Count];
             for (int i = 0; i < input.Length; i++)
             {
                 input[i] = bits.Length > i && bits[i];
             }
             DigitalMultiChannelWriter dw = new DigitalMultiChannelWriter(digitalOut.Stream);
             dw.WriteSingleSampleSingleLine(true, input);
         }
         catch (DaqException de)
         {
             log.Write(de.Message);
         }
     }
 }
        /*
        /// <summary>
        /// This class contains both the analog and the digital tasks returned from a specific device.
        /// The reason for its existence is that if a device is to have both its analog and its digital outputs used,
        /// then they must exist in separate tasks.
        /// </summary>
        ///
        public class TaskCollection
        {
            public Task analogTask;
            public Task digitalTask;
        }
        */
        /*
        public static Task createVariableTimebaseTask(string digitalTimebaseOutLine, string analogTimebaseOutLine)
        {

        }*/
        ///
        /// This method creates a daqMX task for an "output now" command, and starts the output.
        /// </summary>
        /// <param name="deviceName"></param>
        /// <param name="settings"></param>
        /// <param name="output"></param>
        /// <returns></returns>
        public static Task createDaqMxTaskAndOutputNow(string deviceName, DeviceSettings deviceSettings, SingleOutputFrame output, 
            SettingsData settings, Dictionary<int, HardwareChannel> usedDigitalChannels, Dictionary<int, HardwareChannel> usedAnalogChannels)
        {
            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);

            // now create buffer.

            task.Timing.SampleTimingType = SampleTimingType.OnDemand;

            // analog output
            if (analogIDs.Count != 0)
            {

                // extract a list of analog values corresponding to the list analodIDs. This is
                // sorted in the same way as the channels were created in parseAndCreateChannels
                List<double> outputValues = new List<double>();
                foreach (int analogID in analogIDs)
                {
                    double val;
                    if (output.analogValues.ContainsKey(analogID))
                        val = output.analogValues[analogID];
                    else
                        val = 0;
                    outputValues.Add(val);
                }

                AnalogMultiChannelWriter writer = new AnalogMultiChannelWriter(task.Stream);
                writer.WriteSingleSample(true, outputValues.ToArray());
            }

            // digital output
            if (usedPortNumbers.Count != 0)
            {
                List<byte> outputValues = new List<byte>();

                foreach (int portNumber in usedPortNumbers)
                {
                    byte digitalMask = 1;
                    byte value=0;
                    for (int lineNum = 0; lineNum < 8; lineNum++)
                    {
                        int digitalID = port_digital_IDs[portNumber][lineNum];
                        if (digitalID != -1)
                        {
                            bool val = false;
                            if (output.digitalValues.ContainsKey(digitalID))
                                val = output.digitalValues[digitalID];

                            if (val)
                                value |= digitalMask;
                        }
                        digitalMask = (byte) (digitalMask << 1);
                    }

                    outputValues.Add(value);
                }

                DigitalMultiChannelWriter writer = new DigitalMultiChannelWriter(task.Stream);
                writer.WriteSingleSamplePort(true, outputValues.ToArray());
            }

            return task;
        }
        /// <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;
        }
        private void Line2Valve_StateChanged(int port, int line, bool value, string msg)
        {
#if DEBUG
            Console.WriteLine(msg + " Port {0} line {1} state {2}", port, line, value);
#endif
            //if (!resettingSwitches)
            //{
            try
            {
                // Get the task name and load from MAX
                string taskName = "";

                switch (port)
                {
                case PORT_0:
                    taskName = "Port0DigitalOutTask";
                    break;

                case PORT_1:
                    taskName = "Port1DigitalOutTask";
                    break;

                case PORT_2:
                    taskName = "Port2DigitalOutTask";
                    break;

                default:
                    break;
                }

                using (NationalInstruments.DAQmx.Task digitalWriteTask = DaqSystem.Local.LoadTask(taskName))
                {
                    // Get switch values
                    int tmp             = line;
                    int cyclinderToRead = 1;

                    switch (tmp)
                    {
                    //case CYCLINDER_VALVE_0:
                    //    dataArray[tmp, 0] = value;
                    //    break;
                    case CYCLINDER_VALVE_1:
                        dataArray[tmp, 1] = value;
                        cyclinderToRead   = CYCLINDER_VALVE_1;
                        break;

                    case CYCLINDER_VALVE_2:
                        dataArray[tmp, 2] = value;
                        cyclinderToRead   = CYCLINDER_VALVE_2;
                        break;

                    case CYCLINDER_VALVE_3:
                        dataArray[tmp, 3] = value;
                        cyclinderToRead   = CYCLINDER_VALVE_3;
                        break;

                    case CYCLINDER_VALVE_4:
                        dataArray[tmp, 4] = value;
                        cyclinderToRead   = CYCLINDER_VALVE_4;
                        break;

                    case CYCLINDER_VALVE_5:
                        dataArray[tmp, 5] = value;
                        cyclinderToRead   = CYCLINDER_VALVE_5;
                        break;

                    case CYCLINDER_VALVE_6:
                        dataArray[tmp, 6] = value;
                        cyclinderToRead   = CYCLINDER_VALVE_6;
                        break;

                    case CYCLINDER_VALVE_7:
                        dataArray[tmp, 7] = value;
                        cyclinderToRead   = CYCLINDER_VALVE_7;
                        break;

                    case CYCLINDER_VALVE_8:
                        dataArray[tmp, 8] = value;
                        cyclinderToRead   = CYCLINDER_VALVE_8;
                        break;

                    case CYCLINDER_VALVE_9:
                        dataArray[tmp, 9] = value;
                        cyclinderToRead   = CYCLINDER_VALVE_9;
                        break;

                    case CYCLINDER_VALVE_10:
                        dataArray[tmp, 10] = value;
                        cyclinderToRead    = CYCLINDER_VALVE_10;
                        break;

                    case CYCLINDER_VALVE_11:
                        dataArray[tmp, 11] = value;
                        cyclinderToRead    = CYCLINDER_VALVE_11;
                        break;

                    case CYCLINDER_VALVE_12:
                        dataArray[tmp, 12] = value;
                        cyclinderToRead    = CYCLINDER_VALVE_12;
                        break;

                    //case CYCLINDER_VALVE_13:
                    //    dataArray[tmp, 13] = value;
                    //    break;
                    //case CYCLINDER_VALVE_14:
                    //    dataArray[tmp, 14] = value;
                    //    break;
                    //case CYCLINDER_VALVE_15:
                    //    dataArray[tmp, 15] = value;
                    //    break;
                    default:
                        break;
                    }

                    // Write data to the port
                    DigitalMultiChannelWriter writer = new DigitalMultiChannelWriter(digitalWriteTask.Stream);
                    writer.WriteSingleSampleMultiLine(true, dataArray);
                    digitalWriteTask.Dispose();
#if DEBUG
                    double rval = ReadSensor(_panelID.ToString(), port.ToString(), cyclinderToRead);;
                    Console.WriteLine("Debug Write line {0} value {1}", line, rval);
#else
                    double rval = ReadSensor(_panelID.ToString(), port.ToString(), cyclinderToRead);;
#endif
                }
            }
            catch (DaqException ex)
            {
                MessageBox.Show(ex.Message);
                eventLog1.WriteEntry("Line2Valve_StateChanged - " + ex.Message);
            }
        }
        /// <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);
        }
        /*
         * /// <summary>
         * /// This class contains both the analog and the digital tasks returned from a specific device.
         * /// The reason for its existence is that if a device is to have both its analog and its digital outputs used,
         * /// then they must exist in separate tasks.
         * /// </summary>
         * ///
         * public class TaskCollection
         * {
         *  public Task analogTask;
         *  public Task digitalTask;
         * }
         */

        /*
         * public static Task createVariableTimebaseTask(string digitalTimebaseOutLine, string analogTimebaseOutLine)
         * {
         *
         * }*/

        ///
        /// This method creates a daqMX task for an "output now" command, and starts the output.
        /// </summary>
        /// <param name="deviceName"></param>
        /// <param name="settings"></param>
        /// <param name="output"></param>
        /// <returns></returns>


        public static Task createDaqMxTaskAndOutputNow(string deviceName, DeviceSettings deviceSettings, SingleOutputFrame output,
                                                       SettingsData settings, Dictionary <int, HardwareChannel> usedDigitalChannels, Dictionary <int, HardwareChannel> usedAnalogChannels)
        {
            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);


            // now create buffer.

            task.Timing.SampleTimingType = SampleTimingType.OnDemand;

            // analog output
            if (analogIDs.Count != 0)
            {
                // extract a list of analog values corresponding to the list analodIDs. This is
                // sorted in the same way as the channels were created in parseAndCreateChannels
                List <double> outputValues = new List <double>();
                foreach (int analogID in analogIDs)
                {
                    double val;
                    if (output.analogValues.ContainsKey(analogID))
                    {
                        val = output.analogValues[analogID];
                    }
                    else
                    {
                        val = 0;
                    }
                    outputValues.Add(val);
                }

                AnalogMultiChannelWriter writer = new AnalogMultiChannelWriter(task.Stream);
                writer.WriteSingleSample(true, outputValues.ToArray());
            }

            // digital output
            if (usedPortNumbers.Count != 0)
            {
                List <byte> outputValues = new List <byte>();

                foreach (int portNumber in usedPortNumbers)
                {
                    byte digitalMask = 1;
                    byte value       = 0;
                    for (int lineNum = 0; lineNum < 8; lineNum++)
                    {
                        int digitalID = port_digital_IDs[portNumber][lineNum];
                        if (digitalID != -1)
                        {
                            bool val = false;
                            if (output.digitalValues.ContainsKey(digitalID))
                            {
                                val = output.digitalValues[digitalID];
                            }

                            if (val)
                            {
                                value |= digitalMask;
                            }
                        }
                        digitalMask = (byte)(digitalMask << 1);
                    }

                    outputValues.Add(value);
                }

                DigitalMultiChannelWriter writer = new DigitalMultiChannelWriter(task.Stream);
                writer.WriteSingleSamplePort(true, outputValues.ToArray());
            }

            return(task);
        }
Example #11
0
        private void Line2Valve_StateChanged(int port, int line, byte value)
        {
            //if (!resettingSwitches)
            //{
            try
            {
                // Get the task name and load from MAX
                string taskName = "";

                switch (port)
                {
                case 0:
                    taskName = "";
                    break;

                case 1:
                    taskName = "";
                    break;

                case 2:
                    taskName = "Port2DigitalOutTask";
                    break;

                default:
                    break;
                }

                using (NationalInstruments.DAQmx.Task digitalWriteTask = DaqSystem.Local.LoadTask(taskName))
                {
                    // Get switch values
                    switch (line)
                    {
                    case 0:
                        dataArray[0] = 1;
                        break;

                    case 1:
                        dataArray[1] = 0;
                        break;

                    case 2:
                        dataArray[2] = 0;
                        break;

                    case 3:
                        dataArray[3] = 0;
                        break;

                    case 4:
                        dataArray[4] = 0;
                        break;

                    case 5:
                        dataArray[5] = 0;
                        break;

                    case 6:
                        dataArray[6] = 0;
                        break;

                    case 7:
                        dataArray[7] = 0;
                        break;

                    default:
                        break;
                    }
                    //int dataValue = 0;

                    // Convert switch values (0/1) into a decimal value
                    //for (int i = 0; i < 8; i++)
                    //{
                    //    if (dataArray[i] == 1)
                    //        dataValue += Convert.ToInt32(Math.Pow(2, (double)i));
                    //}

                    // Write data to the port
                    DigitalMultiChannelWriter writer = new DigitalMultiChannelWriter(digitalWriteTask.Stream);
                    writer.WriteSingleSamplePort(true, dataArray);
                }
            }
            catch (DaqException ex)
            {
                MessageBox.Show(ex.Message);
            }
            //}
        }
        private void WriteDigital(IDictionary<Channel, double[]> output, int nsamples)
        {
            var data = new UInt32[output.Count, nsamples];
            var chans = DAQTasks.DOChannels.Cast<DOChannel>().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] = (UInt32) o.Value[i];
                }
            }

            var writer = new DigitalMultiChannelWriter(DAQTasks.DOStream);
            writer.WriteMultiSamplePort(false, data);
        }