LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

90 Degree Phase shift between two PWM signals

HI,
I HAVE GENERATED TWO PWM SIGNALS USING DAQmx FUNCTIONS IN LabWindows/CVI, AND I WANT A PHASE SHIFT OF 90 DEGREES BETWEEN THEM. CAN I HAVE THE SOLUTION FOR THIS PROBLEM
0 Kudos
Message 1 of 8
(6,356 Views)
Hi,

I would recommend using a Hilbert Transform. It is located in ::Advanced Analysis Library -> Signal Processing -> Frequency Domain -> FastHilbertTransform

The Hilbert transform should perform a 90 degree phase shift on the real part of your waveform.

http://forums.ni.com/ni/board/message?board.id=170&message.id=78713&requireLogin=False

Regards,
Matthew Slaughter
Applications Engineer
National Instruments

LabVIEW Integration Engineer with experience in LabVIEW Real-Time, LabVIEW FPGA, DAQ, Machine Vision, as well as C/C++. CLAD, working on CLD and CLA.
0 Kudos
Message 2 of 8
(6,333 Views)
Hi Matthew Slaughter
Thanks for giving the suggestion. And one more small help from you. Can you provide sample program on using this.

Thanks and Regards
Murali Krishna
0 Kudos
Message 3 of 8
(6,315 Views)
Hi Murali-

How are you generating your signals? Are you using a counter or are you generating the entire cycle of operation at the beginning and using an analog (or digital) output? The hilbert transform will only work if the entire array is generated at the beginning of operation and not if you are adjusting parameters on the fly.

Please give us a bit more information about what type of output you are using and how exactly you are generating the signals. A small portion of your code might be helpful for troubleshooting or giving tips.

Thanks-
Tom W
National Instruments
0 Kudos
Message 4 of 8
(6,300 Views)
Hi Tom

We have a knob on the GUI,The knob represent dutycycle. on rotation of the knob
the application should generate two PWM signals with the dutycycle read from the knob and a constant frequency(500 Hz). There should be a 90 degrees phase shift between these two PWM signals generated .We are using counters for generating the PWM signals.
This is the piece of code we are using

/*****************************************************************************
FUNCTION NAME : Configure_WritePwm
DESCRIPTION : Configures ,starts the task and Writes
PARAMETERS DESCRIPTION : Recommended parameters:chan = "Dev1/ctr0",frequency,duty cycle, idlestate,taskhandle
Return Value : 0 if Success else negative number
*****************************************************************************/
int32 Configure_WritePwm(const char chan[], float64 freq, float64 duty,int32 IdleState, TaskHandle *taskHandle)
{
int error=0;
static int cnt = 0;
/*Create a task*/
DAQmxErrChk (DAQmxCreateTask("",taskHandle));
/*Create an pwm Output Channel*/
DAQmxErrChk (DAQmxCreateCOPulseChanFreq(*taskHandle,chan,"",DAQmx_Val_Hz,IdleState,0.0,freq,duty));
/*Sets only the number of samples to acquire or generate without specifying timing*/
DAQmxErrChk (DAQmxCfgImplicitTiming(*taskHandle,DAQmx_Val_ContSamps,1000));

Error:
return error;
}
/*****************************************************************************
FUNCTION NAME : Start_WritePwm
DESCRIPTION : Starts the task
PARAMETERS DESCRIPTION : Task Handle
Return Value : 0 if Success else negative number
*****************************************************************************/
int32 Start_WritePwm(TaskHandle taskHandle)
{
return DAQmxStartTask(taskHandle);
}
/*****************************************************************************
FUNCTION NAME : Stop_Write_Pwm
DESCRIPTION : Stops the task
PARAMETERS DESCRIPTION : Task Handle
Return Value : 0 if Success else negative number
*****************************************************************************/
int32 Stop_Write_Pwm(TaskHandle taskHandle)
{
int32 error=0;
error = DAQmxStopTask(taskHandle);
DAQmxClearTask(taskHandle);
return error;
}


Thanks and Regards
Murali Krishna
0 Kudos
Message 5 of 8
(6,296 Views)
Hi Murali-

This problem is somewhat difficult to implement but can be accomplished using both of the counters on your board.

For the counter that will not be delayed you can simply create the pulse train of user-specified pulse width as you have done in your code above. To generate the delayed pulse train you will need to generate single pulses of appropriate pulse width and with appropriate delays set. You will then trigger these single pulses from the original signal and the specified delay will result in the delayed operation you desire. I'm not sure exactly what you mean by a 90 degree shift, but if you are attempting to delay 0.25 periods this delay will be easy to calculate based on your main constant output frequency.

The example "DigPulse.prj" in the NI Example Finder (Help>Find Examples in CVI) under Hardware Input and Output>DAQmx>Generating Digital Pulses shows how to create a pulse of specified delay on a counter output line. I have added the following line in the Generate callback to specify triggering for the PFI0 line:

DAQmxErrChk (DAQmxCreateCOPulseChanTime(taskHandle,chan,"",DAQmx_Val_Seconds,idle,initialdelay,lowtime,hightime));
DAQmxErrChk (DAQmxCfgDigEdgeStartTrig (taskHandle, "PFI0", DAQmx_Val_Rising));

You will need to find an available PFI line for your device and route the first counter output to this line externally.
Best regards-
Tom W
National Instruments
0 Kudos
Message 6 of 8
(6,274 Views)
Hi Tom

Thanks for your immediate response.

Precisely to be more clear

Internally our application writes to two counter channels by calling the function Configure_WritePwm() which i have posted yesterday. Two PWM pulse train are being generated. Our requirement is that one signal should lead the other signal by 90 degrees(delay 0.25 periods ).

We tried to establish this phase shift by initally generating one pulse train on one counter channel with initial_delay set to zero when calling the write using
DAQmxCreateCOPulseChanFreq(*taskHandle,chan,"",DAQmx_Val_Hz,IdleState,initial_delay,freq,duty)
and then generating another pulse train on another channel with the initial_delay set to 1/(4*frequency) when calling the above function. But we observing different phase shifts at different instances rather to 90 degrees which was expected.

Does the function call to write each counter effect the phase difference between the signals in any way

Could you clarify more on this?

Thanks and Regards
Murali Krishna
0 Kudos
Message 7 of 8
(6,249 Views)
Hi Murali-

What type of board are you using to generate your pulses? If you are using a counter/timer board the initial delay will work as desired, but this functionality is not supported on E Series multifunction DAQ cards. If your board is E Series then my original suggestion will be the only option.

For a counter card, unless you specify triggering of one channel by the other channel, generation will begin as soon as the task is started. This could explain why you are seeing phase shifts that differ from those that you request. If the initial delay is supported on your card then the operation will be as easy as setting the second (delayed) pulse train to start generation based on triggering by the first (non-delayed) pulse train. By selecting continuous operation you will ensure that the phase difference is maintained throughout the generation.

So, to reiterate calling the starts for the tasks in succession does not mean they will start simulaneously or even sync up well at all. The only method to accomplish this is with triggering for the tasks.

Thanks again-
Tom W
National Instruments
0 Kudos
Message 8 of 8
(6,220 Views)