Show Posts
Pages: 1 [2]
16  Topics / Science and Measurement / Re: ESR meter with Arduino on: January 21, 2013, 03:37:24 pm
Hi all,
A few weeks ago I was looking for an ESR meter to build and ran across this thread. Thank you szmeu! I have built this up and it works very well.
I just wanted to share some observations. First, the hardware is a great circuit, simple and effective. Thanks again. And the circuit is very tolerant of the non-polarized capacitor value (47microFarad in the original). I used a 10micro I had and it works fine.
Second, you are correct that the pulse is not from a current source and what you want is to calculate as a voltage divider. (BTW, the original code will get you close enough to serve the purpose, especially at low values of ESR.)
Let's say that Vin is your source voltage (near 5V here), Vout is the value between the two resistors (you measure that at AIN0), Rs is the upper resistance (the 100 Ohm resister) and the lower resistance, the ESR, we'll call Rm. The formula is given as follows.
Rm = Rs / ((Vin/Vout) - 1)
It is important to not mix units, so here is an example. Say your AIN0 measurement, 'milliVolts' variable in the code, is 20. So, Vout is 20mV. Using the value of 5V for the source voltage, Vin, we need to express that in millVolts because that's the unit we're using for Vout. So, Vin is 5000mV. Rs is 100 Ohms so the result will be in Ohms.
Rm (in Ohms) = 100 / ((5000/20)-1) = 100 / 249  = 0.402 Ohms
To get milliOhms, multiply times 1000 or 402 milliOhms!

Here is my re-write of the ESR calc routine. This combines the oversample routine with some things were outside in the original code. A couple of lines are re-ordered. The big calculation difference is at the end.

Code:
// ESR calculation routine
// discharge, start a current pulse, measure the voltage at the ESR_PIN, stop the pulse
// repeat 4096 times and average the results ('oversampling and decimation')
// refer to Atmel Application Note AVR121: 'Enhancing ADC resolution by oversampling'
// http://www.atmel.com/images/doc8003.pdf
double calcESR()
{
  unsigned long accumulator = 0;
  unsigned int sample = 0;
  int i = 0;
  // oversampling 4096 times (for 16 bit is 4^(desiredResolution - ADCresolution))
  while ( i++ < 4096 )
  {
    digitalWrite( DISCHARGE_PIN, HIGH ); // discharge the capacitors
    delayMicroseconds( 600 ); // discharge wait time
    digitalWrite( DISCHARGE_PIN, LOW ); // disable discharging
    cli(); // disable interrupts for the pulse measure
    digitalWrite( PulsePin, PulseActive ); // start current pulse
    delayMicroseconds( 1 );
    // on the scope it appears that after enabling the pulse
    // a small delay is needed for oscillations to fade away
    sample = analogRead( ESR_PIN ); // read ADC value
    sei(); // measured, enable interrupts
    digitalWrite( PulsePin, ! PulseActive ); // stop current pulse
    accumulator += sample; // accumulate
  }
  // sampling is done
  esrSamples = accumulator >> 6; // decimate the accumulated result
  // calculate voltage on AIN0 pin...
  milliVolts = (esrSamples * vRef) / 65.536;
  // calculate ESR in milliOhms...
  double Rm = Rs / ((Vin / milliVolts) - 1); // Rm is in Ohms
  return Rm * 1000; // milliOhms
}

This now consistently measures my 0.1 Ohm and 1 Ohm precision resistors within about 2%. And a 4.7 Ohm resistor reads 4.68. Super!

BTW, I used all those extra pins on the Arduino to drive a 3-digit, 7-segment display. (That's why the code above has interrupt disable/enable calls to protect the pulse measure from the display multiplex interrupts.)

- Totoro

17  Using Arduino / Programming Questions / Re: including a contributed library in a library header on: June 03, 2012, 05:53:25 am
Nick, that was a quick answer! Thank you very much.
"Think of it as a form of documentation."
OK, that works for me!
- Totoro
18  Using Arduino / Programming Questions / including a contributed library in a library header on: June 03, 2012, 05:43:24 am
Hi all,
I'm new to the forum and to Arduino development. I have gotten pretty far thanks to wealth of information here. I am sure this has been asked and answered before but I haven't been able to get the correct search phrase to find it, so excuse me for asking again.
I want to include a contributed library header in my library header. I have written a library named DS1821 for the same-named Maxim/Dallas Semi temperature sensor and want to include the OneWire library (my class inherits the OneWire class). Both libraries, my DS1821 and OneWire, are in the /Users/me/documents/Arduino/libraries directory (Mac OS X 10.6). Arduino is 1.0.1.

In my header, DS1821.h, I have the lines

#ifndef DS1821_h
#define DS1821_H
#include <OneWire.h>
. . .
#endif // DS1821_h

However, my application won't compile unless I include both headers.

#include <OneWire.h>
#include <DS1821.h>
. . .

While this works just fine, what should I do to not have to include the OneWire header in my application code?
Thanks for your help!
Pages: 1 [2]