OSH Park 4 layer stackup and impedance data

Here’s some data on the OSH Park 4 layer stackup:


Here’s the data as typed into Altium:



If you want a 50 ohm trace on the top layer and the second layer is ground (as it should be) then you want the trace width to be 13.45 thousands of an inch:


That’s kind of wide. Let’s see if we can make it smaller by using an edge coupled microstrip (coplanar waveguide):


Not really. The coplanar waveguide will give you a thinner trace width (W) than a microstrip of the same Z0 when the height (H) is large, like if using a double sided board of normal 62 mil thickness.

But using an edge coupled microstrip will provide better shielding. Make sure to use stitching vias from the edge ground to ground plane.

If you’re making 100 ohm differential pairs then use these values:




Table completed

I actually completed the table around March 2013 but I neglected to update my blog. Here are a couple pictures:

DSC_0003 DSC_0007I skipped a lot of steps. Leave a comment if you have any questions.


I just found a bunch of pictures of the leg building process, etc:

01-DSC_0001 02-DSC_0002 03-DSC_0003 04-DSC_0004 05-DSC_0005 06-DSC_0006 07-DSC_0007 08-DSC_0008 09-DSC_0009 10-DSC_0010 11-DSC_0011 12-DSC_0012 13-DSC_0013 14-DSC_0018 15-DSC_0019

GPS Preamplifier board

This is designed to amplify weak GPS signals at 1575.42 MHz.

It uses the inexpensive and easy to obtain Hittite HMC474SC70 amplifier chip which currently costs $3.16 at Digi-Key.

gpspreampAnd here’s a schematic:

gpspreampschematicSimple, eh?

The square spots are for an RF shield can (see parts list.) The gain of this assembly should be close to +15dB with a noise figure of 3.9dB. Thus this will make a terrible LNA and you should only use this with an integrated antenna-LNA such as this part from Digi-Key:

W4000G197Parts list:

Comment Pattern Quantity Components
+5v PADS_2 1 J1
10nF 25V 0603 SMD-0603 3 C3, C5, C7 CAP MLCC SMT
110R 5% 1206(3216) RESC1206(3216)_N 1 R1 110R 0.25W 5% 1206 (3216 Metric) SMD
1nF 50V 0603 SMD-0603 2 C8, C9 CAP MLCC SMT
1uF 6.3V 0603 SMD-0603 4 C1, C2, C4, C6 CAP MLCC SMT
Gain block 15dB SC70-6 1 IC1 HMC474SC70
47nH inductor SMD-0402 4 L1, L2, L3, L4 LQW15AN47NH00D
RF shield frame BMIS-201-F 1 SHLD1 RF shield frame/cover F/C
RF shield frame BMIS-201-C 1 SHLD1 RF shield frame/cover F/C
SMA SMA_LINX 2 J2, J3 Vertical SMA through hole connector


It works! Performance is as predicted. I haven’t been able to test with the actual GPS antenna yet because GPS signal level is in the noise. Interestingly (to me) the amplifier is very wide-band. With a small piece of wire as an antenna, I am able to watch OFDM from the many WiFi devices, on the spectrum analyzer at ~2.4 GHz.

Future Goals:

This board is part of my learning and experimentation with RF techniques. I am new to RF design but not embedded systems. My goal is to eventually build a GPS receiver.2014-12-18 08.34.05


You can buy your own PCBs from OSHPark as I’ve shared this design.

Revised photodiode amplifier

I designed a new photodiode amplifier:
photodiode_amp2And an associated printed circuit board:

Photodiode amplifier PCBThe printed circuit board is available to purchase from OSH Park if you like.

I will update this post after I receive the PCB and test the circuit.


photodiode_amp_psThe first part of the schematic is the power supply. VIN is +15V.
The L78L12 supplies regulated +12V to bias the photodiode. The RLC lumped element filter that follows ensures a low noise voltage source for the photodiode bias. The filter response is (simulated) as follows:

photodiode_amp_psfilterThe filter quickly drops below the noise floor above a couple MHz. This is theoretical. Actual performance won’t be quite as nice.

The 47 Ohm resistors thrown into the filter will not measurably affect the photodiode response. The DC power will be no more than a few milliwatts maximum.

The AC power will probably be below the microwatt level, I’ll guess around -40dBm. Again, I’ll update this when I have some results.

photodiode_amp_RFThe next section I’ll talk about is the photodiode itself and the amplifier.
The photodiode is an OPF432. It comes in a handy package that has an ST style fiber optic connector so you don’t have to have any bulky external mechanical parts to couple light into the diode.

OPF432The photodiode is reverse biased at +12V. According to the datasheet this should provide a rise time of about 8 microseconds. I believe this refers to the time constant. The datasheet claims this part can be used up to 100 MHz which is a period of 10ns.

The signal rises in half the period which is 5ns. If the datasheet rise time is accurate at 8 microseconds, I believe the AC output amplitude (peak) of a 100 MHz modulation will be:

Current = (5ns/8us)*50A/W = .03125 A/W

A/W is amps per watt of input power. In my application the input amplitude may be approximately 10uW. Multiplying:

31.25mA/W * 10uW = 312.5nW

This sounds very low, but let’s convert to units of dBm (decibel milliwatts):

P = 10*log10(312.5nW)+30 = -35 dBm

The GALI-74 is an MMIC that conveniently provides a 50-ohm matched input and output with +25dB of gain from low frequencies up to well above the design goal of 100 MHz.

The output will be at about -10 dBm which corresponds to an amplitude of approximately 70 millivolts into a 50 ohm load.


The final section of the schematic provides a low pass filtered output which indicates the DC amplitude of the incoming light.


ESP8266 WiFi module

Recently I received some really cheap WiFi modules.

The Wi07C isn’t much more than a little rectangular board with a WiFi chip, flash chip, and copper trace antenna.



The little board on the left is the ESP8266 board. It’s wired to a CP2102 UART to USB bridge and powered by a 5V – 3.3V buck converter I had laying around.

I bought the ESP8266 board from a store in Korea called Electrodragon

Pinout and AT command reference here

I made 5 connections for this demonstration:
VDD to +3.3v
RX to TX on CP2102
TX to RX on CP2102
RST to +3.3v

On my computer I ran a perl script that listens for connections on port 8001 and simply spits out data that it receives. If it receives the text “PING?” then it responds with “OK”

So I connected to the CP2102 UART bridge using Realterm. The baud rate is 57,600. The line endings are CR but CR+LF will work fine.

I sent the following commands to the module to

1. Connect to my WiFi AP
2. Establish a TCP/IP connection
3. Send data
4. Disconnect


Here’s a screen shot of what was echoed back to me on Realterm:


So I actually sent the PING twice. The last character after PING doesn’t matter in my perl script. You can see the second time I sent 7 characters. PING is 4. There’s a space you can’t see, and then CR+LF for a total of 7. The +IPD,3:OK indicates that the host (the perl script) returned 3 characters: “OK” and then a CR character.

I’m impressed that a $4.50 WiFi module does anything at all, but it actually worked without much trouble so I’m very impressed.

I then ran a command that the module didn’t like, and it’s only responding with “busy now …” to any command I send it. I’ll have to toggle the RST line or power in order to reset the device. An acceptable caveat or will this prove to be a persistent problem?

Here’s the perl script I used:



use IO::Socket::INET;

# auto-flush on socket
$| = 1;

# creating a listening socket
my $socket = new IO::Socket::INET (
LocalHost => '',
LocalPort => '8001',
Proto => 'tcp',
Listen => 5,
Reuse => 1
die "cannot create socket $!\n" unless $socket;
print "server waiting for client connection on port 8001\n";

# waiting for a new client connection
my $client_socket = $socket->accept();

# get information about a newly connected client
my $client_address = $client_socket->peerhost();
my $client_port = $client_socket->peerport();
print "connection from $client_address:$client_port\n";

# read up to 1024 characters from the connected client
my $data = "";
$client_socket->recv($data, 1024);
print "received data: $data\n";

print $data;
# write response data to the connected client

# read up to 1024 characters from the connected client
my $data = "";
$client_socket->recv($data, 1024);
print "received data: $data\n";

if($data =~ m/PING.*/){
$data = "OK\n";
} else {
goto shdn;
# write response data to the connected client
print $data;

# close
shutdown($client_socket, 1);




Capacitor impedance

Ever since I began designing circuits, I’ve read about bypass capacitor usage.

Engineers make broad statements about what you obviously have to do. Disagreeing with this advice automatically makes you a neophyte.

Common phraseology of bypass capacitor lore includes:
– You must use a mixture of low and high value capacitors to filter low and high frequency transients.
– You must use a tantalum bulk capacitor
– Sprinkling 1uF or 100nF caps around a board is stupid
and I’ve not made this one up:
– If you don’t know how to properly design capacitor bypassing, you should not be an EE.
[Of course, by “proper” they mean follow their advice]

I’ve been told by other reputable sources that since good MLCC [multi-layer ceramic capacitors] of high value and good electrolyte are now available, that most of these rules are exaggerated as yet another way for some engineers to claim superiority over others.

I decided to perform a few simple measurements to help me figure out for myself what I need to do when designing a circuit with bypass capacitors. Feel free to post below and offer advice as to how I’m wrong and/or what I should do with my graphs.

Test setup:
I have a simple “DG8SAQ” Vector Network Analyzer that I bought from SDR-Kits. It’s a reasonably good value and covers the range of 1kHz to 1.3 GHz. Without any fancy impedance converters, I decided that using this 50-ohm system to measure capacitor impedance would not be an unreasonable analog to what is happening when a capacitor is used for bypassing.

Bypassing for high speed digital systems is demanding. Edge slew rates can easily reach into the GHz range for FPGA designs. Even common LVCMOS digital logic can be extremely demanding – a recent comparator I used (MAX962) will drive it’s output high/low in 2.3ns (specified at 5v. It will be somewhat slower at 3.3V)

What I decided to do is solder a couple SMA connectors adjacent to each other, as in the following picture:
2014-05-27 14.23.57

I calibrated VNA and soldered a few surface mount capacitors into the open space. I used the following values:
1 nF
10 nF
100 nF
1 uF

From basic theory we know that the impedance of a capacitor is, as written in Laplace domain:

s = j*W [complex frequency]
C = capacitance value in Farads

In reality, capacitors have ESR and ESL. ESR is equivalent series resistance, and ESL is equivalent series inductance.
Alternating current by definition makes the impedance of a capacitor change.

My measurement system is not perfect for at least one reason; the ESR of a capacitor is usually << 1 ohm. My VNA is a 50 ohm system. I cannot effectively measure the ESR with this system. These plots will reflect the ESL, which I can measure.

Firstly I measured a 1nF capacitor. This plot is the magnitude of the signal that goes through the capacitor. This is called “S21″
I measured from 10kHz to 100 MHz because this seems to be a range most people would be interested in:

[click image for larger version]
1nf_cap_impedanceNext I tested a 10nF capacitor of the same size and type:

10nf_cap_impedanceLooks pretty nice to me.

Now for the 100nF cap:

I continued on with a 1uF capacitor. The plot is quite boring:

1uf_cap_impedanceIf you’ll notice: these last two plots went all the way up to 300 MHz. I thought there must be something interesting going on at some point. Not really.

My conclusions are based on the measurements that I’ve done. Obviously I have not included PCB parasitics in my test setup.
My conclusion is that for point-of-load bypass capacitors, the actual value of the capacitor makes little difference. I would not hesitate to use 100nF MLC-capacitors all over my PCB. Ideally the capacitors are placed as close to the power pins of the integrated circuits as possible, in order to make the current loops as small as possible.

Bypassing requirements for real circuits are very complicated. If you just have a fundamental sine wave current, you just pick one capacitor and be done with it.

I believe what I’ve shown is that the Fourier components of your load current that exceed about 1 MHz are easily handled by 100nF MLC capacitors, and that your lower frequency bypassing can be handled by a bulk capacitor that is located elsewhere on the board. Of course this depends on the inductance of your PCB traces.

Your system probably has intermittent loads switching on and off, or perhaps you’re building a switching power supply. The best bypassing setup would be an ideal capacitor of arbitrarily large capacitance value. This would theoretically cover your Fourier components from a few Hertz up to hundreds of MHz. Recently I’ve been using MLCC as large as 100uF with the X5R rated dielectric (never use Y5V!) I believe these new enormous MLCC are nearly ideal capacitors. They are expensive but I highly recommend them, especially if your alternative is a tantalum capacitor.

Thoughts on RF spectrum analyzers


Note: I’m contemplating designing a spectrum analyzer. The following are a compilation of my own notes that I’m making public. They might not make a lot of sense as a coherent treatise but take the pieces for what they are.

The classical way of performing RF spectrum analysis is to mix the input with a local oscillator (FLO1) that ramps between two higher frequencies, producing IF1.

IF1 is sent through a narrow band filter which leaves you with a narrow piece of the input spectrum that has been shifted up. The ramping action gives you a sliding window of the input spectrum, shifted up to the center frequency of the narrow bandpass filter.

Stepping back, remember that the IF1 frequency is the result of nonlinear mixing of the input with the local oscillator.
Let’s make some assumptions:

– the input (Fin) is any signal between zero and 1000 MHz.
– the local oscillator (FLO1) ramps between 1050 and 2050 MHz
– the narrow bandpass filter (FBP) is 1050 MHz

Mixing the local oscillator and the input with a non-ideal mixer gives you:

IF1 = N*input +- M*LO

The strongest output spectra will be where N=1 and M=1. This gives you spectra centered at:

(a) Fin + FLO1
(b) Fin – FLO1

Since FLO1 is always greater than Fin, we get a nice strong first image (a) between 1050 and 2050 MHz.
The first negative image (b) is wrapped into the range of 0 to 1050 MHz. Subsequent energies are present at higher orders, however their amplitude is orders of magnitude lower than the main images.

After mixing, IF1 is filtered using a high-Q filter. Q, of course, is a measure of how wide the pass-band is.
Q = Fc/Fbw where Fbw is the -3dB bandwidth.

Common hobbyist spectrum analyzers[1][2] use cavity or helical filters.

A cavity filter has radiative elements (I’ll liberally call antennae) in a conductive can along with a resonator whose length can be changed. They can and often contain multiple cavities

Here’s a paper from M/A COM on cavity and helical filter design.


[1] Scotty’s Modularized Spectrum Analyzer
[2] Andrew Holme – Homebrew spectrum analyser

HF/VHF photodiode amplifier


Recently at work I was tasked with determining the frequency modulation of a laser beam. I designed and tested the above circuit in a couple hours.

I tested the circuit first with no photodiode in place using my DG8SAQ vector network analyzer — a very low cost network analyzer based on the highly respected (by me) AD9852 DDS chip.

The circuit showed >+20dB gain from about 4 MHz to the cutoff frequency of the RLP-137. Hooray for small victories!

For the photodiode, I had no choice because I just had one laying around here that I could find the part number for: a Melles Griot 13DSI001. This particular part has a responsivity of 0.45 Amps/Watt at 830nm, breakdown voltage of 60, and 10pF capacitance.

A photodiode is typically reverse biased as you see above, with a positive voltage on the cathode. In my case I don’t care very much about what voltage I’m using as long as I do not exceed the breakdown voltage (more about that coming up.)

As light becomes incident on the diode junction, carriers are created that allow current to flow from the high potential to the low potential. This holds true for high frequencies; a high frequency alternating current is allowed through the device.

When a current source is terminated into a resistor we get a voltage source having an impedance of the resistor value. The photodiode is terminated into a 50 ohm resistor, hence we have a fairly decent 50 ohm source that is converting light modulation into RF of a convenient impedance. The maximum frequency (as I understand) is limited by the 10pF intrinsic capacitance of D1, combined with the load resistance, R3. This gives a cutoff frequency of 1/(2*Pi*RC) of about 300 MHz. I may not have needed the lowpass filter (RLP-137), however with my shoddy perf-board construction I was worried about the GALI-74 potentially oscillating in the GHz range.

The 1k resistor R1 is to limit the maximum current that can pass through the photodiode. Combined with C3, this provides filtering from feedback or noise that could come through VCC.

I’d be happy to see your comments below if you have corrections or advice.

MMIC photodiode amplifier

MMIC photodiode amplifier

Setting up NFS client on Beaglebone black

Really short HOWTO here. I want to share files from my desktop running Ubuntu, to my Beaglebone Black, which is running Angstrom Linux. Here’s how I did it:

  1. Install nfs-server on the Ubuntu machine
# apt-get install nfs-kernel-server

2. Edit /etc/exports, adding this line:


3. Create the directory on the server side (as normal user)

$ mkdir /home/martin/beaglebone_nfs

4. Install nfs-utils-client on Beaglebone (Angstrom) side

root@beaglebone:~# opkg update
root@beaglebone:~# opkg install nfs-utils-client

5. Re[start] the NFS server on the Ubuntu side

# service nfs-kernel-server restart

6. Mount your NFS share on the Beaglebone side

root@beaglebone:~# mount -onolock -t nfs /mnt

7. And to make it mount every time you reboot, add a line to /etc/fstab: /mnt nfs defaults,nolock 0 0

8. Unmount and remount from fstab to ensure that you got the fstab line correct (without rebooting)

# umount /mnt
# mount -a
# df
Filesystem                                1K-blocks     Used Available Use% Mounted on
rootfs                                      1738184  1175444    472776  72% /
/dev/root                                   1738184  1175444    472776  72% /
devtmpfs                                     255280        0    255280   0% /dev
tmpfs                                        255408        0    255408   0% /dev/shm
tmpfs                                        255408      220    255188   1% /run
tmpfs                                        255408        0    255408   0% /sys/fs/cgroup
tmpfs                                        255408        4    255404   1% /tmp  22145024 15797248   5199872  76% /mnt

And there you have it.