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); }
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); }
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(); }
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); }
/// <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); }
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); }