I am currently working on a project, which requires me to measure the very low currents (approximately in the range of 100 pA to 10 uA) from an electrochemical sensor.

The sensor is kind of a new approach and it is still in development at the university I go to, therefore the currents are so low.

My task is to implement a read-out circuit based on a microcontroller for the sensor by using impedance spectroscopy. That's why I need an transimpedance amplifier (TIA.)

I searched the web and university library yesterday, but I couldn't really find much information for TIAs in this current range. Of course I know that I will probably have various problems with noise, parasitic capacitances, oscillating and what not, but it doesn't have to be perfect, I just need some help to get an idea how to even approach this problem.


  1. Wide range of input currents
  2. Very low current

Solutions for Problem 1
I think the best solution here is to use multiple resistors like this, with making the selection of the gain resistors either possible by setting pin-jumper beforehand manually or make it controllable by the microcontroller. Although I think this setup can also have some disadvantages, because I imagine it weill further introduce parasitic capacitances which can lead to oscillation of the TIA if I understood correctly, but it's currently my only idea.

enter image description here

Solutions for Problem 2

  • Multi-stage amplifier with something like a current pre-amplification so that a normal TIA can handle it, but I have no experience with something like that. I could only find some vague circuits like this one and that one, but before I dive into analysing such complex circuits I wanted the get some opinions with more expertise.
  • Operational amplifier with very low input offset current like the LMP7721, which I got from this thread. Problems here are that I would need a precise resistor in the neighborhood of 10 GOhm (which is ridiculous, I would probably get a lower resistance if I put no resistor on the PCB) and the op-amp shows already while simulating with near ideal values some problems like shown below

The used values I got from an example calculation on the LMP7721 product website. The problem is if I lower the value for C1, the output starts to oscillate and if I increase the value, the phase shift between input-current and output-voltage will become bigger, which is pretty bad for impedance spectroscopy. Also, the frequency influences the phase shift and stability, too.

  • Integrated solutions from various chip manufacturers, but the highest gain I could find an such a chip was around 5*10^5.

I expect no complete solution to my problems, just a nudge or point in the right direction or some ideas I haven't thought about yet.

For clarification, because I am not sure if I explained it understandably: The currents I have to measure are dependent on the type of sensor used. I feed the sensor a sine wave with an amplitude of 10mV with no offset voltage. The different sensors have impedances ranging from |Z| = 10^3 to 10^8 Ohms, but the most interesting part for us (because most sensors fall into this category) is between 10^5 and 10^8. So as the output from the sensors I get back a current sine wave with amplitudes of 100 pA to 100 nA, depending on the used sensor type.

I am, therefore, particulary interested in, for example, measuring a current between 0 and 100 pA and not between 100 pA and 100 nA, so my resolution should be higher than 100 pA.

I am sorry if I caused confusion, but I don't have to measure currents ranging from 100 pA to 100 nA in one measurement. For a specific sensor I have to be able to measure between 0 and 100 pA (-100 pA respectively) correctly and for the next sensor I may have to be able to measure a range between 0 and 100 nA.

Some key data points:

  • Power supply: 5V over USB, converted into +/- 3.3V on board
  • Microcontroller in use: MSP430FR2355 with 24 MHz
  • Input signal: 10 mV amplitude sine wave with a frequency between 1 Hz and 10 kHz
  • Output signal: 100 pA to 100 nA amplitude sine wave
  • Target: Convert the current sine wave (the amplitude of which does not change during the measurement) into a voltage signal so that I am able to read it out with an ADC.

I will not be doing any complex calculations on the MSP430. This chip is only for signal generation, signal sampling and communication with a PC. Maybe I will try to implement the signal averaging on the microcontroller, otherwise I will send the raw ADC data to the PC and do the calculations there.

  • 1
    \$\begingroup\$ Note that Vinput (Vin differential) is limited to +/-0.3V around Vcm. \$\endgroup\$
    – Antonio51
    Commented Nov 11, 2021 at 15:02
  • 1
    \$\begingroup\$ Problems here are that I would need a precise resistor in the neighborhood of 10GOhm (which is ridiculous, I would probably get a lower resistance if I put no resistor on the PCB) - think again. \$\endgroup\$
    – Andy aka
    Commented Nov 11, 2021 at 15:09
  • 3
    \$\begingroup\$ Your feedback resistor is too large, you don't want to make the smallest current saturate your ADC, just to get it above your noise floor. pA (millions of photons) to uA (trillions of photons) currents are commonly measured by photodiode transimpedance amplifiers. An electro-optics or photodiodes text would probably have lots of good circuits your could use for this measurement range. \$\endgroup\$ Commented Nov 11, 2021 at 16:49
  • 1
    \$\begingroup\$ Have you had a look at the AD5940 / ADUCM355 analog front-ends? \$\endgroup\$ Commented Nov 11, 2021 at 22:44
  • 1
    \$\begingroup\$ As far as switching gain resistors is concerned...Kelvin switching: analog.com/ru/analog-dialogue/articles/… \$\endgroup\$
    – DKNguyen
    Commented Nov 12, 2021 at 2:06

7 Answers 7


I've built a few of these for the instruments at my current job. Here are a couple things I picked up along the way:

Don't go straight to a multi-stage amplifier. You are better off if you can get the gain you need in one element. If you do, put as much gain in the first stage as possible.

Speaking of gain...try to get away with a 1 GΩ feedback resistor and no capacitor. Use high quality resistors, and don't just believe vendor information. We had to test quite a few before we found ones quiet enough. Going over 1 GΩ is going to lead to all sorts of trouble. That should be enough for you to get your signal into a decent ADC. You could go to 10 GΩ if you are careful with your layout/wiring.

I see you have identified the need for a very low input bias current opamp. The one you have is a bit extreme and may be kind of squirrely. This may be why you need that feedback cap. I've had good luck with the AD549 in this situation.

Keep everything clean and physically isolated. Don't let the feedback resistor touch the PCB, have it stick up a bit on its leads. At these levels fingerprints and grime can really ruin your day.

Good PCB layout is a must, use guard rings and ground planes.

  • \$\begingroup\$ Thank you very much for your input and advice. Concerning the LMP7721, I too thought it's kinda to good to be true. It is probably more like a marketing thing under special conditions or a theoretical value, considering the chip you suggested costs 10+ times as much and despite that has still a input bias current which is a multiple of the bias current of the LMP7721. \$\endgroup\$
    – Rata
    Commented Nov 11, 2021 at 16:32
  • \$\begingroup\$ You get what you pay for. The input bias current is low enough for your needs, and being limited to +/- 5 V on a TIA trying to measure very small currents is a problem. If this is for a high volume product, fair enough, otherwise, how much pain are you willing to go through to save a few bucks? What you get for the money is +/- 15V rails and a more stable amp. \$\endgroup\$ Commented Nov 11, 2021 at 16:38
  • \$\begingroup\$ "try to get away with a 1 GΩ feedback resistor and no capacitor" Why save a sub 1 cent feedback cap ? I would say any feedback resistor > Megaohms is sure to oscillate with a halfway modern opamp. Let alone Gigaohm. Just throw in that 10 pF cap anyway. It never hurts. \$\endgroup\$
    – tobalt
    Commented Nov 11, 2021 at 16:51
  • \$\begingroup\$ Don't get me wrong, I appreciate your suggestion and get where you are coming from. But at the end of the day, it is not my decision which chips are getting bought, because currently I do this project as my bachelor thesis and I don't know how open my supervisor will be to the idea spending this much money on an idea without at least a simulation or other proof-of-concept :D. Another topic is the supply voltage: You said in your comment, that +/- 15V would be a lot better, but we currently just have +/- 3.3V and 5V on the board. Do you think we will be able to implement it with those voltages? \$\endgroup\$
    – Rata
    Commented Nov 11, 2021 at 16:57
  • \$\begingroup\$ Agreed, a 10 pF cap wouldn't be the end of the world. \$\endgroup\$ Commented Nov 11, 2021 at 16:57

Don't overthink it. You are looking only at 5 orders of magnitude dynamic range (1e-10 .. 1e-5 A). Also the lowest currents of 100 pA is not so challenging.

So for the sake of simplicity I recommend a single stage, fixed gain, TIA. Use something with a JFET input and pick the feedback resistor such that 10µA maxes out your output voltage range. Your 10G is way over the top for the current your trying to measure. E.g. for a 5V reference, your feedback resistor could be 500k, so that 10 µA maxes out your dynamic range.

Run that into a standard 24 bit ADC and you are done.

I advice against CMOS opamps for precision tasks because of their considerably low frequency noise. If you really do need rail-to-rail output, then consider CMOS, but often there are ways around it.

  • \$\begingroup\$ Well i think your first sentence is pretty spot on. In the last two days looking for a solution i just found more possible problems. Anyway, i am not sure if you misunderstood my post or I misunderstand your comment, but I don't have this range in a single measurement. I will clarify that in my post and add some key data. My problem is that I currently just have a 12bit ADC on the uC I "should" use. "Should" in the sense of "if there is no other way we can get an external on, otherwise try to use the existing one". \$\endgroup\$
    – Rata
    Commented Nov 11, 2021 at 17:20
  • \$\begingroup\$ In the case where you need discrimination down to maybe pA. Make maybe two different switchable FB resistors, 10M is enough for the smaller range. @Rata pay special attention to switch leakage and capacitance. Even stray capacitance if you are trying to measure AC. it will be tricky at > Megaohm source impedance \$\endgroup\$
    – tobalt
    Commented Nov 11, 2021 at 18:00
  • \$\begingroup\$ @Rata using a 12 bit ADC will require larger resistors and better switches. In the end using an extra 24 bit ADC will be simpler than the trouble with ultra high R and switches. \$\endgroup\$
    – tobalt
    Commented Nov 11, 2021 at 18:02
  • \$\begingroup\$ That's exaclty what I am afraid of and what I mentioned in the segment "Solution for Problem 1". I am not sure how severe it will be, but considering that I am in the fF/pF range for feedback resistors I can imagine that everything down to a switch can break my legs, metaphorically speaking. But I guess I have no other way of finding out then trying with all the suggestions and advices I have received in mind :). \$\endgroup\$
    – Rata
    Commented Nov 11, 2021 at 18:17
  • \$\begingroup\$ @Rata in this case I suggest you build the circuit with a single 1MOhm||10pF feedback and see how far you get with the 12 bit ADC. Get a feeling for it, and this try will be cheap. Also consider your choice for AC. are you using shielded cable? They have about 100pF/m. calculate the impedance of this stray capacitance and compare to your 100MOhm DUT. You might be surprised. \$\endgroup\$
    – tobalt
    Commented Nov 11, 2021 at 18:28

I've spent a few years building TIA in the pA range with 1kHz bandwidth. One thing to note is that simulations break down at these range of values. You have to test everything a thousand times. Simulations will point towards an answer, but you have to build it.

We used the LTC6268 (not the -10 version) as the main stage - I then had LPF, offset compensation and differential drivers after that. But the main stage used a 100M feedback resistor with very careful layout.

At one stage I was ordering custom 1G resistors in 1002 package (long and thin) with single-sided terminals for wire-bonding. Here's more info on the single-sided resistors. Having 3 sides increased parasitic capacitance. I measured 220fF vs 18fF for standard 1206 1G resistor vs single-sided 1002 1G resistor, which helped increase bandwidth.

The layout has to be very carefully considered. We were measuring a 2mV offset at the output of the 1st stage and we couldn't work out why. We traced it back to that the LTC6268 was internally oscillating at around 1.5GHz due to sub-par grounding. The output wasn't oscillating at all, just internally. We found this by using an E-Field probe. Since the LTC6268 comes in 2 flavours, a 500MHz and a 4GHz, the difference on the die is of a compensation network on the 500MHz that will help with stability at the expense of bandwidth - this means that the opamp internally still has the ability to oscillate above frequencies that it can output.

What I'm saying with this is that strange things happen at such low currents and to be very careful for layouts. The LTC6268 datasheet has some excellent tips on layout. The ADA4530-1 datasheet also has that, plus a guide on how to properly clean the board after assembly. I recommend reading through both anyway.

  • 1
    \$\begingroup\$ Thanks for the chip suggestion and in particular the advice and sources regarding the layout of the PCB. I already got some infos, but it's for sure good to have them again as a coherent text. \$\endgroup\$
    – Rata
    Commented Nov 12, 2021 at 10:36

OK, so you want to measure the impedance of your sensor in a range between 1Hz and 10kHz. From the numbers (10mV, 100p1...100nA) it is between 100kOhm and 100MOhm.

On the data acquisition side, the simplest solution would be to use a 24-bit ADC, so you have enough dynamic range to avoid range switching entirely. If you also want to measure the phase of your impedance accurately, then you'll need a high enough sample rate that the 10kHz sinewave doesn't look like a mess. The DAC that generates the test signal should also have a high enough sample rate to make a clean sine wave. The CPU should also have enough power to process the data.

If you acquire enough samples, then you can also use averaging to reduce noise. Basically, if you acquire a few cycles of sinewave, and multiply this with \$ e^{j \omega t} \$ then average the result, then you can extract phase and magnitude directly. By using averaging, you can extract signal even if it is buried in noise.

If your sensor picks up some ambient 50/60Hz fields, then this method will get rid of them: since it detects the amplitude and phase only at the frequency of interest, it will reject noise and interference at other frequencies. If you simply measure voltage at the transimpedance output, it will not be the case, you will get a lot more noise.

You can also use a log sweep, which is faster.

I got nanoamps resolution with a soundcard, and the current sense resistor was just a few tens of ohms. So the voltage being measured was really tiny, it went through an instrumentation amplifier, then averaged over a bunch of periods. The nice thing about this method is, it gives you a time versus resolution/noise tradeoff. If you find you need lower noise and higher resolution, just use a longer acquisition time.

This would be quite difficult to do with a MSP430, but it is very easy with audio gear. Audio ADC/DAC chips will do the oversampling automatically. In fact, you could use a PC or Raspberry Pi soundcard as data acquisition hardware. Most are AC coupled, so you would need to calibrate out low frequency rolloff or shunt some capacitors, but that's not a problem. Also you probably won't need to code anything, since there are already lots of PC software for impedance analysis... but if you do want to code it yourself, it's easy to do with python.

So the problem is how to turn this tiny current into a voltage suitable for a soundcard input.

Since you're only using AC, the input offset current of your opamp only matters if it's large enough to clip the output. However, your source and feedback impedances are very high, so you should really pay attention to the input noise current of the opamp and its 1/f corner. For example LT1793 has pretty low input current noise.

Note the simulation trace in the question shows the opamp is clipping. If you use a single supply, then its input common mode and output voltage range need to include ground.

It would probably be easier to use positive and negative supplies, to avoid clipping the opamp at zero input current if you get a specimen with an offset voltage that goes in the wrong direction. Also if you use AC current to measure your impedance, then it is much easier to use split supplies for the opamp. Otherwise you'll have to AC-couple with a capacitor to a reference voltage somewhere around midsupply, and then think about the cap's leakage current, etc.

The other answers provide enough info about how to do the TIA part, so I won't elaborate.

Edit: DSP stuff

To plot modulus and phase of impedance vs frequency, you can use two methods:

This is the classic test, it sweeps the entire frequency range of interest. Detailed explanations and math are in the link, it's about 1-2 pages of python code. Since it requires FFT of the entire waveform, it has to fit in memory, so this isn't possible with a microcontroller. It is the fastest method if you are interested in the whole range of frequencies.

  • Run multiple single-frequency tests, stepping frequency

This is simpler. If you're only interested in a few frequency points, then this is a good option. It can have lower noise than the swept sine if it spends more time averaging one frequency, but of course if you're interested in the full frequency range, it will be much slower since each frequency has to be measured independently, and that includes a bit of settling time after stepping to the next frequency.

It works like this:

Generate sinewave \$ Ao sin(\omega t) \$ and play it with DAC

Record measurement on device under test, it'll also be a sinewave with different amplitude and phase shift. Say the recorded data is \$ Ar sin(\omega t + \phi) \$ with Ar=recorded amplitude and \$ \phi \$ phase shift relative to the original sinewave.

So you compute \$ e^{j \omega t} = cos \omega t + j sin \omega t\$, multiply that with the received signal, and average the result over an integer number of sine periods. The sine period doesn't have to be an integer number of samples, but the averaging should be over an integer number of periods.

Multiplying these two and averaging is just like calculating the discrete time integral of the product of recorded signal with \$ e^{j \omega t} \$. If you write down the integral and solve it, you'll notice the result is a complex number whose amplitude is Ar and phase is \$ \phi \$.

Or maybe it's \$ -\phi \$, I don't remember, but you get the idea.

That's basically how a RF detector works, it multiplies the incoming wave with sin and cos, then averages.

So you get a complex number \$ A(f) \$ that encodes amplitude and phase for each frequency. The swept sine also gives results in the form of complex numbers, so from now on, the calibration method is the same. You have to keep the result as complex number, because that will be useful.

In order to calibrate it, you have to focus on the fact that what you want to measure is the difference between the electrochemical sensor working in the chemical solution, and an identical sensor that is not dipped in the solution. Or maybe it's something else, that's for you to decide, but the point of calibration is to remove all the stuff you don't want to be part of your measurement.

For example you have to cancel all the phase shift due to the setup, DACs, ADCs, sampling delays, buffering, etc (which will not depend on frequency) and the phase shift due to capacitance and analog filters (which will depend on frequency). And you also have to measure a known resistor to know what an ADC amplitude means in terms of analog values.

Since you're measuring a resistor up to 100 Mohms at up to 10kHz, and a parasitic capacitance of 1pF will have 15Mohms impedance at 10kHz, you'll have to be very careful about capacitance, otherwise it will completely swamp your measurement. It's not possible to get rid of capacitance, but if you make it constant, then you can calibrate it out. If picofarads matter, this means you can't have flying wires that could be set in different shapes or with different spacings, because that would change the capacitance. You'll have to use coax. Or you could use no cables at all, and put the TIA on a small PCB right next to the sensor, for example.

Another reason to not use multiple ranges on your ADC is that your setup will probably have like at least 10pF in parallel with the sensor, so at 10kHz on the 100pA range the current through the capacitance will be a lot higher than what you try to measure, so if you use range switching it will just clip the opamp and ADC. If you use an ADC with lots of bits, then no problem.

If you manage to make the sensor capacitance constant and repeatable, then you can fiddle with the TIA feedback cap to somewhat compensate for it. It won't be perfect, unless you manage to build all the sensors absolutely identical, or you make the TIA part of the sensor assembly so each sensor can have its personalized feedback cap, but it should help.

To calibrate you need to be able to replace the sensor with a resistor, so you'll need a connector.

So first you remove the sensor and measure an open circuit, this will give you the response of your setup including all parasitic capacitance, so for this to be accurate, all the wiring must be the same, just the sensor removed. Or you could use a dummy electrochemical sensor without liquid so it has infinite resistance but it still has the capacitance it would have when used in the chemical solution.

Then you can replace the sensor with a known resistor value and measure again. Or, for better results, you would wire a known resistor value in parallel with a sensor that is not dipped in solution, so the only change is resistance, not capacitance.

The method is similar to 2-port network analyzer calibration, but you'll probably be able to ignore most of the terms and use only two calibration points, open and "known load". You can look for literature on that, or you can draw schematics of the various combinations of sensors, no sensors, and calibration resistors... then calculate the impedance of that, put an "=" sign and the measured data on the other side, and solve that system of equations.

If you get the math right, the end result is just a bunch of complex multiplications, divisions and substractions between measured data and calibration data, so it's not difficult to program.

  • \$\begingroup\$ i like the sentiment here which shows that the project is probably less demanding that it first appears if making proper use of hardware and software. @Rata I warmly recommend staying clear of switches altogether at first (they invite tons of new problems) A fixed gain stage with good layout and good DSP can do wonders with minimal hardware. \$\endgroup\$
    – tobalt
    Commented Nov 12, 2021 at 7:36
  • \$\begingroup\$ Yeah it's a nice way to make a quick prototype without too much headache. After this if OP wants a self-contained system then they can build an ADC and DAC ; in fact a Raspberry Pi has I2S IO that works as a soundcard, so it would be convenient to just stick an ADC and DAC plus support circuitry and transimpedance amp on a mezzanine board. The Pi will also run Python and Numpy for easy DSP. \$\endgroup\$
    – bobflux
    Commented Nov 12, 2021 at 7:59
  • \$\begingroup\$ The impedance analyzer part will also need calibration to cancel sensor capacitance (the math is similar to what a network analyzer does) which is again not difficult to do with python/numpy, but MSP430 may have a hard time with complex vector math... \$\endgroup\$
    – bobflux
    Commented Nov 12, 2021 at 8:07
  • \$\begingroup\$ @bobflux thanks a ton for your answer. I'm especially interesteed in the noise-reduction by averaging. Could you explain step by step how you meant the averaging of the sine waves? Because either I am overthinking it or don't understand correctly what you wanted to explain. I would have done multiple measurements of sinewaves anyways and currently I get around 120 datapoints per period if everything works as intended. \$\endgroup\$
    – Rata
    Commented Nov 12, 2021 at 10:30
  • \$\begingroup\$ Also, how would I be able to get the phase directly? For impedance measurement I need the phase shift between input and output signal, how will I be able to get a phase shift without "reference"-phase? \$\endgroup\$
    – Rata
    Commented Nov 12, 2021 at 10:32

You write: "I am currently working on a project, which requires me to measure very low currents"

So the project is to measure very low currents, the project is not to develop a new type of TIA (if it is then all the other answers are superior of course). Look for some supplier, read their datasheets, talk to the suppliers and then buy one. Do the experiment (measuring the currents of the new sensor). If then there is still funding and time you can design your own TIA and see how it compares to the commercial product.

This is the happy path for such a project. There is enough to do to choose the product, and to get the whole thing running.

  • \$\begingroup\$ Yes, you are correct and that was also the first thing I did. Unfortunately I couldn't find any integrated solutions which fitted my requirements. I read through a lot of datasheets, but none of those integrated TIAs have near the gain I would need. \$\endgroup\$
    – Rata
    Commented Nov 14, 2021 at 11:20
  • \$\begingroup\$ @Rata can you specify these requirements [with units]? I find it difficult to read in you post. And lets say what is the reason that lets say these ones do not work for you: thorlabs.com/newgrouppage9.cfm?objectgroup_id=7083 \$\endgroup\$
    – lalala
    Commented Nov 14, 2021 at 12:38

In my opinion, regardless of what circuit topology you may decide on the crucial part will be the point will be the preventing leakage and noise pickup at the input. Start by using the lowest input bias current opamp available. Then use standoffs at the input point keeping everything super clean and free from moisture etc. Then shield this input zone with a copper plate securely soldered to the ground. Design your PCB in line with High Z input criteria as stated by manufacturers. Beware of ground loops and use analog or preferably digital isolation. Design DC accurate low pass or band pass filters in subsequent stages. Make sure DC-DC converters connections stringently follow their manufacturers' application notes. Try to design everything so there is as little chance for noise pickup or parasitic capacitance etc as possible.


You did not say how many digits you need I am assuming you don't need a lot of precision.

Since you are measuring AC, you can let go of the 10GΩ resistor entirely. With a 15pF capacitor and 100pA 10kHz input current the output is 100μV. Filter the output to lower noise. If you use LMC662, the voltage noise will be about 22nV/√Hz * √(10kHz) = 2.2uV RMS.

There is the problem that bias current will integrate and eventually the output of the op-amp will be too close to a rail. You can add a decoupling capacitor at the input (use multiple C0G in parallel if one is not large enough). Then if you use an op-amp with low bias current like the LMC662 (2fA typ.), it takes about 2 hours for the bias current to integrate to 1V with a 15pF capacitor. If you are fine losing 100ms of data every few hours, you can periodically reset the integrator with a push button or relay.


simulate this circuit – Schematic created using CircuitLab

Or if the sensor is resistive at DC and can pass a little current, maybe you can adjust the + input of the integrator with a servo loop.

For inputs that exceed what this integrator can measure, you can engineer another device. If you cannot tolerate two separate devices, you can switch between the two with a relay. Use the NC position for the sensitive one if you're not using a latching relay.

  • \$\begingroup\$ I truly don't need the most precise readout, but I have to admit I don't really understand how a integrator can solve my problem here. It only works like an integrator with DC, granted, but I have frequencies well below 10 kHz that you could as approximated "DC". In addition I want multiple samples per period (not at 10 kHz maybe, but still in the 1-2 kHz range), doesn't that mean I could measure at most the difference between 2 samples on the output of the TIA/integrator? \$\endgroup\$
    – Rata
    Commented Nov 14, 2021 at 12:05
  • \$\begingroup\$ Measure the integrator output. Multiply by jωC to get current. \$\endgroup\$ Commented Nov 15, 2021 at 12:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.