# Can you get better than 10 bit A to D resolution from the Arduino platform.

I am a total newbee to Arduino (in fact, to solid state electronics in general). I am trying to monitor and control the temperature in an electric furnace (0 to 2400 deg. F) using a type K thermocouple connected to an AD8495 amp, connected to the Arduino (was thinking of using a Mega 2560) which would then be connected to the PC, running a C++ program to monitor furnace temperature. The C++ program would also control the furnace temp. by sending on\ off signals back to the Arduino, which would then switch power on and off to the furnace using an SCR. My problem is (I think) the 10 bit resolution of the A to D in the Arduino. I am measuring temps. from about 70 deg. F to about 2400 deg. F. 2400- 70 = 2330. 2330/1024 = 2.28. I suppose I could live with 2.28 deg F, resolution, but is there a simple way to get 1 deg. F resolution in this scenario? This may be (probably is) a stupid question, but like I said, I am a total newbee, and when I tried to search for an answer to this question, all I could find was a suggestion to use two A to D inputs, but it did not explain how to do this, much less how to do this seamlessly. Any suggestions would be greatly appreciated. I would greatly prefer staying with the Arduino platform, as any journeys off into IC individual component never-never land would leave me hopelessly lost! Thanks much; you folks have a great thing going here and I was really lucky to have been steered onto it!

In practice your resolution will be lower, because of the noise and other factors.
You may do more measurements (ie. 1000), sum up all the measurements and then divide the sum by 1000 - that is called averaging. You will get better resolution. The noise helps (dithering).

Another approach is smoothing/filtering (low pass filter). You do measurements in a loop where (for example):

``````..
new_temp = 0.98*old_temp + 0.02*new_temp;  // =A*old_temp + B*new_temp,  where A+B=1.0
do something with new_temp;
old_temp = new_temp;
..
``````

That will provide a low pass filter which gives you a better resolution. The A+B=0.98+0.02=1.0, you may use other ratio, the lower the B the longer the time constant of the filter..

"The AD8494/AD8495/AD8496/AD8497 allow a wide variety of supply voltages. With a 5 V single supply, the 5 mV/°C output allows the devices to cover nearly 1000 degrees of a thermo-couple’s temperature range."

How are you powering the AD8495?

The AD849x achieves a linearity error of less than ±2°C, within the specified operating ranges listed in Table 7.
AD8495 K ±2°C 0°C to 50°C ?25°C to +400°C

For temperature ranges outside those listed in Table 7 or for instructions on how to correct for thermocouple nonlinearity error with software, see the AN-1087 Application Note for additional details.

The C++ program would also control the furnace temp. by sending on\ off signals back to the Arduino, which would then switch power on and off to the furnace using an SCR

I would leave that function to Arduino instead of the computer. It will be easier, I guess.

Related to averaging, you can also use oversampling with the 10bits ADC.

4 samples gives you 1 bit extra
16 samples gives you 2 bit extra
64 samples => 3 bit extra
256 samples => 4 bit extra
1024 samples => 5 bit extra

the price is time …

``````//
//  AUTHOR: Rob Tillaart
//    DATE: 2012-05-10
//
//
// http://www.atmel.com/Images/doc8003.pdf
//

void setup()
{
Serial.begin(115200);

for (int b=10; b< 17; b++)
{
unsigned int val = analogReadN(A0, b);
Serial.println(val, DEC);
}
}

void loop()
{
}

{
bits = constrain(bits, 10, 16) -10;

int samples = 1 << (bits << 1);

uint32_t sum=0;
for (int i=0; i< samples; i++) sum += analogRead(pin);
return sum >> bits;
}

{
bits = constrain(bits, 10, 16) -10;

int d = 1;
for (int i=0; i<bits; i++) d *= 2;
int samples = d*d;

uint16_t sum=0;
for (int i=0; i< samples; i++) sum += analogRead(pin);
return sum / d;   // rounding => return (sum + d/2) / d;
}
``````

Have you considered using a MAX31855K instead of the AD8495? It provides a digital output with a resolution of 0.25C, so you don't need to use the Arduino ADC.

Oversampling when you use the built-in ADC only gives you increased resolution if you have the right amount of random noise on the signal.

The MAX31855 performs cold-junction compensation
and digitizes the signal from a K-, J-, N-, T-, S-, R-, or
E-type thermocouple. The data is output in a signed
14-bit, SPI-compatible, read-only format. This converter
resolves temperatures to 0.25NC, allows readings as high
as +1800NC and as low as -270NC, and exhibits thermocouple
accuracy of ±2NC for temperatures ranging from
-200NC to +700NC for K-type thermocouples.

degree F = 9/5 degree C + 32
so (degree F - 32) *5/9 = degree C

(2400F-32)*5/9 = 1315C

From Page 3, looks like MAX31855R or MAX31855S might be a bit more sensitive,
but the overall error (-4C to +4C) is the same.

Price looks to be the same for K or S parts:
http://www.digikey.com/product-search/en/integrated-circuits-ics/pmic-thermal-management/2556560?k=max31855

The accuracy of your thermocouple won't be better than 1 part in a thousand anyway. And nor will the process of turning the heat on and then off again, to regulate the temperature.

There is no point being picky about one aspect of your process without tackling other sources of uncertainty which are much larger.

If you really want better a/d resolution, there are plenty of external a/d chips with 12 or 14 bit resolution which are easy to use and have other benefits like faster speed.

robtillaart:
Related to averaging, you can also use oversampling with the 10bits ADC.
Read - Application Notes | Microchip Technology -

4 samples gives you 1 bit extra
16 samples gives you 2 bit extra
64 samples => 3 bit extra
256 samples => 4 bit extra
1024 samples => 5 bit extra

the price is time ...

Well its more than that, you have to ensure there's enough Gaussian noise in the
system before you average, otherwise you just average 16 identical samples,
or 256 identical samples. Just enough noise allows the actual voltage to affect
the probability of the value being read as N or N+1 or N-1 counts on the ADC.
Then the averaging process effectively measures this probability as a proxy for
sub-LSB voltage.

To get accurate linearity in averaging lots of readings you, alas, have to inject more
noise to make the relationship between probability and voltage linear enough.

Furthermore you cannot improve upon the existing imperfect linearity of the ADC
response staircase function, so in practice don't expect to get more than 1 or 2 bits more.

If there is existing noise you have to worry about whether its correlated to the signal
or not, since correlated noise cannot be removed by averaging...

I feel averaging 8 or 16 samples is probably worth it, more is not, get a sigma-delta