Assembly: Quanser.Hardware.Hil (in Quanser.Hardware.Hil.dll)
Syntax
Visual Basic (Declaration) |
---|
Function Write ( _ numSamples As Integer, _ analogBuffer As Double(), _ pwmBuffer As Double(), _ digitalBuffer As SByte(), _ otherBuffer As Double() _ ) As Integer |
C# |
---|
int Write( int numSamples, double[] analogBuffer, double[] pwmBuffer, sbyte[] digitalBuffer, double[] otherBuffer ) |
Visual C++ |
---|
int Write( int numSamples, array<double>^ analogBuffer, array<double>^ pwmBuffer, array<signed char>^ digitalBuffer, array<double>^ otherBuffer ) |
JavaScript |
---|
function write(numSamples, analogBuffer, pwmBuffer, digitalBuffer, otherBuffer); |
Parameters
- numSamples
- Type: System..::.Int32
The number of samples to write to the task buffer. Each "sample" consists of all the output channels specified when the task was created using TaskCreateWriter(Int32, array<Int32>[]()[], array<Int32>[]()[], array<Int32>[]()[], array<Int32>[]()[]). For example, if numSamples is 5 and the task is configured to write three analog channels and two PWM channels, then the analog input buffer must contain at least 15 elements and the PWM input buffer must contain at least 10 elements.
- analogBuffer
- Type: array<
System..::.Double
>[]()[]
An array containing the voltage values to write to the analog outputs. The array must contain numAnalogChannels * numSamples elements, where numAnalogChannels is the number of channels specified when the task was created. The array is organized as a linear array of samples, with each sample consisting of a group of channels. For example, if analog input channels 0, 1 and 3 are being written, than the data must appear in the array as follows, where the numbers correspond to channel numbers:
0 1 3 0 1 3 ... If no analog channels were specified in the call to TaskCreateWriter(Int32, array<Int32>[]()[], array<Int32>[]()[], array<Int32>[]()[], array<Int32>[]()[]) then this parameter may be set to NoDoubleBuffer or nullptr.
- pwmBuffer
- Type: array<
System..::.Double
>[]()[]
An array containing the values to write to the PWM outputs. How these values are interpreted depends on the PWM mode. The PWM mode is configured using the SetPwmMode(array<Int32>[]()[], array<Hil..::.PwmMode>[]()[]) method. The array must contain numPwmChannels * numSamples elements, where numPwmChannels is the number of channels specified when the task was created. The array is organized as a linear array of samples, with each sample consisting of a group of channels. For example, if PWM input channels 0, 1 and 3 are being written, than the data must appear in the array as follows, where the numbers correspond to channel numbers:
0 1 3 0 1 3 ... If no PWM channels were specified in the call to TaskCreateWriter(Int32, array<Int32>[]()[], array<Int32>[]()[], array<Int32>[]()[], array<Int32>[]()[]) then this parameter may be set to NoDoubleBuffer or nullptr.
- digitalBuffer
- Type: array<
System..::.SByte
>[]()[]
An array containing the state values to write to the digital outputs. The array must contain numDigitalChannels * numSamples elements, where numDigitalChannels is the number of channels specified when the task was created. The array is organized as a linear array of samples, with each sample consisting of a group of channels. For example, if digital input channels 0, 1 and 3 are being written, than the data must appear in the array as follows, where the numbers correspond to channel numbers:
0 1 3 0 1 3 ... If no digital channels were specified in the call to TaskCreateWriter(Int32, array<Int32>[]()[], array<Int32>[]()[], array<Int32>[]()[], array<Int32>[]()[]) then this parameter may be set to NoBooleanBuffer or nullptr.
- otherBuffer
- Type: array<
System..::.Double
>[]()[]
An array containing the values to write to the other outputs. The array must contain numOtherChannels * numSamples elements, where numOtherChannels is the number of channels specified when the task was created. The array is organized as a linear array of samples, with each sample consisting of a group of channels. For example, if other input channels 0, 1 and 3 are being written, than the data must appear in the array as follows, where the numbers correspond to channel numbers:
0 1 3 0 1 3 ... If no other channels were specified in the call to TaskCreateWriter(Int32, array<Int32>[]()[], array<Int32>[]()[], array<Int32>[]()[], array<Int32>[]()[]) then this parameter may be set to NoDoubleBuffer or nullptr.
Return Value
The return value is the number of samples written to the task buffer. This value may be less than the requested number of samples (including 0) if the task buffer does not have sufficient space and the task is stopped or has finished processing the total number of samples indicated in the call to Start(Hil..::.Clock, Double, Int32).
Note that successive calls to Write can write more samples in total then the total number of samples specified in the call to Start(Hil..::.Clock, Double, Int32). However, only the number of samples specified in Start(Hil..::.Clock, Double, Int32) will actually be processed and written to the hardware.
Remarks
The Write method writes the specified number of samples to the task buffer of a task created using the TaskCreateWriter(Int32, array<Int32>[]()[], array<Int32>[]()[], array<Int32>[]()[], array<Int32>[]()[]) method. If there's not enough space in the task buffer, then this method will block until space for the requested number of samples becomes available or the task stops. Since the task removes data from the task buffer and writes it to the hardware at the sampling rate specified in the call to Start(Hil..::.Clock, Double, Int32), this method will never block for longer than the given number of samples times the sampling period.
Note that this method only blocks until there is enough space available in the task buffer. Because the task buffer is depleted at a given sampling rate, calling this function only synchronizes the caller to that sampling rate if the task buffer is kept full. Data must be written to the task buffer before the task buffer is completely depleted or else the next attempt to write to the task buffer will throw a HilExceptionBufferOverflow exception. As a result, Write should be used to put data into the task buffer prior to starting the task!.
Writer tasks are typically used to stream data to HIL hardware. In this case the numSamples parameter is typically half the number of samples in the task buffer to implement double-buffering.
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 Write(Int32, array<Double>[]()[], array<Double>[]()[], array<SByte>[]()[], array<Double>[]()[]) method failing to write the digital I/O as expected. |
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.
Examples
C# | Copy Code |
---|---|
int [] analogChannels = { 0, 1, 2, 3 }; int [] pwmChannels = { 0, 1 }; double frequency = 1000; int samples = 5000; int samplesInBuffer = frequency; int samplesToWrite = 100; double [] analogBuffer = new double [samplesToWrite * analogChannels.Length]; double [] pwmBuffer = new double [samplesToWrite * pwmChannels.Length]; Hil.Task task; /* ... fill buffers with samplesToWrite samples ... */ /* Create task */ task = card.TaskCreateWriter(samplesInBuffer, analogChannels, pwmChannels, nullptr, nullptr); /* Preload task buffer with first samplesToWrite samples prior to starting task */ task.Write(samplesToWrite, analogBuffer, pwmBuffer, nullptr, nullptr); /* Start task */ task.Start(Hil.Clock.Hardware0, frequency, samples); for (int index = samples; index < samples; index += samples_to_write) { /* ... fill buffers with next samplesToWrite samples ... */ /* Block (if necessary) waiting to write next samplesToWrite samples. However, it only waits for space in the task buffer (which can contain samplesInBuffer samples), not for the data to actually be written to the hardware. Hence, it will not block until the task buffer is full (a little over one second in this example since samplesInBuffer is 1000). */ task.Write(samplesToWrite, analogBuffer, pwmBuffer, nullptr, nullptr); } /* Flush to make sure all data has been written to the hardware before stopping task */ task.Flush(); task.Stop(); |
Visual Basic | Copy Code |
---|---|
Dim analogChannels() As Integer = {0, 1, 2, 3} Dim pwmChannels() As Integer = {0, 1} Dim frequency as Double = 1000 Dim samples As Integer = 5000 Dim samplesInBuffer As Integer = frequency Dim samplesToWrite As Integer = 100 Dim analogBuffer(samplesToWrite * analogChannels.Length - 1) As Double Dim pwmBuffer(samplesToWrite * pwmChannels.Length - 1) As Double Dim task As Hil.Task Dim index As Integer ' ... fill buffers with samplesToWrite samples ... ' Create task task = card.TaskCreateWriter(samplesInBuffer, analogChannels, pwmChannels, Hil.NoChannels, Hil.NoChannels) ' Preload task buffer with first samplesToWrite samples prior to starting task task.Write(samplesToWrite, analogBuffer, pwmBuffer, Hil.NoBooleanBuffer, Hil.NoDoubleBuffer) ' Start task task.Start(Hil.Clock.Hardware0, frequency, samples) For index = 0 To samples - 1 Step samplesToWrite ' ... fill buffers with next samplesToWrite sample ... ' Block (if necessary) waiting to write next samplesToWrite samples. ' However, it only waits for space in the task buffer (which can contain ' samplesInBuffer samples), not for the data to actually be written to ' the hardware. Hence, it will not block until the task buffer is full ' (a little over one second in this example since samplesInBuffer is 1000). task.Write(samplesToWrite, analogBuffer, pwmBuffer, Hil.NoBooleanBuffer, Hil.NoDoubleBuffer) Next ' Flush to make sure all data has been written to the hardware before stopping task task.Flush() task.Stop() |
Visual C++ | Copy Code |
---|---|
array<int>^ analogChannels = { 0, 1, 2, 3 }; array<int>^ pwmChannels = { 0, 1 }; double frequency = 1000; int samples = 5000; int samplesInBuffer = frequency; int samplesToWrite = 100; array<double>^ analogBuffer = gcnew array<double>(samplesToWrite * analogChannels->Length); array<double>^ pwmBuffer = gcnew array<double>(samplesToWrite * pwmChannels->Length); Hil::Task^ task; /* ... fill buffers with samplesToWrite samples ... */ /* Create task */ task = card->TaskCreateWriter(samplesInBuffer, analogChannels, pwmChannels, nullptr, nullptr); /* Preload task buffer with first samplesToWrite samples prior to starting task */ task->Write(samplesToWrite, analogBuffer, pwmBuffer, nullptr, nullptr); /* Start task */ task->Start(Hil::Clock::Hardware0, frequency, samples); for (int index = 0; index < samples; index += samplesToWrite) { /* ... fill buffers with next samplesToWrite samples ... */ /* Block (if necessary) waiting to write next samplesToWrite samples. However, it only waits for space in the task buffer (which can contain samplesInBuffer samples), not for the data to actually be written to the hardware. Hence, it will not block until the task buffer is full (a little over one second in this example since samplesInBuffer is 1000). */ task->Write(samplesToWrite, analogBuffer, pwmBuffer, nullptr, nullptr); } /* Flush to make sure all data has been written to the hardware before stopping task */ task->Flush(); task->Stop(); |
Exceptions
Exception | Condition |
---|---|
Quanser.Hardware..::.HilException | If the write cannot be performed then an exception is thrown. This situtation typically arises if the task buffer underflowed (ran out of data) after the last call to this method. |