The FabFish

An Electric Field Sensor/Prototype Kit


board layout

Beta Warning

Note that this hardware and firmware (and webpage) are still under development. By building and using the hardware and firmware in the beta phase, you are indicating your understanding that there may still be outstanding issues. Of course, any feedback is appreciated and will be used to improve the design and documentation.


The FabFish is yet another electric field sensor board in what's grown to be a large family of electric field sensors developed at the Media Lab. It is designed to be quickly manufacturable with a small desktop mill, and to be a building block for rapid prototyping of systems that need electric field sensing.

The hardware is an incremental revision to my TinyFish sensor boards. The primary improvements over the TinyFish 1.5 are:

The firmware incorporates the same hardware-driven, phase-locked transmit signal generation and synchronous demodulation that resulted in a significant SNR increase in the TinyFish 1.5 firmware, but has been rewritten to clean up and modularize the code for easy modification. The firmware is set up so that it works with no modification as a serial device, controlled by a PC, and is easily extensible to replace the serial communication loop with one's own application on the microcontroller itself. Measurements are made with a single function call and the result easily retrieved with another.

Schematic and Board Layout


Bill of Materials

The FabFish is designed to be buildable with commonly-available components, many from the standard fab lab inventory. The CPU is the ubiquitous ATmega168, and most of the passives are 1206, with a handful of 0603 parts (capacitors and inductors for power supply decoupling.)

The most exotic components are the main op amp, the inductors, and the tuning capacitors.

Identifier Description DigiKey Part Quantity Unit Total
C1-2, C5-6 0603 0.1 µF ceramic capacitor 478-1239-1-ND 4 $ 0.02 $ 0.08
C3-4 1206 22 pF ceramic capacitor 311-1154-1-ND 2 $ 0.12 $ 0.24
C7 1206 0.1 µF ceramic capacitor 399-4674-1-ND 1 $ 0.39 $ 0.39
C8-9 0603 80 pF ceramic capacitor¹ 478-4996-1-ND 2 $ 0.21 $ 0.42
C10-11 5-20 pF variable capacitor² 490-1993-1-ND 2 $ 1.05 $ 2.10
C12 0603 4.7 µF ceramic capacitor 478-5009-1-ND 1 $ 0.28 $ 0.28
C13 2312 15 µF tantalum capacitor 478-5805-1-ND 1 $ 0.50 $ 0.50
R1-2 1206 1.0 MΩ resistor³ 311-1.00MFRCT-ND 2 $ 0.08 $ 0.16
R3-4 1206 10 KΩ resistor 311-10.0KFRCT-ND 2 $ 0.08 $ 0.16
R5-8, R10 1206 100 KΩ resistor 311-100KFRCT-ND 5 $ 0.08 $ 0.41
R9, R11-12 1206 0 Ω resistor 311-0.0ERCT-ND 3 $ 0.08 $ 0.25
R13-15 1206 330 Ω resistor 311-330FRCT-ND 3 $ 0.08 $ 0.25
R16-17 1206 0 Ω resistor¹ 311-0.0ERCT-ND 2 $ 0.08 $ 0.16
L1-3 0603 10µH inductor⁴ 445-6389-1-ND 3 $ 0.11 $ 0.33
L4-5 10 mH shielded inductor¹ DN7562CT-ND 2 $ 2.55 $ 5.10
D1-2 1206 LED red 160-1167-1-ND 1 $ 0.38 $ 0.38
D3 1206 LED green 160-1169-1-ND 1 $ 0.50 $ 0.50
Y1 20 MHz ceramic resonator XC1109CT-ND 1 $ 0.57 $ 0.57
U1 10MHz quad low-voltage rail-to-rail JFET op amp⁵ MCP6024-I/SL-ND 1 $ 2.08 $ 2.08
U2 General-purpose dual low-voltage rail-to-rail op amp⁵ MCP6272-E/SN-ND 1 $ 0.74 $ 0.74
U3 TQFP ATmega168 microcontroller ATMEGA168A-AU-ND 1 $ 3.23 $ 3.23
U4 3.3V low dropout regulator ZXCL330E5CT-ND 1 $ 0.61 $ 0.61
P1-5 100mil right-angle breakaway SMD header⁶ S1113E-36-ND 1 $ 3.68 $ 3.68
ISP 50mil 2x3pin SMD male header⁶ S9012E-03-ND 1 $ 0.57 $ 0.57


  1. Choose these components to yield a resonant frequency of 156.25 kHz. R16 and R17 allow some resistance to be added to the tank circuit; see the note about transmit Q below.
  2. May be omitted if the Q of the transmit resonator is sufficiently low, but populating these is recommended.
  3. Adjust this resistor to set the current gain of the front end.
  4. Depending on how good your power supply is, the circuit may have better performance with L2 replaced with a solder jumper. (Definitely do this for USB power.)
  5. See notes below about op amp selection.
  6. See notes below about connectors.

Transmitter Q Factor

The transmit electrodes are driven by a resonant RLC tank circuit to generate large sinusoidal voltages. For maximum range, minimizing the resistance (using 0Ω 'resistors' for R16 and R17) yields maximum Q (the circuit will create very large voltages at the resonant frequency, but voltage falls off sharply with slight detuning.) In some cases, you may want to introduce a small amount of resistance to lower the Q of the tank circuit (the maximum voltage produced will be lower, but the circuit is more tolerant of not being exactly tuned.) This is desirable if you want to omit the variable tuning capacitors, or if you don't need as much voltage (if the electrodes are very large or very close.)

The Q of the circuit can be calculated as follows:

Q = (1/R) * sqrt(L/C)

Choosing op amps

You may substitute U1 with another SOIC-14 op amp, provided that it has reasonably high gain-bandwidth, can operate from a 3.3V single supply, and has JFET input stages (you want the input leakage current to be as low as possible; if you use an op amp with bipolar inputs, it will just end up measuring its own leakage current.)

U2 buffers the analog ground, and helps drive the shield on the receiver cables. It is not strictly necessary; if you're really trying to shave costs off of the board, you can omit it and jumper pins 2 and 3. Pretty much any op amp that's unity gain stable and can run from 3.3V should work here. Note that a dual package is used even though only one channel is used in the design.

Connecting to the board

The ISP connector follows the standard AVR ISP pinout, but uses a 50mil header instead of the standard 100mil one to save space on the board. The mating connector is DigiKey part number S9009E-03-ND. I use one of these and a section of 2x3 male pin header to make an adapter cable that I use to program all of my boards (once you build one, you'll stop using the giant 100mil headers on all of your boards.) Note that these are a little bit fragile, so it's worthwile to properly heatshrink your adapter cable. And order a few extra connectors!

The connectors to the electrodes are standard 100mil pin headers. They mate nicely with the Molex KK series connectors. You can use one two-pin housing for each electrode connection, or you can use a 5-pin housing and connect to both transmits or receives, with the middle pin unpopulated. Of course, you can solder directly to the pads, too, if you want. Or if you want to get fancy, you can populate the positions on the board with actual Molex KK headers and get the nice friction locks to hold your mating KKs in place.

The serial header is the standard pinout for an FTDI USB-to-serial cable.



Toolpath files are available here:

The path was generated from the PNG with the following command:

png_path fabfish.png fabfish.path 1.01 .395 -1 0.3

The board exactly fits on half of a 2x3 inch FR1 PCB. To set up the Modela, affix the PCB to the bed, making sure that the front of the board is square with the front of the bed (use the lines as a reference, or pull the bed off and use a small T-square.) Insert a 1/64 inch endmill as usual, and adjust the Z position so that the tool is just touching the board at Z=0. Then, use the rml_move command to move the tool so that it is exactly at the bottom left corner of the board (to within 0.5mm). Use these coordinates when you run path_rml to generate the path.

When the board is finished cutting, if you want to make another on the same board, re-run path_rml and add 25.4 to the Y value that you used before.

Cutting the board

Cutting the board is critical to separate the analog and digital ground planes. The notcher works well for this. Cut the board so that the left and right sides of the plane just above the ISP connector are not connected (but make sure not to break the trace going to the ISP connector!) If a little bit of copper is left connecting the two planes together, you can remove it with an exacto knife.

I recommend that you inspect the finished board under a microscope and verify that there are no copper filaments shorting adjacent traces.


I'm not posting gerber files until the design is somewhat more finalized. However, if you really want to have the board manufactured, contact me and I'll give you the files.


Assembly of the board is relatively straightforward. I recommend starting with the ICs, then the passives, then the edge connectors, and finally the ISP connector.

Since the board has no soldermask, be careful not to short traces under it when soldering the ISP connector. It may be necessary to insulate the traces under the connector with a little bit of Kapton (or other insulating) tape.

Since the analog front end is sensitive to very small currents, you should remove any flux residue on the board, as this might conduct very small currents. Do be careful not to let too much flux remover/flux residue run into the variable capacitors, however, as it can interfere with their correct operation.

Testing and Bringup

Before applying power to the board, test the following with an ohmmeter:

  1. There should be no shorts between VCC and ground.
  2. There should be no shorts between the analog and digital ground planes.
  3. There should be no shorts between AV+ and AV-.

Connect an FTDI USB-serial cable to the header on the bottom of the board. The black ground wire should be at the left side of the connector. Measure the following voltages with your voltmeter:

  1. VCC to ground (should be 5V, or close, depending on your USB port)
  2. AV+ to AGND (should be 1.6V)
  3. AV- to AGND (should be -1.6V)
  4. AGND to GND (should be 1.6V)
  5. AV+ to GND (should be 3.3V)

Load the firmware on the board (running make install in the source directory will do this; you might need to edit the Makefile to set your programmer type. The green D3 light should come on.


The firmware is kept in a publicly-accesible Mercurial repository. To clone the latest version of the firmware, execute:

hg clone

You can then later update to the latest version in the repository with hg pull -u.