Sunteți pe pagina 1din 9

instructables

How to Measure High Frequency and Duty Cycle, Simultaneously, Using a


Microcontroller.

by MolecularD

I know what you think: "Huh? There are lots of While the MCU measures signal's period, it can also
Instructables on how to use microcontrollers to determine its pulse width, P: the time of signal
measure signal frequency. Yawn." But wait, there is a voltage remaining high. In other words, time between
novelty in this one: I describe a method of measuring low-to-high and high-to-low transitions. The signal's
frequencies much higher than a microcontroller duty cycle is then defined as the following
(MCU) can bear and the signal's duty cycle - all at the percentage:
same time!
Duty = 100% * P / T
The device's frequency range spans from ~43 Hz to
~450 kHz, while duty cycle ranges from 1% up to Just like in the case of frequency, there is a practical
99%. limit on pulse width. Using the above example, 106
clock cycles would limit the pulse width to no less
Let me explain the "can bear" part: an MCU than 2.21 microseconds. Or, no less than 50% at
226.4
How to Measure High Frequency and Duty Cycle, kHz.
Simultaneously, Using a Microcontroller.: Page 1
measures period of a square wave signal, T, by 226.4 kHz.
tracking time between two subsequent transition
events. For example, low-to-high voltage jumps on One of the ways of boosting up the upper frequency
one of its I/O pins. It does it by counting the number limit of square wave signals is the application of digita
of pulses of its own internal clock. Naively, the upper l dividers that utilize flip-flops. Dividing the input
limit for measured frequencies should obey the Nyqvi frequency by n would extend the measurable upper
st-Shannon sampling theorem; i.e., it would roughly range n times. This is great news, digital dividers
equal to the half of the MCUs clock frequency. In have one fundamental flaw: divided signal loses the
reality the limit is much, much lower, because the pulse width (and duty cycle) information! Because of
MCU must execute code to handle interrupts, save the way the dividers work, their output has always
variables, do arithmetic operations, display results, 50% duty cycle. Bummer...
etc. In my experiments with a 48 MHz MCU the
minimal number of clock cycles between measurable In the following pages, however, I will show how to
transitions was about 106. Hence, the upper limit of digitally divide frequency and preserve the original
the measurable frequency range in this case would pulse width allowing me to measure signals well
be 48,000 / 212 / 2 = 226.4 kHz. beyond the limits imposed by direct counting.

1. My square wave generator in a tea can enclosure; not covered by this


Instructable.
2. Frequency and duty cycle detector, also in a tea can, which is the
subject of this Instructable.

How to Measure High Frequency and Duty Cycle, Simultaneously, Using a Microcontroller.: Page 2
How to Measure High Frequency and Duty Cycle, Simultaneously, Using a Microcontroller.: Page 3
Step 1: Digital Frequency Division

Traditional digital frequency dividers use flip-flops; thi Adding another JK flip-flop in a configuration shown
s tutorial nicely explains principles how to construct in the third figure divides the original frequency by 4.
dividers using standard JK flip-flops. This solves the Adding more flip-flops in the same sequential manner
problem of input frequencies too high for the MCU, divides frequency by subsequent powers of 2: 8, 16,
but has one major drawback: divided signal has 50% 32, etc.
duty cycle irrespective of the input signal's duty! To
see why it's the case look at the first two figures. The Problem: how to divide frequency of a square wave
original signal with period T and pulse width P is fed while preserving it's pulse width?
into the clock pin of a JK flip-flop while its J and K
pins are held high at all times (first figure). 3.3V logic The idea is to properly add a negative edge triggered
is assumed throughout. Let's suppose that the flip- JK flip-flop to the mix. Let's call it "Neg FF"; see fourth
flop is triggered by the positive (i.e., rising) edge of figure. Here, "properly" means that the J and K pins
the clock. Under these conditions, changes of the of the new flip-flop are tied to the Q and Qbar output
state of the output pin (individual "flips" and "flops") pins, respectively, of the divider-by-4 ("Pos FF")
occur every time the clock pin goes from low to high. illustrated in the previous figure. (In here, "bar" is the
The clock's high to low transition (i.e., the negative horizontal bar over the Q symbol indicating logical
edge) is completely ignored. See the second figure. negation.) To see what this achieves take a look at
The output pin, Q, emits a signal whose period is the function table of the "Neg FF" in the fifth figure:
twice as long as the original period, i.e., it's frequency Neg's output pins, Q and Qbar, mirror the state of its
is halved. The output's pulse width is always equal to input pins, J and K, respectively. Which means they
T. Consequently, the original pulse width, P, is lost. mirror the state of the Pos' Q and Qbar. But, the
Neg's flip-flop action must wait for the negative edge

of the original signal, which arrives at time P after the MCU. However, it turned out to be problematic for
positive edge. Aha! very short pulse widths because of the MCU's 106
cycles limitation mentioned in the Introduction. I've
The resulting waveforms are illustrated in the sixth solved this small problem by picking another output:
figure. "Pos Q" outputs signal at 1/4th frequency, "Pos Qbar" AND "Neg Qbar" instead. One look at the
"Pos Qbar" is it inverse, "Neg Q" follows "Pos Q" waveforms should convince you that pulse width of
shifted by pulse width P, and "Neg Qbar" is its this particular waveform, P', varies between T and 2T
inverse. You can verify that the logical AND of "Pos instead of (0, T) range for P. The P can be easily
Qbar" and "Neg Q" produces a pulse train recovered from P' by:
characterized by the original pulse width P and 1/4th
the frequency. Bingo! P = 2T - P'

At first I used exactly this output signal to feed the

How to Measure High Frequency and Duty Cycle, Simultaneously, Using a Microcontroller.: Page 4
Step 2: Recommended Hardware

I truly like the relative newcomer to electronic hobbyists: Atmel SAM D21 MCUs based on the 32-bit ARM Cortex
M0+ processor operating at 48 MHz clock rate, much higher than the older Atmels. For this project I bought:

ItsyBitsy M0 Express MCU board from Adafruit


I happened to have a rechargeable LiPo battery from Adafruit
Monochrome 128x32 SPI OLED display (you guessed it: Adafruit)
Dual positive-edge-triggered JK flip-flop SN74HC109 from Texas Instruments
Dual negative-edge-triggered JK flip-flop SN74HC112 from Texas Instruments
Quadruple AND gate CD74AC08E from Texas Instruments
Quadruple OR gate CD74AC32E from Texas Instruments

How to Measure High Frequency and Duty Cycle, Simultaneously, Using a Microcontroller.: Page 5
How to Measure High Frequency and Duty Cycle, Simultaneously, Using a Microcontroller.: Page 6
Step 3: The Circuit

The first figure shows a simplified schematic of the The schematic does not show the true complexity of
frequency/duty meter. The 3.3 V CMOS logic is digital chip connections. The second image shows
assumed throughout. Consequently, the input square how the project would look on a breadboard. Input
wave's amplitude must be between the corresponding signal comes through a red wire to the 2CLK pin of
VIH level (i.e., 2 V) and 3.3 V. If not, you need to the dual positive edge flip-flop. CAUTION: Normally,
scale it up or down accordingly. In most cases a all the J and K pins of this flip-flop should be held
simple voltage divider would suffice. If you want to high, but SN74HC109 in particular features the Kbar
design your version of the meter at a different logic pin - an inverted K pin - instead. Hence, this pin must
level, then you have to use another micro controller be grounded! The first negative edge flip-flop in
(MCU), battery, and a display that work at the desired SN74HC112 has its 1K and 1J pin connected to the
level. The logic gates and flip-flops used in this 1Q and 1Qbar pins of SN74HC109. The second flip-
project work with logic levels anywhere between 2 V flop in SN74HC112 is unused and its input pins (2K,
and 6 V and should be OK in most cases. 2J, 2CLRbar) are grounded. All other extra pins
PREbar (preset) and CLRbar (clear) in all flip-flops
As shown, the ItsyBitsy MCU uses pins 9-13 to must be connected to logical high. Unused clock and
communicate with the display through the software output pins are left unconnected. Similarly, unused
SPI protocol. The 3V pin delivers power to the entire input pins in all gates are grounded, while unused
circuit. Digital input pin 3 accepts the analyzed signal, output pins are left unconnected. As I discussed in
while pins 2 and 4 control the signal source: either my "Invisible Killer of the Phone Ring" Instructable,
direct signal coming through gate AND3 (low input grounding unused input pins of logical chips
frequencies), or signal divided by 4 through gate eliminates random oscillations and saves battery
AND4 (high input frequencies) as described in Step power.
2. The code, discussed in the next step, automatically
detects the incoming frequency range and
appropriately switches the signal source.

How to Measure High Frequency and Duty Cycle, Simultaneously, Using a Microcontroller.: Page 7
Step 4: The Code and Measuring Low Frequencies

Naturally, all the action happens in the code linked interrupt handler, but soon I have discovered a very
below. When the input incoming on pin 3 switches much related code in the Arduino Forum posts by
from digital low to high, the MCU starts counting users electro_95, MartinL, and Rucus whose
pulses of its internal 48 MHz clock. It notes the contribution is duly acknowledged. I incorporated and
moment of high to low transition and continues the modified their combined code into mine; saving me a
count until the next low to high switch, when it lot of time!
restarts the whole process again. The first count
represents pulse width, while the entire count As I previously mentioned, the signal resolution is
represents the signal's period. And that's the whole limited by ~106 CPU cycles to execute code between
secret. interrupts. Digital division with pulse width
preservation takes care of high frequencies. Low
The CPU notes these transitions via hardware frequencies, on the other hand pose another
interrupts. The SAMD21 has several clocks; my code challenge: since the TC3 clock counter is 16 bit long,
uses TC3 one. Initially, I've started by reading the it overflows after crossing the 65,536 counts limit.
M0's data sheet bracing for a lot of effort in coding the One can handle this situation by adding an overflow

interrupt, but chose a different solution: TC3 can use signal's frequency, with hysteresis, in order to keep
a prescaled (i.e., software-divided) CPU clock instead the TC3 counter within the overflow limit. As a result,
of the hardware 48 MHz one. Thus, if the signal's the lower end of the device's range is about 43 Hz.
period approaches the overflow limit, the code can
instruct TC3 to use 24 MHz counts for the next period You are welcome to fork the code and use it in your
and, voila, the counter drops below 32,768 counts. project, but please do mention its source when
For even lower frequencies the TC3 can be instructed publishing results.
to count 12 MHz pulses, etc. The appropriate
prescaler is automatically determined based on the Link to the code.
So I made it. As I didn't have any JK-flipflops at hand I made it with three D-flipflops (74LS74), an
inverter (74LS14), and a NAND (74LS00). Also I do not have an Atmel SAM microcontroller, so
there I used a STM32F103C8 , an ARM chip running at 72MHz. And it works. Data is transfered
serial to a pc running Putty.
As you can see in the pictures, I have an oscilloscope that can show frequency and duty cycle so I
don't need this measurement device. But still I might build it on a perfboard, you cannot have too
many tools, can you :-) But then I'll make it with the 74HC series instead of the 74LS. For now, it is
a nice experiment.

Awesome work! Thank you for sharing. My oscilloscope can show frequency and duty cycle, too,
but I wanted something battery operated and portable.
So, ARM Cortex M3! At 72 MHz it looks even better than M0. With it, can you measure frequencies
above 1 MHz? Is that the Blue Pill board you are using? Where did you buy it? Did you have to
replace its D+ resistor to make it work with USB? I am guessing it does not work with Arduino IDE,
does it?
The STM32F103C8 indeed is a BluePill, I bought it via eBay from the usual Chinese sellers. It is
cheap (something like 2.50 USD) and it can easily go over 1MHz, without problems. But my
(homemade) frequency generator produces different dutycycles up to 250kHz, above that (up to

How to Measure High Frequency and Duty Cycle, Simultaneously, Using a Microcontroller.: Page 8
10MHz) it is 50% only. Also the 74LS chips aren't the fastest, so I only tested it up to 500kHz.

Yes, on most BluePills the D+ resistor is the wrong value, on some I have replaced it with a
through-hole one (it's huge :-)). On this BluePill I haven't done that, in fact I removed the USB
connector, the 3.3V LDO, the power led and some more components because I don't need them
and I wanted to use it for very low current experiments. For even higher frequencies I use the
STM32F407VGT on a black circuit board, available for less than 10 USD, free shipping.

I do use the Arduino IDE for Arduino boards only. For STM32 I use Atollic's TrueStudio and
STM32CubeMX. I know that you can use the STM32F4 series with the Arduino IDE, not sure if it is
available for STM32F103.
Interesting! I have never seen the use of JK_Flipflops like this before. I'm going to give it a try.

How to Measure High Frequency and Duty Cycle, Simultaneously, Using a Microcontroller.: Page 9

S-ar putea să vă placă și