How can I create a single square wave of varying duty cycle in MATLAB?
12 views (last 30 days)
Show older comments
Joel Kelly
on 23 Mar 2019
Commented: Joel Kelly
on 28 Mar 2019
Hello,
I am wanting to create a square wave in MATLAB that increases it's duty cycle with respect to time, however when I tried to implement this, I ran into the error of MATLAB only allowing scalar values for the duty cycle.
Is there any way around this?
Here is my current code, based off of this example: https://uk.mathworks.com/matlabcentral/answers/217746-implementing-a-sine-wave-with-linearly-changing-frequency
Fs = 100000;
t = 0:1/Fs:1;
f_in_start = (100*1/3)/(100*0.1); %1-to-2 PFM
f_in_end = 50/(100*0.1); %1-to-1 PFM
f_in = linspace(f_in_start, f_in_end, length(t)); %Varying pulse frequency
DC_start = 100*1/3; %1-to-2 PFM
DC_end = 100*1/2; %1-to-1 PFM
DC_in = linspace(DC_start, DC_end, length(t)); %Varying the duty cycle
DC = cumsum(DC_in/Fs); %Duty cycle
phase_in = cumsum(f_in/Fs); %frequency
y = 0.5*square(2*pi*phase_in,DC) + 0.5;
plot(t,y)
For context, the aim is to create a PFM waveform that increases in frequency with respect to time, increasing from a 1-to-2 mark space ratio to a 1-to-1 whilst keeping the 'on-time' of the signal constant.
Ideally, the waveform should look something like this at the start:

And end with something like this:

Thank you in advance
2 Comments
dpb
on 23 Mar 2019
I've not messed with it enough to know for certain, but I think you could make this work with the pulstran function by setting the pulse time vector to the variable spacing to get the desired duty cycle while the pulse vector uses the same rectangular pulse generator function.
Accepted Answer
Gabriel Emile Hine
on 25 Mar 2019
Edited: dpb
on 25 Mar 2019
If I understood the problem, this code should work for you. If you have anu doubts, please ask me.
Duration = 10;
Fs = 100000;
t = 0:1/Fs:Duration;
pulse_width = 0.1;
duty_start = 1/3;
duty_end = 1/2;
N_pulses = Duration /((pulse_width/duty_start + pulse_width/duty_end) /2);
dutys = linspace(duty_start,duty_end,N_pulses);
cycle_periods = pulse_width./dutys;
cycle_starts = cumsum([0 cycle_periods]);
square_wave = double(sum( ...
bsxfun(@ge,t, cycle_starts(:)) & ...
bsxfun(@le,t ,cycle_starts(:)+pulse_width(:)) ...
,1)>0);
plot(square_wave)
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!