chipKIT® Development Platform

Inspired by Arduino™

internal sensors

Created Thu, 30 Apr 2015 07:21:11 +0000 by GastonLagaffe


GastonLagaffe

Thu, 30 Apr 2015 07:21:11 +0000

Salut,

the AVR chip used with the Arduino offers the values of the chip temperature and voltage:

double readTmp()
{
	// Read temperature sensor against 1.1V reference
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284P__)
	return -274.0;
#elif defined(__AVR_ATmega32U4__)
	ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0);
	ADCSRB = _BV(MUX5); // the MUX5 bit is in the ADCSRB register
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
	ADMUX = _BV(REFS1) | _BV(MUX5) | _BV(MUX1);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
	ADMUX = _BV(REFS1) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0);
#else
	ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX3);
#endif
	delay(20); // Wait for ADMUX setting to settle
	ADCSRA |= _BV(ADSC); // Start conversion
	while (bit_is_set(ADCSRA,ADSC)); // measuring
	uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
	uint8_t high = ADCH; // unlocks both
	long result = (high << 8) | low; // combine the two
	return (result - 324.31 ) / 1.22;
}

long readVcc()
{
	// Read 1.1V reference against AVcc
	// set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
	ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
	ADMUX = _BV(MUX5) | _BV(MUX0) ;
#else
	ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
	delay(2); // Wait for Vref to settle
	ADCSRA |= _BV(ADSC); // Start conversion
	while (bit_is_set(ADCSRA, ADSC)); // measuring
	uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
	uint8_t high = ADCH; // unlocks both
	long result = (high << 8) | low;
	result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
	return result; // Vcc in millivolts
}

Just out of curiosity: Is there a similar code available for the PIC32 family? I was not able to find something in the reference manuals.

Ciao, Mathias


majenko

Thu, 30 Apr 2015 08:59:23 +0000

I don't believe the PIC32 has an internal temperature sensor. The chip self-heats too much for an internal sensor to be of any use as an ambient sensor, but doesn't self-heat enough to need any thermal monitoring of its own, so an internal temperature sensor would be a pointless extravagance. The same with an internal reference voltage for the ADC (besides the normal AVcc/AVss pair) - the internal "core" voltage isn't stable enough for reliable ADC readings - the core creates lots of noise on it - and it's expected that if you want anything on than 3.3V (or whatever your supply voltage is) then you'd provide your own stable Vref+ and Vrfef- signals from a reliable source.

The internal 1.1V reference on the Atmel is only "roughly" 1.1V - it could actually be anywhere between 1.0V and 1.2V.


GastonLagaffe

Thu, 30 Apr 2015 11:06:00 +0000

Salut,

thanks for the reply - I was just curious and I use the internal sensors often as dummy data feeds.

Ciao, Mathias


GrahamM242

Fri, 01 May 2015 09:47:40 +0000

You could however use either the CVREF or IVREF outputs as an input for the ADC if you're desperate.