ESR meter with Arduino

I am happy to post my code. You can download it from here.
http://vondervotteimittiss.com/belfry/downloads/ESR_Meter.ino.zip
Just keep in mind, it is a work in progress. As it stands, it works with the 'high-current' resistor in the circuit (the 100 ohm resistor which is actually 110 ohm in my circuit and in my code I refer to this as the low range).
As I mentioned, the schematic I used is the same as szmeu originally posted. (OK, not exactly. I use a 110 ohm resistor, because I had one, and a 10microFarad capacitor, because I had one. Adjust the resistor value accordingly in the code.) The pulse generation part of the circuit as szmeu posted is really elegant and needs no change.
The only change I made is in the display. In my breadboard, I use a three-digit, seven-segment display and have programmed the Arduino drive it. (Adjust the SEG_ON/OFF, DIG_ON/OFF defines as appropriate for your display setup and anode/cathode digit switching transistors.)
I am currently working on getting the 'low-current' mode (the 1000 ohm resistor), what in my code is the high range, to work. That should let me measure higher values of ESR, as szmeu suggested.
Please keep in mind that I am new to micro-controller programming! If you have any questions about the code, I'll try to answer as best I can.
And if you have any suggestions how I can improve, please let me know.
Thanks for your interest.

  • Totoro

Hi all,

Since I do not have an Arduino, I have built szmeu's original circuit around an Atmega8.
The only difference is that I'm using 1N5821 instead of 1N5822.
The firmware has been adapted from Totoro's code.
When connecting a cap or small resistor across pins 1+2 and GND, I'm getting nothing, the ADC value is always 0. (2.56V internal reference)
However, when connecting a potentiometer accross +5V and GND with the wiper going to the ADC (ADC0/PC0 in my case), I'm getting values, so the ADC seems to be working ok.
Charging pulses are generated, measuring about 30mV pp at pins 1+2 (maybe too low?)
Any pointers as to what could be wrong?

When you use a resistor to charge-up a capacitor, the current goes down as the capacitor is charging up, exponentially. This is less of a problem initially; but as the capacitor is charged up, the error (from a linear charging up process produced by a ccs) gets bigger (small resistor or small capacitor, or long charge-up time / cycle).

One way to solve this is to taylor-expand the integral of current over time. You only need to expand to its 2nd order derivative to maintain fairly good accuracy.

Sreg,
First, just to be sure we're on the same wavelength, short pins 1 and 2 on CN1 (on szmeu's schematic) together and put the device-under-test (DUT) between these shorted pins and ground. For now, just ignore the possibility for a four-wire setup (actually three wire with the circuit from szmeu).
OK, you've done that. Now, with a 30mV pulse across your DUT, you can do the math and you should have approx. 600milliOhms +/- for the DUT. This assumes that at top of the 100 Ohm resistor, R8, (where it connects to the emitter of Q1) you see a 5V pulse.
If that's the case, then you may want to make sure that the oversampling is set up correctly for your device. You may need to change some of the register set stuff in the original code. This stuff...
sbi(ADCSRA,ADPS2);
cbi(ADCSRA,ADPS1);
sbi(ADCSRA,ADPS0);
Refer to the datasheet for your device and the Atmel document that szmeu mentions.
Then again, it could be something simple like the discharge transistor, Q2, is always on. Or you didn't change the value of Vref in the code. You mention the internal ref on your device is 2.56V. In the code it's 1.1.
This is all just guesses on my part. Maybe you have checked all this stuff. My 2 (euro) cents worth, anyway.
Good luck!

  • Totoro

Totoro, have you designed PCB by any chance?

bobale,
Sorry, I am just a breadboard/point-to-point/proto-board type. My main need for an ESR meter is to troubleshoot old audio gear and test equipment.

I also need it ocasionally, but I would rather build standalone device, but I'm really bad at PCB design, so I'll wait for someone else to do it (someone who needs it more than me) :grin:

Totoro,

thanks for your reply!

Totoro:
Sreg,
First, just to be sure we're on the same wavelength, short pins 1 and 2 on CN1 (on szmeu's schematic) together and put the device-under-test (DUT) between these shorted pins and ground. For now, just ignore the possibility for a four-wire setup (actually three wire with the circuit from szmeu).

Yes 1+2 are shorted together amd DUT is placed between those and GND.

OK, you've done that. Now, with a 30mV pulse across your DUT, you can do the math and you should have approx. 600milliOhms +/- for the DUT. This assumes that at top of the 100 Ohm resistor, R8, (where it connects to the emitter of Q1) you see a 5V pulse.
If that's the case, then you may want to make sure that the oversampling is set up correctly for your device. You may need to change some of the register set stuff in the original code. This stuff...
sbi(ADCSRA,ADPS2);
cbi(ADCSRA,ADPS1);
sbi(ADCSRA,ADPS0);
Refer to the datasheet for your device and the Atmel document that szmeu mentions.

I'm fairly sure my code is ok, but I'd be glad if you could take look at it - please see attachment.
I'm also getting about 3V pulses measured at the emitter of Q1.

Then again, it could be something simple like the discharge transistor, Q2, is always on. Or you didn't change the value of Vref in the code. You mention the internal ref on your device is 2.56V. In the code it's 1.1.

Unfortunatley the Atmega8 has only 2.56V internal reference voltage, but I think I can live with any decrease in resolution this will introduce.
My problem is that no values whatsoever are displayed when connecting the DUT as described above. (ok not entirely true, -1 is displayed since I return -1 from the calculation if millivolts are 0 - please refer to source code).
Q2 should not always be on, I get pulses on its base according to the discharge pulses.

If I get this to work, I'll gladly post my pcb layout.

-- Sreg

ESR-Meter.c (3.19 KB)

Finally got it to work, it seems the BC327 was defective :blush:

Thanks for all the help!
As promised, I attach my layout and source code (built with Atmel Studio 6.0).

-- Sreg

ESR-Meter.zip (362 KB)

wow thx for the layout. I was just starting to design one. Saved a lot of work.

markbee

Sreg,
Great to hear you got it working!
You mentioned above that you return -1 when millVolts is zero. I wondered why, so I took a look at your code. You have helped me to avoid a bad thing, the potential divide-by-zero bug. Thank you!

  • Totoro

What Schottky diode is everyone using that has had success? I am currently using a B340A-E3/61T and the pulse peak at the terminal with no DUT is only around 150mv. I think this is causing my reading to drastically be off. I am trying to wrap my head around how the current voltage divider equations every one is using is working. It doesn't take in account of the clamping voltage and power dissipation of the Schottky diode. Any help would be greatly appreciated!

Hi bseishen,

If you read my original text (kept intact, below) then I am sorry. I 'double-thinked' myself into some confusion. I will try for a better take.
First, the Schottky diodes only limit the maximum voltage available to the DUT. Here's what happens. The transistor Q1 turns on and a rising wave edge goes through R8 and is pretty much unaffected by C2/C1. So, R8 is effectively in series with the DUT. This forms a simple voltage divider and the rising wave edge sort of shelves at the voltage determined by the divider formed by R8 and the DUT. For a DUT with, say, 100 milliOhms, that is a pretty small voltage, i.e., a few milliVolts. Since we're dealing with capacitors here, there is some continuing charging that will mess up the measurement if we wait too long to make it. I put together a LTSpice model to play with this. Attached is a closeup of a pulse from a sample run with a DUT of 100uF and .1 Ohm ESR. The yellow trace is the R8 side of C2 and the blue is the DUT side. (I had looked at the same thing on a 'scope and the simulation agrees really well. I don't know why it didn't sink in earlier. It is interesting to do a run with a resistor as DUT. The 'shelving' is more apparent.)
So, pretty much ignore what I said before. Part of my confusion was from using a different power source after changing the diodes. This shows that the value for Vcc in the code is quite critical for consistent and linear results. Also, it is now apparent how two ranges work by adjusting the voltage divider.
I hope this helps. My understanding is better, anyway.

---- here is the original text ----
I went back and really looked at this as well as reading the original document by Dr. Le Hung (link in szmeu's first post). I have to admit that after looking closely, I really don't understand this completely either. Clearly, the pulse can only have an amplitude determined by the schottky forward breakdown. In my circuit I used germanium diodes and that was about 300mV. I just swapped them for 1N5822 (as in the orignal schematic) and now have a pulse of 220mV and my calibration is way off. What seems apparent now, is that the voltage specified in the code as the 'supply' voltage, i.e., 5V, is just a number. I mean that it has to be adjusted to correspond to something that, well, I don't know exactly what it specifies. Dr. Le Hung calls the pulses current pulses. There must be something to that since the two ranges do work (there is a factor of ten, approximately, difference when the pulse 'comes from' the 100 vs. 1000 Ohm resistor).
Try playing with the voltage value and see if you can dial something in. I haven't tried that yet but it will be my next step to try and figure this out.
I am first a software guy and the hardware part of this is now not as clear as I thought. Maybe someone else can add to this.

ESR pulser.asc (3.56 KB)

Totoro:
Ended up doing some spice analysis on the schematic. The line is very linear! So with a simple slope formula should be able to get some good results. I currently have some 1% resistors in the mail, when i get them in i'll test this out.

Wow, what timing! You posted while I was composing. Please read my update.
I think your simulation is too simplified. I would be interested in your opinions if you would try mine.

Yup, it is super simplified. Just decided to do DC analysis only. I ran your schematic and I'm getting the same voltage per ohm on the ADC pin :slight_smile: Have you tried running different Schottkys? It changes the ADC voltage quite a bit! The DUT is incremented in .5 ohms on the attached graphs.

MBRS1100.png

1N5819.png

I have upgraded existing code with previous modifications to expand measurement range up to 50 Ohms and to make this ESR meter autoranging in the range of 0-50 Ohms which should be more than enough range for the ESR measurement. The code is included in the attachment and on the schematic you have to add one more PNP transistor with the same configuration as Q1 but with the 1k resistor instead of 100R (1k is for upper range measurement). Pinout in my sketch version is different in order to match my board so you will have to modify it according to your board settings.
Any comments/suggestions are welcome...

ESR50_AutoRange.zip (5.55 KB)

Hello everyone, and thank you for sharing your work.
I built the ESR meter using an Arduino UNO and a lcd display CDL4162-HD44780.
My version can work in two ways: with Arduino UNO connected to the board face down, and in standalone mode.
In the first case, only the bottom side of the pcb is required (single side)
I also added a function that allows me, by selecting the right value of the DUT, to know immediately if it is good or not.
BUT there is a problem: If I measure a 1ohm resistor, the reading is quite correct, but if I measure 150mohm or 75mOhm, the reading is totally wrong. :astonished:
Is there anyone who can help me? Thank you. :~

Standalone.JPG

1000mOHMs.JPG

150mOHMs.JPG

...mah:
20 days, 10 downloads, 0 replies :zipper_mouth_face:

You need to post the code you are using and the schematic of your hardware before someone can help you.