ESR meter with Arduino

First of all I would like to thank you all for such a great work.

I have been implementing the ESR meter, and checking Totoro's function I saw he is using the voltage supply as a parameter. Then I remembered about the hidden voltmeter to own supply voltage on 168 and 328 chips. I just added it on setup and it improves measurement quality. Actually, helps a lot regarding "well regulated quality supply" requirements ;)

Oh, regarding the coupling capacitor: as a bipolar capacitor I have 2 electros 330µF/35V in a back to back configuration. There is a lack of slope in the scope, which means that it is only measuring ESR. Actually, coupling cap ESR is not that important: 1Ohm ESR would only affect 1% over the 100 Ohm sense resistor. Capacitor value however is important, because a low capacitance value would bother the reading due to capacitor impedance. Regarding 4wire sensing: as the ground is shared, 4w cannot be used, but 3-wire sensing can and should be used because it is extremely easy to implement. Regarding Transistors: Transistor models are not important, they are operated as a switching device. However, they should be "fast" to switch. Currently I am using a 2SA733 and 2SC945 that I had in junkbox.

Oh, another thing, adding a decoupling capacitor between PNP transistor emitter and sense ground would be beneficial as well. Location on PCB should be as close as possible to those points.

Edit: Couple mods I think interesting: Playing with it, I just realized that if capacitors hold (or grow) any charge, readings get (easily) bothered. In the original schematic, there is a 10k capacitor to ground, I decreased it to 470 Ohm: well far to bother reading range and low enough to not grow bald while waiting to discharge 1000µF caps... The modification of the "commercial" schematic with BS170 does that, but I think there is no need for 50mA application. For LOW ESR Capacitors, original circuit may be a bit "short" in current terms. If increasing current to say 100mA, decoupling is probably needed for good measurement stability. According to my oscilloscope, measurement last 35µs, so I would use over 100µF...

I have been playing a bit with the Code and the ADC, and reading about it.

It is interesting that maximum 10bit speed is specified at 200kHz, FASTADC option of original code sets the ADC speed at 500kHz, which can degrade resolution. Totoro decreased that speed to 250kHz, increasing acquisition time, but it is important to understand how the ADC works (which I didn't know before :roll_eyes: ) ADC operation is preceded by sample&hold where input is sampled. That takes around 2 ADC cycles and then conversion which may take up to 25cycles. At 250kHz ADC clock, sampling time should be around 8µs, and 4µs when a 500kHz ADC is used. Measuring voltages with oscilloscope, approximated voltage sampling occurs around 10µs and 6µs after pulse activation. Here I attach a picture of a 500kHz ADC sampling a 10µF capacitor. Measurement is pretty close with expected times of around 4µs sample&hold + 1µs delay of micros(1)+ ...

Note that for a 10µF capacitor there is an important charging slope of the capacitor, which sets measurements a bit off. At 50mA and 6µs delay that is ~300mV/C[µF] and 10µs delay ~500mV/C[µF] Using: deltaV[mV]=50*DELAY[µs]/C_value[µF] Even setting a prescaler for ADC clock at 1MHz the delay effects would be around 200mV per each µF.

This comment is important because: decoupling cap can be smaller than what I said before :roll_eyes: and because that with those mV/µF we can find wich is the low-ESR measuring limit for different cap values.

Oh! In Totoro's code, delay added is 5µs, which considering the 250kHz ADC would set the capacitor charging error to ~700mV/µF

Sidenote: The capacitor charging effect and knowing the exact point of S&H can be used to estimate capacitor value as well, even to correct the capacitor charging effects.


My third post in a row…
…finaly I have what seems to be a decent operating capacitor measurement + ESR correction.

Capacitor values found are an estimation, but seem to match with my multimeter readings within 5-10% (tested from 10µF to 1000µF). Then once capacitor value is found, I used to correct the ESR deviation due to DUT charging effects, which can be seen as a resistance at the sampling instant, which if I didn’t do much wrong, would be Zequivalent=deltaV/I → Zeq=6µs/C[µF]
I’d appreciate any comments regarding if this makes sense or I just got crazy here…

Anyways, I attach code for Capacitor measurement function (below 10µF gets high error, so I just cropped under 5µF, I won’t use it with such small caps anyway :smiley:

double measureC()
  double CAP;
  unsigned long esrSamples;
  unsigned int sampleA = 0;
  unsigned int sampleB = 0;
  int cnt = 0;

  //oversampling is overrided
  digitalWrite(DISCHARGE_PIN,LOW);//disable discharging
  digitalWrite(PULSE_PIN,LOW);//making a miliVolt pulse of 50mA
  delayMicroseconds(1);//Considering S&H is done after 2us, this could even be taken away.
  sampleA = analogRead(ESR_PIN); //First read: T=6us
  while((sampleB<sampleA+100)&&(cnt<40)){  //less than 107mV between samples or 40 times done the loop
    sampleB = analogRead(ESR_PIN); //Second read: T+delay
  // If we are here, either samples have more than 107mV or comparison TimedOut
  digitalWrite(PULSE_PIN,HIGH);//stopping pulse
  digitalWrite(DISCHARGE_PIN,HIGH);//discharging the capacitors
  delayMicroseconds(600);//waiting a bit longer

  //Vsupply is found using 'Hidden Voltmeter in AT328'
  //Resistor value is 100.0 (approximated)
  //45.0 is the delay time between measurements (estimated by measured values).
  CAP=45.0*cnt*Vsupply/100.0/(sampleB-sampleA)/vRef; //50us_delay*times_of_delay * Current / (voltagedifference)
  if(CAP<5)  return(0.0);
  else       return(CAP);

Regarding ESR function, I only altered the last part of the function to correct for capacitors detected but smaller than 1000uf

  ESR=1000*100.0 / ((Vsupply / miliVolt) - 1); //100 is sense resistor  //Correct with Cvalue!!!!!
    return ESR-6000.0/Cvalue; //Capacitor nuissance, Req=6/C[µF]
    return ESR;

Thanks for this project everyone, I'm planning to build one of these as soon as I have wrapped my head around all the info in the thread and have had time to design a shield for it. Will upload the gerber files here if someone would be interested. I'm probably going down the SMD route, since I like tinkering with 0805 components :astonished:


I'm about to build this project with parts I have and am a bit lost with caps that are being used.

I have a 2A104J greencap to use as the 100uf (C2).

But the 47uf, Bipol (C1) I do not have, only in electrolytic cap form. I am assuming that I need to find a bidirectional cap? is that what you call a cap that can be used either polarity?

I am finding it hard to find an assorted pack of caps which are not electrolytic on ebay.

Also the only transistors I have are BC328 and BC338. The schematic says 327 and 337...Is there a difference?

One more Q, how the hell are all of you guys making your own circuit boards?

Thank you.

I think that I am worndering how to wire up the push button ZERO with my 2 wire LCD display.


I also built a standalone version of this and it seems to be working ok. There is one thing I don't know what to make of, though.

In the original schematic, there's R4 connected to Arduino digital pin 8. This doesn't seem to be used in any version of the code I found. From what I understand, this was intended to be used as a low current pulse output. Is this correct? If so, isn't the version posted by mikanb

So let me recap (absolutely no pun what-so-ever intended!):

  • The original R4/D8 connection was never used by any version of code seen here on this thread.
  • The 1k-PNP-1k implementation by mikanb does what R4/D8 originally intended to do but never did.
  • The ak-PNP-1k implementation by mikanb is superior to the original R4/D8 implementation, because it adds a bit more decoupling from the MCU through the PNP.
  • In a revised design, I could omit the R4/D8 connection in favour of mikanb's implementation.

Right...? Is it?



@alibenpeng right it is! your observations regarding R4/D8 are correct :-)


Thanks for clearing this up!



I'm looking for SMD parts for this, but being pretty noobish I'm not sure what characteristic to look for in the 1N5822 schottky diodes - could anyone help me explain this? The discussion have been about 300mV voltage drop, but I don't understand what characteristics of the diode this comes from. The specified forward voltage drop on the 1N5822 I've found is 525mV or 950mV.

Great ! Thanks for share !

Thanks for your share !


I got messed up reading this whole posts... Not perfect in english, sorry.

Can anybody tell me - or post- the correct code for this project? I really would like to give it a try, but don't know what changes on the original code I have to make. And where...

Help would be nice!

Thanks! Andy

IT would be nice to have A complete circuit schematic and code pack. I know there have been alot of changes since the very first post. This is a great project just unorganized. Would someone be willing to bundle all the latest up and put it in a zip file to download.

yeep, it would be so cool...

jtroutt19: IT would be nice to have A complete circuit schematic and code pack. I know there have been alot of changes since the very first post. This is a great project just unorganized. Would someone be willing to bundle all the latest up and put it in a zip file to download.


Baravantan: ... 10 downloads of the attached .zip file with code, images, schematics and PCB design...

Great ! Thanks for your share !

Help please, does anyone have arduino code for the original schematics? thanks

hi dear
please tell me,DUT connect to the wich pins of CN1?

This is very old thread, however I have a need to build some simple, cheap and more or less reliable ESR tester fast…

I have look and read this thread and dr. Le Hung website about ESR. Few things I have noticed:

  1. The schematic is almost identical to dr. Le Hung ESR part.
  2. Notification on this forum ESR is not able to do in-circuit measurement, while dr. Le Hung device is.
  3. Dr. Le Hung do not expose source (hex only for ATmega88PA) as it sold the device.
  4. The 47uF discharge capacitor need to be non-polarized? This is not commonly available part easily found in local stores.

Upper force me to believe many things could be improved for this Arduino open source version.

  1. If hardware is almost identical, identical features this ESR tester should have. I.e in-circuit measurements (up to ~300mV test voltage) is possible to achieve.

  2. As I’m only amateur, my knowledge in electronic is limited. However, if 47uF is jut discharge capacitor, I believe it could be used two 100uF 100V in series el. capacitors (with the diodes protection) - the circuit to make non-polarized capacitor from two polarized. This kind of capacitor configuration double its own ESR, however if it serves only to discharge it before test, this is not crucial. Even better, any, especially larger capacitors should be discharged before test in order to protect MCU.

  3. The most important feature for an ESR is to have measures with at least two freq. I have not found at dr. Le Hung documentation that his device can do that as well (only measurement at 100KHz).

Anyone with more experience can elaborate about for this circuit?

If not, is there some DIY circuit with commonly available parts is proven to be able for in-circuit measurements as well as can test in at least two freq.?

Thanks in advance.