"Trick" for measuring DC voltage with 0.1mV sensitivity (MAX6675)

Hey guyz,

For the past couple of weeks I was stuck trying to amplify small DC voltages in the range 0-1mV for my Arduino. Others have inquired about it before, and it is no easy task because of the Input Offset in OpAmps.

But then I got thinking laterally, while playing with a thermocouple (also used in my setup). They output a tiny voltage of mV order, and this voltage increases linearly with temperature. So I bought a couple of cheap MAX6675 on Amazon, and converted their temperature reading back to mV with a 1st degree polynomial. It gives me a decent sensitivity.

I have attached below a photo of my setup (two MAX6675 for DC measurement, and a MAX31856 for actual temperature measurement). The other screenie shows DC voltage measurement over 30min, while stepping the voltage progressively (0.0, 0.2, 0.3, 0.5, 0.8, 1.0mV).

I wrote a small wrapper class for the MAX6675, as shown below. I figured that other people might save time with their own project if I share this “trick”. It is not meant to be scientific, just a little bit of help for people who have no experience with designing an amplifier on their own…

#include <max6675.h>

class Amplifier: public MAX6675 {
	public:
		Amplifier(int p0, int p1, int p2, int p3, int p4) : MAX6675(p0, p1, p2) {
			pinMode(p4,OUTPUT); digitalWrite(p4,LOW);
			pinMode(p3,OUTPUT); digitalWrite(p3,HIGH);
		}
		
		float readVoltage() {
			return (MAX6675::readCelsius() * 0.047 - 1.35);
		}
};

Cheers,
Tony

The MAX6675 compensates for the "cold junction" temperature, so your linear correction will be valid only at one temperature. Temperature drift may account for the measurement drift shown in the photo of the test results.

The HX711 load cell amplifier is designed for measuring a few mV differential, works very well and doesn't have that issue.

Sorry, don't know about your sensors, but for measuring your voltage levels you may use an ADS1115. At it's maximum gain of 16, it has a range of +/- 0.256 V.

wvmarle:
Sorry, don't know about your sensors, but for measuring your voltage levels you may use an ADS1115. At it's maximum gain of 16, it has a range of +/- 0.256 V.

Hey WVMarle. Thank you so much for this piece of information.
Had I known about this chip 2 weeks ago, I would have saved myself a lot of effort!
I found it on Amazon, and also a tutorial for using it, awesome!!

Note that most of the above solutions require the measuring voltage to be within the common mode window of the device.
For e.g. the HX711 that is a ~1.2volt to ~3volt window above ground.
The ADS1115 can't measure negative voltages.
Leo..

8bit-Dude:
Hey guyz,

For the past couple of weeks I was stuck trying to amplify small DC voltages in the range 0-1mV for my Arduino. Others have inquired about it before, and it is no easy task because of the Input Offset in OpAmps.

Which opamps have you looked at? Probably not a CAZ opamp then?

To quote the AD8628 datasheet:

With an offset voltage of only 1μV, drift of less than 0.005 μV/°C,
and noise of only 0.5 μV p-p (0 Hz to 10 Hz), the AD8628/AD8629/AD8630 are suited for applications
where error sources cannot be tolerated.

I bought a couple of ADS1115, to perform a similar test to what I had done with the MAX6675.

The first module was an absolute piece of crap.
If you ever see something that look like this, RUN AWAY:

The second module looks like the photo on the ADAfruit website, it is much better:

I have attached a screenshot of my test.
There is no voltage drift, but about twice as much noise as the MAX6675.
Stepped voltages were: 0.025mV, 0.05mV, 0.1mV, 0.2mV, 0.5mV, 1.0mV.
Measured voltages were: unreadable, unreadable, 0.1mV, 0.3mV, 0.6mV, 1.2mV.

For a 16 bit ADC, 5V/65536 = 0.1 mV, so you certainly can't expect to do better than that without oversampling and averaging.

jremington:
For a 16 bit ADC, 5V/65536 = 0.1 mV, so you certainly can't expect to do better than that without oversampling and averaging.

Eh? :confused:

The ADS1115 has a PGA, so if the OP used the +/- 0.256 v setting, then the least significant bit size is about 8 micro volts.

jremington:
For a 16 bit ADC, 5V/65536 = 0.1 mV, so you certainly can't expect to do better than that without oversampling and averaging.

By setting the gain you can get 256 mV full scale, which would (at least in theory) give a resolution of 3.9 uV.

I hear an echo. :slight_smile:

wvmarle:
By setting the gain you can get 256 mV full scale, which would (at least in theory) give a resolution of 3.9 uV.

Actually, full scale is plus or minus 0.256 v, so the best possible resolution is "only" about 8 micro volts (sez the datasheet), not 3.9 uV.

DaveEvans:
Eh? :confused:

The ADS1115 has a PGA, so if the OP used the +/- 0.256 v setting, then the least significant bit size is about 8 micro volts.

That's the setting I used for these test. In theory the sensitivity is 0.256/32535 = 8uV, but in practice the sensitivity was closer to 100uV, as shown in my tests.

For 1mV signals you definitely want to amplify by 1000 or more before the ADC, rather than trying to use
a high-resolution ADC to make up for lack of gain - the issues with noise and drift are far easier
to control if the signal level is boosted first.

This implies 2-stage opamp circuit into a moderate performance ADC (Arduino's 5V 10 bit ADC will give 2uV
resolution over a +/-1mV range if you amplify x50, x50 first). As I've said ultra-low offset opamps certainly do exist.

The compromise of using a load-cell amp (single high gain instrumentation amp) in place of two
opamp stages is a reasonable one, thermocouple amps are much less suitable due to the cold-junction
compensation circuit.

Just to keep interested people updated, I found this brilliant 24 bit ADC which I bought on ebay: Welcome henrysbench.capnfatz.com - BlueHost.com

It has a sensitivity of about 0.01 mV for voltages in the range 0-5V.
You can improve this by setting a lower reference voltage.