How to calculate the duty cycle of a time signal in a for loop?
You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Show older comments
0 votes
Hi All,
I have multiple time signals and like to compute their duty cycles automatically within a "for loop". For example the duty cycle of the following signal is 74.29%. The signal is attached and the sample rate is 15360000.

Assume I have a bunch of these signals. How can I calculate the ratio of the pulse width (duration of the on state) to the pulse period (the total duration of an on-and-off state) for each signal in a for loop?
Thanks in advance!
Accepted Answer
Walter Roberson
on 14 Mar 2023
load waveform
wr = real(waveform);
wi = imag(waveform);
subplot(2,1,1); plot(wr); ylabel('real');
subplot(2,1,2); plot(wi); ylabel('imag');

mr = movmedian(wr, 5);
mi = movmedian(wi, 5);
mean(abs(mr)<0.01) * 100
ans = 74.2301
mean(abs(mi)<0.01) * 100
ans = 74.4255
9 Comments
@Walter Roberson Thank you so much for your response. It works well. Just a quick question, I noticed that the duty cycle depends pretty much on the "k" value in the movmedian(w,k). How do you choose this value, and how should I find the best "k" for each signal within a loop? For example, for the attached signal, I expect to get an 85.68% duty cycle; however, if I don't change the "k", I get the ~72.4% duty cycle.
And, one more question, How can I compute the representative rate, i.e., 1KHz for the attached signal?
Walter Roberson
on 15 Mar 2023
To be honest, I guessed.
I tried without the movmedian() first, but got values around 54%, which I realized was because the data just happens to have a lot of zero-ish values.
Oh wait, I calculate the wrong thing, don't I? You should not be interested in the portion that is near 0, you should be interested in the portion that is not near 0 -- abs(mr)>0.01 rather than abs(mr)<0.01
The basic idea was that the signal is changing rapidly, and that putting it through a filter should remove a bunch of values that happen to be near 0 in the rapidly changing regions. But I realize now that can be flawed depending on how you happen to do the filtering, especially if the data just happens to be fairly symmetrical.
So maybe movmax() would be better... no, that is still only about 54%
load waveform
wr = real(waveform);
wi = imag(waveform);
mr = abs(wr(3:end) - wr(1:end-2)) > 0.001;
mi = abs(wi(3:end) - wi(1:end-2)) > 0.001;
mean(mr) * 100
ans = 72.0809
mean(mi) * 100
ans = 72.0698
Ah, that works with your original file. I will try your newer file in a moment.
Walter Roberson
on 15 Mar 2023
%newer file -- still not what you were hoping for though
load waveform
wr = real(waveform);
wi = imag(waveform);
mr = abs(wr(3:end) - wr(1:end-2)) > 0.001;
mi = abs(wi(3:end) - wi(1:end-2)) > 0.001;
mean(mr) * 100
ans = 77.2289
mean(mi) * 100
ans = 77.2764
Walter Roberson
on 15 Mar 2023
%newer file
load waveform
wr = real(waveform(:).');
wi = imag(waveform(:).');
maskr = abs(wr) < 1e-3;
startsr = strfind([0 maskr], [0 1 1]);
stopsr = strfind([maskr 0], [1 1 0]) + 2;
(1 - sum(stopsr - startsr) / numel(wr)) * 100
ans = 79.5306
maski = abs(wr) < 1e-3;
startsi = strfind([0 maski], [0 1 1]);
stopsi = strfind([maski 0], [1 1 0]) + 2;
(1 - sum(stopsi - startsi) / numel(wi)) * 100
ans = 79.5306
This counts any place with two or more consequative almost-0 as being out of the duty cycle. Using wr == 0 instead of testing for < 1e-3 makes only a small difference in the fraction.
I do not see any way you could say that the duty cycle is near 85% for this signal.
Susan
on 15 Mar 2023
@Walter Roberson thank you so much for the response. I compute the duty cycle as follow

(30721-17560)/(32920-17560)
ans =
0.8568
That's what I think the DC is near 85% for this signal. Any thoughts?
Walter Roberson
on 15 Mar 2023
My code assumes that the initial burst is part of the signal whose duty-cycle is to be calculated.
Susan
on 15 Mar 2023
@Walter Roberson I see. Do you think there is any way to consider the repeatable part of the signal and ignore any initialization at the beginning?
Walter Roberson
on 15 Mar 2023
We can tell from the graphs that the only part of the signal this is "repeatable" is the zeros.
You can do things like
%newer file
load waveform
wr = real(waveform(:).');
wi = imag(waveform(:).');
maskr = abs(wr) < 1e-3;
stopsr = strfind([maskr 0], [1 1 0]) + 2;
mean(~maskr(stopsr(2):stopsr(end-1)-1)) * 100
ans = 77.2091
maski = abs(wr) < 1e-3;
stopsi = strfind([maski 0], [1 1 0]) + 2;
mean(~maski(stopsi(2):stopsi(end-1)-1)) * 100
ans = 77.2091
This measures for the signal starting from end of the second stretch of zeros (so skipping the first pulse). But you can see it made little difference (gave a lower duty cycle in fact.)
To go much beyond that you would need a more explicit definition of what should be skipped.
Susan
on 16 Mar 2023
@Walter Roberson I see. Thanks again for your help. Appreciate it.
More Answers (0)
Categories
Find more on Pulse and Transition Metrics in Help Center and File Exchange
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)