// Internal Temperature Sensor // Example sketch for ATmega328 types. // // April 2012, Arduino 1.0 #if defined(__AVR_ATmega48__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega88__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined (__AVR_ATmega328__) || defined (__AVR_ATmega328P__) #define USE_SERIAL #endif void setup() { #ifdef USE_SERIAL Serial.begin(9600); Serial.println(F("Internal Temperature Sensor")); #endif } void loop() { // Show the temperature in degrees Celcius. #ifdef USE_SERIAL Serial.write(F("Temperature: ")); Serial.println(getChipTemp(), 2); Serial.write(F("Voltage: ")); Serial.println(getVCCVoltage(), 2); #else getChipTemp(); getVCCVoltage(); #endif delay(1000); } double getChipTemp() { uint16_t wADC; // Set the internal reference and mux. #if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined (__AVR_ATtiny85__) ADMUX = 0b10001111; // REFS2 = 0; REFS1 = 1; REFS0 = 0; MUX3:0 = 0b1111 // Reference = 1.1V, Measure ADC4 (Temperature) #elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined (__AVR_ATtiny84__) ADMUX = 0b10100010; // REFS1 = 1; REFS0 = 0; MUX5:0 = 0b100010 // Reference = 1.1V, Measure ADC8 (Temperature) #elif defined(__AVR_ATmega48__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega88__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined (__AVR_ATmega328__) || defined (__AVR_ATmega328P__) ADMUX = 0b11001000; // REFS1 = 1; REFS0 = 1; MUX3:0 = 0b1000 // Reference = 1.1V, Measure ADC8 (Temperature) #else #error Unknown CPU type, not implemented. #endif ADCSRA |= _BV(ADEN); // enable the ADC delay(10); // wait for voltages to become stable. ADCSRA |= _BV(ADSC); // Start the ADC // Detect end-of-conversion while (bit_is_set(ADCSRA,ADSC)); // Reading register "ADCW" takes care of how to read ADCL and ADCH. wADC = ADCW; // The offset of 324.31 could be wrong. It is just an indication. return (wADC - 314.0d ) / 1.22d; } double getVCCVoltage() { uint16_t wADC; // Set the internal reference and mux. #if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined (__AVR_ATtiny85__) ADMUX = 0b00001110; // REFS2 = 0; REFS1 = 0; REFS0 = 0; MUX3:0 = 0b1100 // Reference = VCC, Measure 1.1V(VBG) bandgap #elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined (__AVR_ATtiny84__) ADMUX = 0b00100001; // REFS1 = 0; REFS0 = 0; MUX5:0 = 0b100001 // Reference = VCC, Measure 1.1V(VBG) bandgap #elif defined(__AVR_ATmega48__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega88__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined (__AVR_ATmega328__) || defined (__AVR_ATmega328P__) ADMUX = 0b01001110; // REFS1 = 0; REFS0 = 1; MUX3:0 = 0b1110 // Reference = AVCC, Measure 1.1V(VBG) bandgap #else #error Unknown CPU type, not implemented. #endif ADCSRA |= _BV(ADEN); // enable the ADC delay(10); // wait for voltages to become stable. ADCSRA |= _BV(ADSC); // Start the ADC while (bit_is_set(ADCSRA, ADSC)); // Wait for conversion to finish. wADC = ADCW; return wADC ? (1.1d * 1023) / wADC : -1; }