MATLAB Answers

Problem with phase delay implementation on a square wave

14 views (last 30 days)
Jordan Monthei
Jordan Monthei on 6 May 2013
I am implementing a Level 2 S-function that generates a square wave that can have a changing duty cycle, phase delay, and dead time which updates every sample. Currently i am only testing a changing phase delay with duty cycle and dead time set as constant parameters. The phase delay change is being simulated with a step-function input which steps at time t with an amplitude which is read as phase in degrees.
The problem occurs when the step occurs at a time when the square wave output is low as the phase delay does not take place. If the step occurs at a time when the square wave is high, then the phase delay does take place. The input is stored as a dWork vector every time the block is updated. I have monitored the dWork vector and noted that the value changes as it is supposed to, but the square wave is not updated appropriately as discussed above, thus i know the input and its corresponding dWork vector are updating correctly. I have included my code below as well.
Note: the dWork Vector 'Rise' is used to signify a rising edge is expected
function vgp(block)
% this function is meant to have a gate pulse signal wherein the duty
% cycle, phase delay, and dead time can all be changed on a per sample
% basis.
setup(block);
%endfunction
function setup(block)
block.NumDialogPrms = 3;
% Register number of ports
block.NumInputPorts = 1;
block.NumOutputPorts = 1;
% Setup port properties to be inherited or dynamic
block.SetPreCompInpPortInfoToDynamic;
block.SetPreCompOutPortInfoToDynamic;
% Override input port properties
block.InputPort(1).DatatypeID = 0; % double
block.InputPort(1).Complexity = 'Real';
block.InputPort(1).Dimensions = 1;
block.OutputPort(1).DatatypeID = 0;
block.OutputPort(1).Complexity = 'Real';
block.OutputPort(1).Dimensions = 1;
% Register sample times
block.SampleTimes = [-2 0]; % set for variable sample time
% Set the block simStateCompliance to custom
block.SimStateCompliance = 'CustomSimState';
% Register methods
block.RegBlockMethod('PostPropagationSetup', @DoPostPropSetup);
block.RegBlockMethod('InitializeConditions', @InitializeConditions);
block.RegBlockMethod('Start', @Start);
block.RegBlockMethod('Outputs', @Outputs);
block.RegBlockMethod('Update', @Update);
%endfunction
function DoPostPropSetup(block)
% Initialize the Dwork vectors
block.NumDworks = 7;
block.Dwork(1).Name = 'CurrentState';
block.Dwork(1).Dimensions = 1;
block.Dwork(1).DatatypeID = 0; % double
block.Dwork(1).Complexity = 'Real'; % real
block.Dwork(1).UsedAsDiscState = true;
block.Dwork(2).Name = 'NextSample';
block.Dwork(2).Dimensions =1;
block.Dwork(2).DataTypeID =0;
block.Dwork(2).Complexity ='Real';
block.Dwork(2).UsedAsDiscState = true;
block.Dwork(3).Name = 'PhaseDelay';
block.Dwork(3).Dimensions = 1;
block.Dwork(3).DataTypeID = 0;
block.Dwork(3).Complexity ='Real';
block.Dwork(3).UsedAsDiscState = false;
block.Dwork(4).Name = 'DutyCycle';
block.Dwork(4).Dimensions = 1;
block.Dwork(4).DataTypeID = 0;
block.Dwork(4).Complexity = 'Real';
block.Dwork(4).UsedAsDiscState = true;
block.Dwork(5).Name ='RiseCheck';
block.Dwork(5).Dimensions = 1;
block.Dwork(5).DataTypeID = 0;
block.Dwork(5).Complexity ='Real';
block.Dwork(5).UsedAsDiscState = true;
block.Dwork(6).Name ='DeadTime';
block.Dwork(6).Dimensions = 1;
block.Dwork(6).DataTypeID = 0;
block.Dwork(6).Complexity ='Real';
block.Dwork(6).UsedAsDiscState = true;
block.Dwork(7).Name ='SampleTime';
block.Dwork(7).Dimensions = 1;
block.Dwork(7).DataTypeID = 0;
block.Dwork(7).Complexity ='Real';
block.Dwork(7).UsedAsDiscState = true;
function Start(block)
block.Dwork(1).data = 0; % initial state to 0
block.Dwork(3).data = 0; % take in phase input
block.Dwork(2).data = 0+eps; % initialize next sample
block.Dwork(5).data = 0; % start before rising edge
function InitializeConditions(block)
block.Dwork(4).data = block.DialogPrm(1).data; % load duty cycle from param
block.Dwork(6).data = block.DialogPrm(2).data; % load dead time from param
block.Dwork(7).data = block.DialogPrm(3).data: % load SampleTime from param
function Outputs(block)
block.OutputPort(1).data = block.Dwork(1).data; % outputs data
block.NextTimeHit = block.Dwork(2).data; % sets the time for next sample
function Update(block)
%update values to be used for next sq. wave calculation
block.Dwork(3).data = block.InputPort(1).data;
block.Dwork(3).data = block.Dwork(3).data / 360; %set in degrees
offtime = 0.5*(1-block.Dwork(4).data);
Ts = block.Dwork(7).data;
DeadTime = block.Dwork(6).data;
%Generation of the square wave with 50% duty cycle
if block.Dwork(1).data == 0 && block.Dwork(5).data == 0 %initial step
block.Dwork(1).data = 0; %stay at 0
block.Dwork(5).data = 1; %signal to rise
block.Dwork(2).data = block.Dwork(2).data + DeadTime + (offtime + block.Dwork(3).data)*Ts; %next sample time
elseif block.Dwork(1).data == 0 && block.Dwork(5).data == 1 %rising edge
block.Dwork(1).data = 1; %set high
block.Dwork(2).data = block.Dwork(2).data + block.Dwork(4).data*Ts - DeadTime; %next sample time
elseif block.Dwork(1).data == 1 && block.Dwork(5).data == 1 %falling edge
block.Dwork(1).data = 0; %set low
block.Dwork(5).data = 0; %reset signal
block.Dwork(2).data = block.Dwork(2).data + (offtime - block.Dwork(3).data)*Ts; %hold for next
end

  1 Comment

Jordan Monthei
Jordan Monthei on 6 May 2013
Please feel free to ask for any clarifications about the problem occurring, or the system being implemented.
if you would like to implement this yourself. Create a custom Level 2 S-function with the above code. Then in a simulink block file, use a step-function input with a step that can range from -89 to 89 degrees. The output of the block should go to a scope. I also found it helpful to use a pulse generator which is also an input into the scope as a comparison signal (if so, use a 50% duty cycle and 0.25 phase delay). Additionally it helps to have the step-function feed into the scope to note where the step occurs in relation to the block output.
In the s-function block parameters should be set as : Duty cycle (decimal value 0 to 1), dead time (best left at 0), Sample Time (best left as 1).
with that setup, begin with the step function staying at 0 for the duration of your test to note where the base signal is. Then, set the step-function block so that the step occurs with an amplitude of +/- 89 for a noticeable shift while the square wave output of your custom S-function is high and note the output. Then change the step so that it occurs while the square wave is low and you should see my problem.

Sign in to comment.

Answers (0)

Sign in to answer this question.