LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Writing PWM data to analog using FPGA

Hello,

 

I am working on a project to read the period of a PWM signal using FPGA. I am transferring that data to the host(RT) to calculate frequency and then convert it into an analog signal to write it on an analog channel in RT.

 

However, it is not writing anything to the analog channel. Can somebody suggest a proper method to do it, I just want the latest data because the frequency will remain same, so there is no need to buffer? Also, if I can know that what is the possible cause of the error in my VI?

 

Regards,

Kashish Dhal

Download All
0 Kudos
Message 1 of 14
(3,612 Views)

Do you not have access to a DIO port?

0 Kudos
Message 2 of 14
(3,593 Views)

I have access and able to read the frequency successfully. However, I can not write the value to analog channel.

0 Kudos
Message 3 of 14
(3,589 Views)

You don't appear to have any loop timing implemented, with the exception of the timed loop on the RT side.  The while loop below it is executing as fast as possible, which will likely consume near 100% of available CPU resources, as well as monopolize access to the local variable you are attempting to write to within the timed loop.

 

In your FPGA VI, you don't actually have to perform the period calculation explicitly using functions.  Timed loops provide this information automatically.  Just make the left hand data node visible and select the appropriate option.  You can wire that output directly into your indicator.  What period have you configured for that timed loop?  Generally, you want to look up the hardware specifications of your input I/O and see how fast you can acquire values, and then time the I/O reads in the FPGA accordingly.

 

On the RT side, you could then choose to synchronize to this, or as I think you have done, implement a slower read loop to read from the FPGA I/O node and perform your processing.  I wonder why you have chosen to use a local variable here?  You also have UI updates within a RT timed loop, which is unnecessary.  What I would do instead is put your analog output write within the RT timed loop, and set the loop timing to match the permissible update rate of the output hardware.  Then, move all of your UI update functions (indicators) to the non-deterministic loop, instead of performing front panel updates in the timed loop.  Instead, wire all of the desired ouputs to single point RT FIFOs in the timed loop, and read from those FIFOs (buffered read) in the non-deterministic loop, updating the front panel controls from there.  The UI doesn't need to update any faster than 100ms or so.  Faster is rarely perceptible, and just consumes CPU resources.  Then you can optimize the period of the timed loop to take advantage of your I/O hardware capabilities.

0 Kudos
Message 4 of 14
(3,579 Views)

Just to add to that, unless you have some other means of loop synchronization (i.e dequeue function etc.), you should always add sleep time via wait functions to non-deterministic loops, in order to cede resources to other processes.

0 Kudos
Message 5 of 14
(3,577 Views)

Thank you for your valuable input.

To answer your question, I thought the maximum frequency of a while loop is 1 Khz. So, I used the  while loop and I was writing a value to Analog Output channel inside that while loop and it was not writing to that channel.

So, I used two loops instead running at different rates and passed data using local variable but that didn't work either.

I am running FPGA loop at 40 MHz and I don't know how to get time from left node. To add, I am acquiring data but I am not able to write it.

Also, I just want to read the latest data, so is it mandatory to use FIFO in RT? I can try changing the timeloop on RT.

 

Regards,

Kashish Dhal

0 Kudos
Message 6 of 14
(3,567 Views)

Right-click on the left or right borders of the timed structure to show the data nodes.  These can be expanded to show additional available data.  Fully populated, a timed loop structure looks like this:

 

Timed Loop with data nodes shown and expandedTimed Loop with data nodes shown and expanded

 40 MHz is the clock rate of the FPGA chip.  This represents the maximum possible resolution of your loop timing, but it is unlikely that you will actually be able to execute code that performs I/O within a single tick at 40 MHz.  Double-click the timed structure to configure it if you're not using the dynamic inputs.  Loop timing period will be one of the settings.  What hardware are you using?  On a CompactRIO target, for example, each type of C-series module will have its own specifications for supported sample rate or output update rate.  Running your FPGA loop faster than these specified values offers no benefit.  As I use many different types of I/O modules, I generally create a separate loop for each one, and run it at the maximum rate supported by the module for full channel complement update.  That way, when I read from FPGA I/O nodes in my RT code, I always have the latest values available, without attempting unnecessary reads, and I can set the RT timed loop to a period appropriate for what I'm trying to do. I might set the hardware output loop on the FPGA to my desired PWM frequency, but run the RT loop a lot slower if I'm only passing a duty cycle % to the FPGA, for example.

 

So your RT timed loop needs to read from the FPGA I/O, perform your processing, and write to the analog output (is this on the FPGA, or implemented some other way?)  In either case, the ultimate purpose of that loop is to write to a hardware analog output, and to do so deterministically.  The fastest update rate that makes sense is therefore the fastest update rate supported by the output hardware.  If you're doing PWM, it doesn't make much sense to iterate faster than your PWM frequency.  You can of course go slower, which will reduce resource usage if you don't require such rapid processing, but it's your call.  I tend to optimize my code for speed initially, and then back off loop rates when I need to free CPU utilization.

 

The RT FIFO is a way of passing data between deterministic and non-deterministic loops without affect the determinism of your RT timed loop.  This can be done either with the RT FIFO functions, or by creating single-process shared variables with RT FIFO enabled, which is a simpler implementation, but somewhat less scalable.  In any case, both reading from the FPGA I/O, signal / data processing, and writing to the analog output should be in the deterministic loop.  What I'm suggesting is to create a RT FIFO for each value that you want to pass from the deterministic loop to the non-deterministic processes, such as updating your UI, logging to file, network communication, etc.  Each iteration of the timed loop will write a single value to the RT FIFO at the timed loop rate (i.e. no buffer).  Analog output in that timed loop will also execute at that rate.  In the while loop, however, you read the latest single value out of each of those RT FIFOs for updating your front panel controls and so forth - the less important processes.  That way, no matter what happens in the while loop with regard to processing delays, it will not affect the determinism of your control.  Using them this way is lossy, but unless you need to stream the data (in which case you would set some buffer size, and continue to write a single element in each iteration of the timed loop, but read multiple points at once in the non-deterministic loop which is executing slower), you don't care.

 

If updating your front panel indicators is all you need to do, I would insert a 100 ms delay (or wait for ms multiple) in the while loop.  10 Hz is as fast as you need to update indicators for it to still appear smooth, and the delay allows the scheduler to allocate CPU time to other processes.

0 Kudos
Message 7 of 14
(3,560 Views)

I did not say that my code is executing at one tick, I am not even bothered about how many ticks it takes to execute. However, I am measuring the difference between the two ticks values for rising edges.

After getting ticks, I multiply with a no. to convert that into frequency. I am sending certain frequency from a board and I already verified that it is correctly read by FPGA. 

The next step is to convert this frequency into analog signal and then send to AO pin.

I am not concerned or interested about UI, as long as conversion is good, I can do it in FPGA.

As per previous post, I was sending Analog Out signal from RT but I can do it in FPGA as well if you think it will be better.

Tell me what should I do.

 

Regards,

Kashish Dhal

0 Kudos
Message 8 of 14
(3,554 Views)

This time I tried using Wait=100ms inside While loop to write data to Analog Channel (data is acquired at FPGA) but its still not executing. The image is attached. When I put a probe it reads 10 but I am not getting any output volotage.

 

Regards,

Kashish Dhal

0 Kudos
Message 9 of 14
(3,547 Views)

First thing I would to is determine whether there is any way that the required processing could be done on the FPGA instead of on the RT CPU.  In your case, I see that you are using extended precision floating point numbers in your code, so I'm guessing that the answer to that question is no, but sometimes you can use fixed-point and other supported functions to implement your algorithms on the FPGA fabric exclusively, which would be both faster and more robust.  Since you can't do that, the next thing I would look at are the supported I/O rates.  In your FPGA code, you have an I/O node labeled "ConnectorC/DIO0".  What is the actual hardware you are using? I would figure out how fast that DIO line could possibly be updated (check the hardware datasheet), and set the loop rate in the FPGA to that speed.  That will give you the best possible resolution for your "Measured Period (Ticks) 2" calculated output.  If you run the loop faster, you don't gain useful information, because additional iterations will only produce cached values.  I also might consider replacing the timed loop structure with a while loop with an included loop timer VI, but those are functionally identical implementations.

 

If you can write to your analog output on the FPGA instead of directly from the RT VI, that is preferable.  If that is possible, before figuring out what rate to use for the RT timed loop, you need to determine what the maximum supported output update rate of the hardware is, for your output channel "C/AO0 (AO0)", just as you did for the input.  The loop rate of the RT timed loop structure should then be the same as the slower of the two hardware rates, because any faster would either be reading cached input values, or writing faster than the output hardware can accommodate.  On the FPGA, create a second loop with appropriate timing for the output channel updates, and where you currently have the "analog out" indicator, write that instead to the new FPGA I/O node.  Lose the local variable entirely.

 

Move all of your front panel indicators (frequency, feed rate, Waveform Chart and analog out) in the RT VI to the non-deterministic loop, replacing them in the timed loop with RT FIFO writes (no buffer).  In the non-deterministic loop, create RT FIFO reads that then update the indicators.  Time this loop at a period of 100 ms, as it doesn't need to iterate anywhere near as fast as your hardware updates.

 

Finally, check that the processing you are doing in the RT timed loop can be accomplished in the allotted period.  Check the "finished late?" output from the left hand data node to see if it can keep up.  If not, reduce your loop periods accordingly.

 

 

0 Kudos
Message 10 of 14
(3,540 Views)