Skip to content
 

Environmental temperature readings with Arduino.

Some days ago, while I was reading the ATMEGA328P datasheet, I found an interesting (little known?) feature. The IC has an integrated thermistor!

As it is integrated in the die the readings are not really environmental, but anyway the IC doesn’t make much heat, so we are quite close to the right temperature.

There is no support in the Arduino own libraries so I had to code everything from scratch. The datasheet is quite clear on how to get the raw readings. Just set the multiplexer to the thermistor input, set the ADC voltage reference to “internal” and we are ready to do the readings.

I don’t find the readings from my Arduino consistent with the datasheet. Maybe the table is wrong, or maybe they don’t care much of the scale as the declared precision is ±20 C°, but the sensitivity is around 1mV/C°.
By assuming linear response, I got this formula:
t_celsius = raw_t / vref_mv * adc_top * t_factor – t_constant
Getting t_factor by interpolating the datasheet’s table and t_constant by my poor measurements (I don’t want to put my Arduino running in a thermostatic oven or fridge!) I get the formula:
t_celsius = raw_t / 1100 * 1024 * 1.028 – 307.28
which can be approximated by:
t_celsius = raw_t – 322

So here is the code:


#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/io.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

void setup() {
Serial.begin(9600);
ADMUX = 0xc8; // 1100.1000 -> c.8
}

void loop() {
uint8_t h;
uint8_t l;
int t;
sbi(ADCSRA, ADSC);
while (bit_is_set(ADCSRA, ADSC));
l = ADCL;
h = ADCH;
t = (h << 8 ) | l;
delay(100);
//Serial.println( t );
Serial.println( t – 322);
}

If you try it, please tell me about your experience and whether you find better values. Don't melt Arduinos in the process. Or at least make a youtube vid of it :P

It would be way better if I used timer + interrupts so the IC can sleep, draw less power and produce less heat and give better readings, but I'm lazy. Actually I tried but after the first reading the CPU never woke up, I got something wrong.
So, nice hacking! If you find this useful and you do something fun with it let me know :)

  • Share/Save/Bookmark

Leave a Reply