Creates a task for reading from analog, encoder, digital and/or other inputs and writing to analog, PWM, digital and/or other outputs at the same time.

Namespace:  Quanser.Hardware
Assembly:  Quanser.Hardware.Hil (in Quanser.Hardware.Hil.dll)

Syntax

Visual Basic (Declaration)
Public Function TaskCreateReaderWriter ( _
	samplesInBuffer As Integer, _
	analogInputChannels As Integer(), _
	encoderInputChannels As Integer(), _
	digitalInputChannels As Integer(), _
	otherInputChannels As Integer(), _
	analogOutputChannels As Integer(), _
	pwmOutputChannels As Integer(), _
	digitalOutputChannels As Integer(), _
	otherOutputChannels As Integer() _
) As Hil..::.Task
C#
public Hil..::.Task TaskCreateReaderWriter(
	int samplesInBuffer,
	int[] analogInputChannels,
	int[] encoderInputChannels,
	int[] digitalInputChannels,
	int[] otherInputChannels,
	int[] analogOutputChannels,
	int[] pwmOutputChannels,
	int[] digitalOutputChannels,
	int[] otherOutputChannels
)
Visual C++
public:
Hil..::.Task^ TaskCreateReaderWriter(
	int samplesInBuffer, 
	array<int>^ analogInputChannels, 
	array<int>^ encoderInputChannels, 
	array<int>^ digitalInputChannels, 
	array<int>^ otherInputChannels, 
	array<int>^ analogOutputChannels, 
	array<int>^ pwmOutputChannels, 
	array<int>^ digitalOutputChannels, 
	array<int>^ otherOutputChannels
)
JavaScript
function taskCreateReaderWriter(samplesInBuffer, analogInputChannels, encoderInputChannels, digitalInputChannels, otherInputChannels, analogOutputChannels, pwmOutputChannels, digitalOutputChannels, otherOutputChannels);

Parameters

samplesInBuffer
Type: System..::.Int32

The number of samples in the task buffers. The ReadWrite(Int32, array<Double>[]()[], array<Int32>[]()[], array<SByte>[]()[], array<Double>[]()[], array<Double>[]()[], array<Double>[]()[], array<SByte>[]()[], array<Double>[]()[]) method cannot read or write more samples than this in a single call. If the task input buffer overflows because ReadWrite(Int32, array<Double>[]()[], array<Int32>[]()[], array<SByte>[]()[], array<Double>[]()[], array<Double>[]()[], array<Double>[]()[], array<SByte>[]()[], array<Double>[]()[]) has not been called in time to remove the data from the task buffer then the next call to ReadWrite(Int32, array<Double>[]()[], array<Int32>[]()[], array<SByte>[]()[], array<Double>[]()[], array<Double>[]()[], array<Double>[]()[], array<SByte>[]()[], array<Double>[]()[]) will throw an HilException exception. Likewise, if the task output buffer underflows because ReadWrite(Int32, array<Double>[]()[], array<Int32>[]()[], array<SByte>[]()[], array<Double>[]()[], array<Double>[]()[], array<Double>[]()[], array<SByte>[]()[], array<Double>[]()[]) has not been called in time to add data to the task output buffer then the next call to ReadWrite(Int32, array<Double>[]()[], array<Int32>[]()[], array<SByte>[]()[], array<Double>[]()[], array<Double>[]()[], array<Double>[]()[], array<SByte>[]()[], array<Double>[]()[]) will also throw an HilException exception. See Hil..::.Task for more information on task buffers.

analogInputChannels
Type: array< System..::.Int32 >[]()[]

An array containing the numbers of the analog input channels to be read by the task. Channel numbers are zero-based. Thus, channel 0 is the first channel, channel 1 the second channel, etc. If no analog input channels are to be read then set this parameter to NoChannels or nullptr.

Select a board type to the list for board-specific details: .

encoderInputChannels
Type: array< System..::.Int32 >[]()[]

An array containing the numbers of the encoder input channels to be read by the task. Channel numbers are zero-based. Thus, channel 0 is the first channel, channel 1 the second channel, etc. If no encoder input channels are to be read then set this parameter to NoChannels or nullptr.

Select a board type to the list for board-specific details: .

digitalInputChannels
Type: array< System..::.Int32 >[]()[]

An array containing the numbers of the digital input channels to be read by the task. Channel numbers are zero-based. Thus, channel 0 is the first channel, channel 1 the second channel, etc. If no digital input channels are to be read then set this parameter to NoChannels or nullptr.

Select a board type to the list for board-specific details: .

otherInputChannels
Type: array< System..::.Int32 >[]()[]

An array containing the numbers of the other input channels to be read by the task. Channel numbers are zero-based. Thus, channel 0 is the first channel, channel 1 the second channel, etc. If no other input channels are to be read then set this parameter to NoChannels or nullptr.

Select a board type to the list for board-specific details: .

analogOutputChannels
Type: array< System..::.Int32 >[]()[]

An array containing the numbers of the analog output channels to be written by the task. Channel numbers are zero-based. Thus, channel 0 is the first channel, channel 1 the second channel, etc. If no analog output channels are to be written then set this parameter to NoChannels or nullptr.

Select a board type to the list for board-specific details: .

pwmOutputChannels
Type: array< System..::.Int32 >[]()[]

An array containing the numbers of the PWM output channels to be written by the task. Channel numbers are zero-based. Thus, channel 0 is the first channel, channel 1 the second channel, etc. If no PWM output channels are to be written then set this parameter to NoChannels or nullptr.

Select a board type to the list for board-specific details: .

digitalOutputChannels
Type: array< System..::.Int32 >[]()[]

An array containing the numbers of the digital output channels to be written by the task. Channel numbers are zero-based. Thus, channel 0 is the first channel, channel 1 the second channel, etc. If no digital output channels are to be written then set this parameter to NoChannels or nullptr.

Select a board type to the list for board-specific details: .

otherOutputChannels
Type: array< System..::.Int32 >[]()[]

An array containing the numbers of the other output channels to be written by the task. Channel numbers are zero-based. Thus, channel 0 is the first channel, channel 1 the second channel, etc. If no other output channels are to be written then set this parameter to NoChannels or nullptr.

Select a board type to the list for board-specific details: .

Return Value

Returns a Hil..::.Task interface for manipulating the task, including starting and stopping the task, and for reading and writing the samples for the task.

Remarks

The TaskCreateReaderWriter method creates a task for reading from the specified input channels and writing to the specified output channels at the same time. The task allows other operations to be performed while the inputs are being read and the outputs are being written "in the background". The data read from the inputs is stored in an internal circular "task input buffer". The data written to the outputs is read from an internal circular "task output buffer". The application may read the data from the task input buffer and write data to the task output buffer at any time using the ReadWrite(Int32, array<Double>[]()[], array<Int32>[]()[], array<SByte>[]()[], array<Double>[]()[], array<Double>[]()[], array<Double>[]()[], array<SByte>[]()[], array<Double>[]()[]) method. Data may also be read separately from the task input buffer using the Read(Int32, array<Double>[]()[], array<Int32>[]()[], array<SByte>[]()[], array<Double>[]()[]) method, and data may also be written into the task output buffer using the Write(Int32, array<Double>[]()[], array<Double>[]()[], array<SByte>[]()[], array<Double>[]()[]) method. The size of this task buffer is determined by the samplesInBuffer parameter.

The Write(Int32, array<Double>[]()[], array<Double>[]()[], array<SByte>[]()[], array<Double>[]()[]) method is typically called prior to starting the task in order to put the initial samples in the the task output buffer. After the task is started, ReadWrite(Int32, array<Double>[]()[], array<Int32>[]()[], array<SByte>[]()[], array<Double>[]()[], array<Double>[]()[], array<Double>[]()[], array<SByte>[]()[], array<Double>[]()[]) is typically called to read the input values from the task input buffer and to put more data into the task output buffer for the outputs.

The task does not actually start reading from the inputs and storing the data in the task input buffer or reading the data from the task output buffer and writing it to the outputs until the Start(Hil..::.Clock, Double, Int32) method is called. In order for data to be available in the task buffer as soon as the task starts, store data in the buffer using Write(Int32, array<Double>[]()[], array<Double>[]()[], array<SByte>[]()[], array<Double>[]()[]) prior to starting the task.

Each sampling instant, the task first reads from the input channels selected and stores the data in the task input buffer. Then, in the same sampling instant, the task extracts one sample from the task output buffer and writes to the selected output channels. This synchronization of input and output is particularly useful for system identification because the time at which a sample is read and a sample is written is known, so no postprocessing is required to determine the response delay in the system been identified.

Since the task writes to the outputs at the sampling rate specified when the task is started, it will be reading data from the task output buffer at that rate. Thus, ReadWrite(Int32, array<Double>[]()[], array<Int32>[]()[], array<SByte>[]()[], array<Double>[]()[], array<Double>[]()[], array<Double>[]()[], array<SByte>[]()[], array<Double>[]()[]) or Write(Int32, array<Double>[]()[], array<Double>[]()[], array<SByte>[]()[], array<Double>[]()[]) must be called to add more data to the task output buffer before all the data in the buffer is depleted. Otherwise the task will have no data to write to the outputs and will return with an HilException exception the next time ReadWrite(Int32, array<Double>[]()[], array<Int32>[]()[], array<SByte>[]()[], array<Double>[]()[], array<Double>[]()[], array<Double>[]()[], array<SByte>[]()[], array<Double>[]()[]) or Write(Int32, array<Double>[]()[], array<Double>[]()[], array<SByte>[]()[], array<Double>[]()[]) is called. See Hil..::.Task for more information on tasks.

The interpretation of the PWM samples to be written depends upon the PWM mode. Typically the data is interpreted as a duty cycle, in which a magnitude of 0.0 denotes a 0% duty cycle and magnitude of 1.0 indicates a 100% duty cycle. The sign determines the polarity of the output for those boards supporting bidirectional PWM outputs. However, other PWM modes are possible with some boards. Refer to the SetPwmMode(array<Int32>[]()[], array<Hil..::.PwmMode>[]()[]) method for details.

Warning

Many cards allow the digital I/O lines to be programmed as inputs or outputs. The digital I/O lines are configured as inputs or outputs using the SetDigitalDirections(array<Int32>[]()[], array<Int32>[]()[]) method. All the channels which will be used as digital inputs or outputs must be configured accordingly using this function. Failure to configure the digital I/O may result in the ReadWrite(Int32, array<Double>[]()[], array<Int32>[]()[], array<SByte>[]()[], array<Double>[]()[], array<Double>[]()[], array<Double>[]()[], array<SByte>[]()[], array<Double>[]()[]) method failing to read or write digital I/O as expected.

Examples

This example illustrates how to read various inputs and write various outputs at the same time using a task. The task reads analog input channels 1 and 3 and encoder input channels 0 and 2 while writing to analog output channels 2 and 3 and PWM output channel 0 every millisecond using a hardware clock. The data may be processed each sampling instant. It runs for 5 seconds before stopping. Exceptions are ignored for simplicity.
C# Copy Code
int [] analogInputChannels  = { 1, 3 };
int [] encoderInputChannels = { 0, 2 };
int [] analogOutputChannels = { 2, 3 };
int [] pwmOutputChannels    = { 0 };
double frequency            = 1000;
int    samples              = 5000;
int    samplesInBuffer      = frequency;
int    samplesToReadWrite   = 1;

double [] analogInputBuffer  = new double [samplesToReadWrite * analogInputChannels.length];
int []    encoderInputBuffer = new int    [samplesToReadWrite * encoderInputChannels.length];
double [] analogOutputBuffer = new double [samplesToReadWrite * analogOutputChannels.length];
double [] pwmOutputBuffer    = new double [samplesToReadWrite * pwmOutputChannels.length];

Hil.Task task;

/* ... fill output buffers with samplesToReadWrite samples to write ... */

task = card.TaskCreateReaderWriter(samplesInBuffer, 
   analogInputChannels, encoderInputChannels, nullptr, nullptr,
   analogOutputChannels, pwmOutputChannels, nullptr, nullptr);

/* Preload task output buffer with first samplesToReadWrite samples prior to starting task */
task.Write(samplesToReadWrite, analogOutputBuffer, pwmOutputBuffer, nullptr, nullptr);

/* Start task */
task.Start(Hil.Clock.Hardware0, frequency, samples);
for (int index = 0; index < samples; index += samplesToReadWrite) {
    /* ... fill output buffers with next samplesToReadWrite samples to write ... */

    /* 
        Block (if necessary) waiting to read next samplesToReadWrite samples from
        the hardware and for space in the task output buffer.
    */
    task.ReadWrite(samplesToReadWrite,
        analogInputBuffer, encoderInputBuffer, nullptr, nullptr,
        analogOutputBuffer, pwmOutputBuffer, nullptr, nullptr);

    /* ... process samplesToReadWrite samples read ... */
}
task.Stop();
Visual Basic Copy Code
Dim analogInputChannels() As Integer = {1, 3}
Dim encoderInputChannels() As Integer = {0, 2}
Dim analogOutputChannels() As Integer = {2, 3}
Dim pwmOutputChannels() As Integer = {0}
Dim frequency as Double = 1000
Dim samples As Integer = 5000
Dim samplesInBuffer As Integer = frequency
Dim samplesToReadWrite As Integer = 1

Dim analogInputBuffer(samplesToReadWrite * analogInputChannels.Length - 1) As Double
Dim encoderInputBuffer(samplesToReadWrite * encoderInputChannels.Length - 1) As Integer
Dim analogOutputBuffer(samplesToReadWrite * analogOutputChannels.Length - 1) As Double
Dim pwmOutputBuffer(samplesToReadWrite * pwmOutputChannels.Length - 1) As Double
Dim task As Hil.Task
Dim index As Integer

' ... fill output buffers with samplesToReadWrite samples to write ...

' Create task
task = card.TaskCreateReaderWriter(samplesInBuffer, _
    analogInputChannels, encoderInputChannels, Hil.NoChannels, Hil.NoChannels, _
    analogOutputChannels, pwmOutputChannels, Hil.NoChannels, Hil.NoChannels)

' Preload task buffer with first samplesToReadWrite samples prior to starting task
task.Write(samplesToWrite, analogOutputBuffer, pwmOutputBuffer, Hil.NoBooleanBuffer, Hil.NoDoubleBuffer)

' Start task
task.Start(Hil.Clock.Hardware0, frequency, samples)
For index = 0 To samples - 1 Step samplesToReadWrite
    ' ... fill output buffers with next samplesToReadWrite samples to write ...

    ' Block (if necessary) waiting to read next samplesToReadWrite samples
    ' from the hardware and for space in the task output buffer.
    task.ReadWrite(samplesToReadWrite, _
        analogInputBuffer, encoderInputBuffer, Hil.NoBooleanBuffer, Hil.NoDoubleBuffer, _
        analogOutputBuffer, pwmOutputBuffer, Hil.NoBooleanBuffer, Hil.NoDoubleBuffer)

    ' ... process samplesToReadWrite samples read ...
Next
task.Stop()
Visual C++ Copy Code
array<int>^ analogInputChannels  = { 1, 3 };
array<int>^ encoderInputChannels = { 0, 2 };
array<int>^ analogOutputChannels = { 2, 3 };
array<int>^ pwmOutputChannels    = { 0 };
double      frequency            = 1000;
int         samples              = 5000;
int         samplesInBuffer      = frequency;
int         samplesToReadWrite   = 1;

array<double>^ analogInputBuffer  = gcnew array<double>(samplesToReadWrite * analogInputChannels->Length);
array<int>^    encoderInputBuffer = gcnew array<int>   (samplesToReadWrite * encoderInputChannels->Length);
array<double>^ analogOutputBuffer = gcnew array<double>(samplesToReadWrite * analogOutputChannels->Length);
array<double>^ pwmOutputBuffer    = gcnew array<double>(samplesToReadWrite * pwmOutputChannels->Length);
Hil::Task^ task;

/* ... fill output buffers with samplesToReadWrite samples to write ... */

/* Create task */
task = card->TaskCreateReaderWriter(samplesInBuffer,
    analogInputChannels, encoderInputChannels, nullptr, nullptr,
    analogOutputChannels, pwmOutputChannels, nullptr, nullptr);

/* Preload task buffer with first samplesToWrite samples prior to starting task */
task->Write(samplesToWrite, analogOutputBuffer, pwmOutputBuffer, nullptr, nullptr);

/* Start task */
task->Start(Hil::Clock::Hardware0, frequency, samples);
for (int index = 0; index < samples; index += samplesToReadWrite) {
    /* ... fill output buffers with next samplesToReadWrite samples to write ... */

    /* 
        Block (if necessary) waiting to read next samplesToReadWrite samples from
        the hardware and for space in the task output buffer.
    */
    task->ReadWrite(samplesToReadWrite, 
        analogInputBuffer, encoderInputBuffer, nullptr, nullptr,
        analogOutputBuffer, pwmOutputBuffer, nullptr, nullptr);

    /* ... process samplesToReadWrite samples read ... */
}
task->Stop();

Exceptions

ExceptionCondition
Quanser.Hardware..::.HilException If the task cannot be created then an exception is thrown. This situtation typically arises if the board does not support analog I/O or tasks.

See Also