Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

hardware timing of digital outputs

Solved!
Go to solution

Hi Folks

 

I am cimpletely new to DAQmx and am struggling to come up to speed.  I am using a NI PCIe-6353 card in my device.  My programming environment in Visual Studio 2015 using Visial Basic with .NET 4.5.1.  I am not using Measurement Studio, just calling the .NET api directly from my code.

 

I have a set of 6 LED's that are attached to 6 of the digital output ports on this card.  I have been able to sucessfully turn the LED's on/off, but now I want to send PWM pulses to the LED's and control the duty cycle to change the intensity of the LEDs.  I know there is some way to use the internal counters on the card to generate a PWM pulse stream, and then use that pulse stream to somehow change the output to the digital lines, but I hnoestly don't have a clue about how to make that work.  I've search through the examples on my system. but noine of them show how to drive a digital output from a timer.

 

Can anybody give me some example code that can point me in the right diection?

 

Thanks

 

- Mike

 

 

0 Kudos
Message 1 of 6
(4,603 Views)

Hi Mike,

 

That sounds an awful lot like the PWM Counter Output example... the one in C:\Users\Public\Documents\National Instruments\NI-DAQ\Examples\DotNET4.5\Control\General\PWMCounterOutput\VB

 

That example is using counters to generate a PWM pulse stream. What is the difference between what you are looking to do and that example?

 

Regards,

 

GiantDeathRobot

William R.
0 Kudos
Message 2 of 6
(4,583 Views)

GiantDeathRobot -

 

Thanks for the reply.  I guess I don't really understand that example very well, but it doesn't look much like what I am seeking to me.

 

  I want to generate a PWM stream on 6 different digial output lines.  That example utilizes an analog input - I'm not sure what for - I think to obtain info about the desired duty cycle?  THen it generates the pulse stream - but on a counter output - how would I get this onto the digital outputs?

 

This may be a good place to start, but I'm having trouble getting how to translate this into what I am trying to do.

 

any advice?

 

Thanks

 

- Mike

0 Kudos
Message 3 of 6
(4,581 Views)

Mike,

 

Oh, right. The normal digital outputs. We have two types of digital outputs on our devices, PFI and DIO. Counter/timer outputs have to go out over a Programmably Function Interface (PFI) line. (See http://digital.ni.com/public.nsf/allkb/8058F1BEF0944D99862574A3007EB53C and page 7-41 of the X-Series User Manual: http://www.ni.com/pdf/manuals/370784g.pdf) DIO can have a buffered output, so if you had a previously determined PWM signal as a waveform, you could load that and push it out a standard DIO line. However, PWM is normally done using a counter, so you would be limited to a PFI line.

 

Also, you may be limited in how many PWM streams you can output by how many counters you have. (Unless you are trying to send one signal to six LEDs- you can tie PFI lines together so the output on one will drive another.)

 

Also, you would be right. Typically a PWM example will take an analog input and then output the same signal via PWM.

 

GiantDeathRobot

William R.
0 Kudos
Message 4 of 6
(4,566 Views)

Well - I've had some limited sucess getting this to work.  I have a counter task that is outputting PWM pulses. And I have a digital output task that can turn my 6 LEDs on/off.  I've used timing object of the digital output task to ties it to the counter task.  The only probel is that the LED's now blink at the same rate regardless of the duty cycle I program into the counter.  They just turn on/off at the frequency I provide.  I think the probelm is that I am using just the rising edge ofthe counter pulse when I really need to change states on both the rising and falling edge.  BUt there does not seem to be any option to do that - so I'm stuck.  Any ideas

 

Also, I'm not really sure what I'm doing when I buffer the data - maybe I'm doing that wrong?

 

Here my sample code - it runs behind a trivial form that just has input boxes for the frequency and duty cycle, and a start and a stop button.  Any advice is appreciated.

 

Private Sub StartButton_Click(sender As Object, e As EventArgs) Handles StartButton.Click

        Try

            StopButton.Enabled = True

            StartButton.Enabled = False

            DutyCycleTrackBar.Enabled = False

            FrequencyUpDown.Enabled = False

            '

            ' set up a counter to generate a PWM pulse

            '

            Dim freq As Double = Me.FrequencyUpDown.Value

            Dim dutyCycle As Double = CDbl(DutyCycleTrackBar.Value) / 100.0

 

            countTask = New Task("PWM Generator")

            countTask.COChannels.CreatePulseChannelFrequency("Dev1/ctr0", "ContinuousPulseTrain", COPulseFrequencyUnits.Hertz,

                                                                COPulseIdleState.Low, 0.0, freq, dutyCycle)

            countTask.Timing.ConfigureImplicit(SampleQuantityMode.ContinuousSamples, 1000)

            '

            ' set up a task for outputting to the LED digital output lines

            '

            digitalWriteTask = New Task("Digital Write Task")

            digitalWriteTask.DOChannels.CreateChannel(ILLUM_CHANNEL_1_LINES, "first4", ChannelLineGrouping.OneChannelForAllLines)

            digitalWriteTask.DOChannels.CreateChannel(DILLUM_CHANNEL_2_LINES, "last2", ChannelLineGrouping.OneChannelForAllLines)

            '

            ' configute the timing on the output task to utilize the output of the timing task

            '

            digitalWriteTask.Timing.ConfigureSampleClock("Ctr0InternalOutput", 1.0, SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples)

            '

            ' Write On/Off data into the buffer (2 samples - 1 for each state)

           '

            Dim writer As New DigitalMultiChannelWriter(digitalWriteTask.Stream)

            Dim offData(,) As Boolean = {{False, False, False, False}, {False, False, False, False}}

            Dim onData(,) As Boolean = {{True, True, True, True}, {True, True, True, True}}

            digitalWriteTask.Stream.ConfigureOutputBuffer(2)

 

            writer.WriteSingleSampleMultiLine(False, onData)

            writer.WriteSingleSampleMultiLine(False, offData)

            digitalWriteTask.Control(TaskAction.Verify)

 

            digitalWriteTask.Start()

            countTask.Start()

 

        Catch ex As Exception

            MsgBox(ex.Message)

 

        Finally

 

        End Try

    End Sub

 

 

 

0 Kudos
Message 5 of 6
(4,485 Views)
Solution
Accepted by topic author mclaus

That sounds like expected behavior, assuming the positive is the first half of the duty cycle. All your rising edges will be an equal distance apart, it is the falling edges that will vary. However, like I said before, dynamically generating a PWM signal would need to be done on a PFI line, not a DIO line. DIO is for a predetermined waveform. 

 

Using a DIO line, you have a buffer of samples that you create, and then output one sample from that buffer at each clock tick, at which point it is removed from the buffer. The reason this doesn't work well for PWM is that when your reference signal changes, you still have to go through all the samples in the buffer before you can change the output pattern. So there will always be a latency from when there is a change in input to when there is a change in output.

 

It would be simpler if you instead routed the output of the Counter to a PFI line, and simply connected your LED to that PFI line. Once you have it working with a single LED, then you can scale it up to the full six.

William R.
0 Kudos
Message 6 of 6
(4,432 Views)