Introduction: Microcontroller Interface to Forrest Mims's Electrometer

About: If you wish to contact me, I can be reached at

My daughter wanted a way of measuring static for her science project. While scanning through an old copy of "Getting Started in Electronics" by Forrest M. Mims, III, I happened upon a suitable small circuit for an electrometer based on a JFET (p.106). We actually used a slightly modified version, shown in the second picture above, (which used a LED instead of resistors for some visual feedback) for her project experiments. However, the setup was a little delicate, so for her science show we decided to make something more robust and with a display that didn't involve reading a meter (she didn't share my fascination with analog meters).

A JFET is used because the (controlling) gate pin is essentially insulated from the other pins (inappropriately named drain and source), and so small charges on the gate pin (induced by static) can turn the JFET 'off' (it is 'on' by default).

A more elaborate design would follow the same basic idea, but use a JFET opamp as the input stage, and also increase the part count and power requirements. JFETs are amazingly sensitive devices.

For the display, we decided to use a small 10 bar LED strip which I got from Radio Shack aeons ago. I wanted to put the whole contraption in a small box which meant using small batteries. I settled on two CR2032 cells, which meant that I needed to be careful with power consumption, since with all 10 LEDS on the current would be at least 200mA. Since the CR2032's have a 225mAh capacity ( ) this would only yield about an hour of use. So I needed to strobe the LEDs. I also needed to read the JFET drain voltage (as a proxy for current), which meant an ADC. I had only ATtiny2313 controllers in my box, but unfortunately they don't have an ADC. However, they have an analog comparator, so by using a suitable RC circuit I was able to cobble together a rough ADC (the RC circuit/comparator combination 'converts' voltage into time, which we can easily measure).

Note that each CR2032 has an internal resistance of 10-40Ω (eg, see ), so the power supply effectively has 20-80Ω in series.

I had an old 4 oz. Coleman's Mustard Powder tin which looked big enough to hold the circuit and battery (barely, as it turned out).

The code is written in C, and is straightforward. Working with interrupts is often a bit delicate; in this case it took me a while to figure out that function calls were causing a huge delay in an interrupt service routine which was affecting the 'ADC' part of the code. Most of my coding time was spent figuring out the correct timer/interrupt setup. (However, I should point out that I have been coding for many years, and have much experience dealing with this sort of project.)

The total cost of parts for this project probably amounts to less than $10 or so. However, you need to be familiar with programming a microcontroller (the wonderful ATtiny2313). I use the avrdude/avr-gcc toolchain on Linux with a USBtinyISP programmer from . I used a programming cradle (see for example) to connect the programmer to the microcontroller. Since you at least need a programmer, it would be a bit misleading to characterize this as a $10 project!

One nice thing about 'one off' projects is that I can do things that would be sloppy design in a production environment; I can measure I_DSS for the JFET (which can vary quite a bit from JFET to JFET), and make some adjustments in software to account for component variations (including the ATtiny2313 on-chip clock, and voltage drop due to the high internal resistance of CR2032 cells). Another thing is to keep in mind that the ATtiny2313 costs all of about $3, so trial and error is a perfectly acceptable approach, blowing a few is not going to break the bank. Much of the analysis presented in this instructable is somewhat after the fact, which shows that simple back-of-the-envelope calculations are generally fine in this situation. It reminds me of a saying by a former Taoiseach of Ireland, Dr. Garret FitzGerald, who said "That's fine in practice, but will it work in theory?".

Another reality of this sort of project is that it is often driven by what you have in your component box and interest rather than any cool level-headed rational design process. For example, I have had a 10 segment LED display for years and never found a good use. So it absolutely had to be part of the design, even though I have an ample supply of cheap, high-efficiency, low current LEDS also sitting in my box!

The LED current is significant. The 5V I/O Pin Source current on p.196 can be used to extract a quadratic model (since we are operating in the so-called linear region of the driving MOSFET) of I_OH vs. V_OH (I_OH = 2*6*(-3.833*(V_OH-V_CC)-0.5*(V_OH-V_CC)**2) mA), and the LEDs can be modelled as 2V drop in series with the series combination of a current limiting resistor and the internal resistance from the batteries (taken to about 40Ω). A load-line analysis yields a LED current of 40mA if one LED is on, and 24mA if two LEDs are on (ie, a total of 48mA). Still, this yields a useful life of around 4.5 hours, which is ample for the science show.

Among other things, you will need a programmer for the ATtiny2313. Fast debugging was helped significantly by my prehistoric (but functional) 4 channel 300Mhz Tektronix scope. Soldering iron, solder, wire snips, wire stripper, solder sucker, wire of various sorts and a bread board for experiments all help too. A good tweezers and a multimeter are almost indispensable. I used magnet wire to wire the perfboard, it is easy to thread and when soldered the insulation disappears - very handy for low current applications.

I used Eagle to draw schematics, and Octave/Gnuplot to do some calculatons and plots.

The rest of the instructable describes the circuit, the hardware, the software and the construction.

Step 1: Circuit & Hardware

The electronic parts used in the static detector were:

1x MPF102 JFET ($1.29)
1x ATtiny2313 ($2.88)
1x 10 segment red LED bar graph display ($1.40)
2x coin cell holders (sewable SMD, $2.50)
2x CR2032 coin batteries ($1.00)
1x 20 pin DIP socket (for ATtiny2313)
1x 20 pin DIP wirewrap socket (longer pins so LEDs can be higher))
1x switch (SPST on-off rocker, $2.66)
1x 0.1uF capacitor
various resistors {10, 120, 330, 4.7K, 10K, 22K, 1M} ohm
2x terminal block connectors ($1.10)
1x ring connector to ground the mustard tin

The total of the known prices is less than $15.

The circuit has three parts; (1) the JFET and load, (2) the LEDs and current limiting resistor, and (3) the RC circuit used to jury-rig an approximate ADC. In the ensuing discussion, it may help to look at the circuit schematic.

Analyzing the circuits parts requires a little math. I have detailed the relevant calculations and discussions in an attachment below, in case you care.

The JFET part is basically from Mims, except that the 'ADC' replaces the ammeter, and I chose the load resistor after measuring I_DSS, so there was no need for a potentiometer. To measure I_DSS, just ground the gate and measure the current when driven by, say, a 6V source (just need to drive the JFET into saturation). My JFET had a I_DSS of about 9mA (actually I tried a few JFETs, and they all were 9mA, which seems a bit unusual, perhaps they are binned?). I chose a 330Ω load resistor, which gives a drain voltage range of about V_CC-3V to V_CC. With a 6V supply, this range is 3V-6V.

Purely out of interest, I measured drain current vs. gate voltage to see what sort of gate voltage would shut the JFET down. This shows a pinch-off V_P of about -4V. This gives some idea of the potential created on the gate pin by static. The plot is attached below.

I added a 1MΩ 'safety resistor' to the gate input, probably unnecessary, but reduces the chance of blowing the JFET.

Ideally, we would measure the drain current and use this as a measure of the static affecting the gate pin. This would typically involve either a Hall effect device, or a low value sensing resistor and an op-amp to compute the voltage difference (and Ohm's law, of course). However, this is starting to get unnecessarily complicated for the project at hand. A simpler method is to note that the drain current ranges from about 0-9mA, and choose a suitable load resistor (one end connected to the supply, and one to the JFET drain) that gives a workable voltage range for these currents. This way only one voltage reading is necessary, at the expense of being very sensitive to supply voltage (which changes).

I played with the 10 segment display for a while and even when on 100% of the time, it was fairly dim, which didn't bode well for my strobing idea to reduce current. When I strobed it, it (obviously) became even dimmer. I chose a 20% duty cycle, and replaced the current limiting resistor by 10Ω, and this was dim, but acceptable. So, I decided to strobe all LEDs on a 20% duty cycle, have at most 2 of the 10 on at any time, and connect all cathodes to a single 10Ω current limiting resistor. I tried this out and it worked fine, and then I spent a few hours justifying what I had just done. The detailed analysis is attached below, for those who care.

I had code from a previous project that used Timer1 to generate interrupts every 1mS, so I used this for the LED strobing. The software would ensure that no LED would remain on for more than 2mS in every 10mS cycle (ie. 20% duty).

One way of using the 10 segment display would be to display a 10 bit binary number representing the load resistor voltage. I tried this, but it was hard to read, so I decided to just go with displaying a range from 0 (all off) to 10 (all on). This looked good, and didn't require explanation to understand.

To measure the load resistor voltage, I needed some form of ADC. The ATtiny2313 has no ADC, but it has an analog comparator which can be used to implement a ramp ADC. One input to the comparator is the signal being measured, the other input is a ramp of known slope starting from 0V. By measuring the time for the comparator output to flip, the input voltage can be figured out. (In fact, it doesn't really need to be a ramp, any known increasing signal will do, a ramp is typically preferred because it offers equal sensitivity to the entire input range. In our case, this doesn't matter). For this design, a simple RC circuit is used to create an increasing signal. Ramp ADCs have a few disadvantages; (1) the conversion time taken varies with measured voltage, and (2) the measurement is affected by changes in V_OH (which depends on V_CC). In this design, the first is not really a problem as along as it doesn't interfere with the strobing (which could change the pin DC current), and the second is not too much of a problem (although showing this involves a bit more calculus), mainly because the ramp ADC implementation ends up (indirectly) measuring the load resistor voltage divided by the supply voltage (or rather, V_OH).

To avoid interfering too much with the LED strobing, I wanted the ADC conversion to happen in under 1mS. I decided to run the ATtiny2313 at 1Mhz, which gives me 1μS resolution on timing. I chose R=4.7KΩ, and C=0.1μF, which gives a 470μS time constant. This would, roughly, be the time taken to measure a voltage of (0.63)V_OH. To discharge the capacitor a little faster, I also connected a discharge resistor R_DIS to the capacitor, and chose R_DIS to discharge quickly (without exceeding specs.). The choice of R_DIS is detailed below. When charging the capacitor, the pin driving the 4.7KΩ resistor is driven high, while the pin driving R_DIS is tri-stated. When discharging, the pin driving the 4.7KΩ resistor is tri-stated, and the pin driving R_DIS is driven low. The capacitor effectively discharges in about 60μS (5 time constants). The tri-state effectively disconnects the relevant resistor from the circuit.

When the JFET is off, the load resistor voltage will be at V_CC. Since the 'ramp' is actually an exponential, it may never finish conversion in this case! To avoid this problem, the load resistor voltage is fed into a voltage divider (22K/32K) of suitably high impedance (32KΩ) so it doesn't interfere appreciably with the load resistor voltage. With a 6V supply the divided load resistor voltage ranges from about 2V to 4.2V, so the conversion will finish in less than 550μS. One of the attached graphs below shows the conversion time vs. the measured voltage for a 5V & 6V supply. A small calculation shows that for the 5V supply, the maximum time will be less than 600μS. Thus the total conversion time is less than 1mS.

I used a bread board to test the setup, particularly the LED strobing.

I used Eagle to draw the schematic, create a board, do the layout and autoroute. It does a good job, but 'thinks' that it is for a two layer PCB. In any case, it saves me having to do a lot of boring work. I used some perfboard for the components, and magnet wire to connect them together. Before actually soldering anything, I place the components on the perfboard just to make sure things will really fit. At this stage I decided that I would put the power switch on the mustard tin lid instead of the side.

I drilled holes for two standoffs (see the Assembly section) before attaching components to the perfboard. The idea was that the two standoffs and the probe insulator would support the perfboard in the mustard tin.

Step 2: Software

There are three main parts to the software; (1) the setup (timer1, the ports and comparator), (2) the LED strobing, and (3) performing the ADC conversion.

The ATtiny2313 fuses must be set appropriately to select the internal clock of 1Mhz. The following link is useful to simplify the slightly confusing reverse logic used for fuse programming. The fuse.txt file below shows the command I used to program the fuses.

One other thing is that the flash programming ports overlap with PORTB, so you may need to disconnect the LEDs while programming the ATtiny2313. The build instructions are in the file build.txt below. (Just as a sanity check, I print out the code sizes and the variable map.)

I used a multi-channel scope for debugging. It would have been difficult for me to find some of the 'bugs' otherwise. It took me a while to figure out that the LED strobing was interfering with the conversion. To debug this issue, which I suspected was related to the interrupts, I used the unused port of PORTD and set it at the start of the interrupt and unset it just before the end. The problem was that while the strobing code in the interrupt service routine was easy to read and understand, it took about 500μS to execute. I rewrote the code so that it had fewer lines (but more complicated and less understandable), and this became less of an issue. I also decided to disable the strobing interrupts during conversion.

The setup is straightforward, timer1 is used to trigger the strobing interrupt (1000 cycles at 1Mhz). The comparator is enabled to trigger a timer capture on a rising edge. All bits of PORTB and PORTD are initially tri-stated. The LED drives (6 bits on PORTB, 4 on PORTD) are enabled. The ports driving the charge and discharge resistors are set to high and low respectively. The capacitor is discharged, then the interrupts are enabled. This is followed by an infinite loop of conversions followed by displaying the result.

The LED strobing is conceptually simple, but complicated slightly by the fact the the bits are split across two ports. The strobing works in a 10mS cycle. In the first cycle, LED0 & LED1 are enabled, in the next cycle, LED1 & LED2 are enabled, and so on, until the last cycle in which LED9 & LED0 are enabled. The enable masks are stored in a pre-computed static array display_mask_B and display_mask_D, and the interrupt routine cycles through each of the 10 masks.

The ADC conversion works by disabling the timer1 interrupt, charging the capacitor (and recording the start time which is the timer1 value) until the comparator output is set. Then the capacitor is discharged for 5*R_DIS*C_CHR which is about 60μS. The time taken for the conversion is measured by the timer1 capture interrupt (triggered by a rising edge on the comparator output). The timer1 interrupt is enabled and the time difference computed. The computation is straightforward since the conversion takes less than 1mS. (Remember that the counter wraps around every 1000 ticks.)

Initially I tried calibrating the output by measuring and computing, but it started to get too complicated, so I decided to temporarily display the result using a debug_led_value routine (which displayed the value in 10-bit binary, hold the display for a second), and play with some static. This gave a (subjective) range of times from 136-351 ticks. I then wrote some branching code to map this range into a number between 0 and 10, and used this to display the bars. This worked satisfactorily. (I calibrated the device before assembly, as this involved reflashing the ATtiny2313.)

Step 3: Assembly

This was the most challenging part for me. As mentioned earlier, I drilled two holes for the 13/16" standoffs in the perfboard. I used a paper template of the perfboard to figure out where the holes had to be drilled in the mustard tin. I drilled a hole for the probe antenna. The tin is fairly thin and difficult (for me) to work with. I used the paper template to figure out where the LED display would go, and drilled a few holes and used wire snips to cut the tin away. This didn't go too well, so I ended up using a Dremel tool to finish the job (and remove jagged edges).

I used another paper template of the rocker switch to cut a hole in the lid, and used a utility knife to cut the plastic. Then I snapped the switch in place.

I soldered the battery holders and the switch together and attached them to the terminal blocks. I also used a ring connector to attach the tin to the circuit ground. I unfolded a paper clip to used as the probe and attached this to the appropriate terminal block. I threaded the straightened paper clip through an eraser which would serve as an insulator and a support. With the wirewrap socket, the LED display protruded through the tin, so this had to be inserted after the perfboard was installed. The perfboard was a much tighter fit than planned (because the terminal blocks were taller than expected), but a bit of squeezing and maneuvering did the trick.

Just as I was about to put the batteries inside, I realized that the coin cells positive terminals were highly likely to touch the tin (bad design), so I fixed this by wrapping the coin cells with insulating tape. The unit then worked as expected.

When operating the device (or Mims's original design, as well), some odd behavior can occur. The device gets into a state where all LEDs are on (indicating that the JFET is off), even though the source of static is removed. I am presuming that the probe has retained some charge. Anyway, the fix is to get a charged object, move it close to the probe and then remove the charged object very quickly. This turns the JFET back on again. The device is very sensitive.

The device wasn't quite a hit at the science show, partly because there were too many charged objects (people and stuff) nearby, but my daughter and her friends liked playing with it away from the show. But now she has some ideas for other mustard tin projects with LEDs.

LED Contest

Participated in the
LED Contest