readinternaltemp - is there a bug? Are RAW_L and _H swapped?

AllyCat

Senior Member
Hi,

I'm aware that readinternaltemp cannot give the accuracy of a dedicated sensor (of any type) and that IMHO Microchip made a silly mistake in "hanging" the sensing diodes from the supply rail (so the FVR cannot be used to eliminate supply voltage variations), instead of referencing them to ground. However, for a measurement in my current project I would like to compensate for the (temperature-varying) voltage drop of an external diode. Since neither this diode nor the PICaxe will dissipate any significant power (i.e. negligible self-heating) they should track reasonably well, so it "should" be possible to achieve around an order of magnitude improvement. However, I can't get any "sensible" results from readinternaltemp. :(

My original prototype used a 3 volt rail (2 x AA cells), but IT_3V0 produced a "temperature" of about 6200 (which wasn't particularly plausible even when truncated to a single byte). IT_RAW_L produced a value in the 300s which implies about one volt drop across each diode (instead of the expected 600 - 700 mV each). :confused:

So I created a basic test program and changed to a 3 cell supply (4.25 volts) to allow _H, _L , _4V0 and _4V5 all to be tested (with a 20M2 and PE 5.5.6). Now, the basic value (using IT_4V5) seems reasonable (provided the high byte of the word is ignored) but the RAW values still look "wrong". Using _L should give around 725 (two diode drops below the supply rail, e.g. 1023 - 300) and _H around 450 (four diode drops below the supply rail), but they almost appear exchanged.

Furthermore, when I put the breadboard into the freezer for an hour or two (say -20 degrees C, compared with the current room temperarure of +25 degees C), the "temperature" fell by only about 15 degrees. Also, both _L and _H fell by hardly more than 2mV/degC (compared with the expected 3-4 and 7-8 mV/degC of 2/4 diodes). Here's my test code with typical results pasted below. Am I doing something wrong?
Code:
#picaxe 20m2
#no_data

do
	readinternaltemp it_4v0,0,w0
	readinternaltemp it_4v5,0,w4
	readinternaltemp it_raw_L,0,w1
	readinternaltemp it_raw_H,0,w2	
	calibadc10 w3
	sertxd(#w0," ",#w4," ",#b0," ",#w1," ",#w2," ",#w3,cr,lf)
	pause 1000
loop

#rem  4.25v supply
4v0 4v5 b0  _L  _H adc10

283 271 27 557 736 248  Room Temperature ~ 25 degC
267 253 11 541 716 250  From Freezer  ~ -20 degC
281 269 25 554 733 248  Warm again
.
Thanks, Alan.
 

g6ejd

Senior Member
Isn't there a heating effect of power to/from the CPU? I get the same thing with the Arduino chip, I just use it to measure CPU temp.
 

hippy

Technical Support
Staff member
The IT_RAW_L and IT_RAW_H seem to be the correct way round to me; _H uses four diodes so has a greater range of change than _L which uses two and that seems to be what you observe.

The values you are seeing seem reasonable for room temperature, but the change at -20C seem less than would be expected but are you sure the temperature of the chip is actually -20C ?

I think the main issue is that you are expecting a particular change per degree C and that is not the case; each PIC has to be calibrated to determine what the actual change is. The offset and slope of any reading changes depending on chip and voltage.

The IT_xVy options were never designed for negative temperatures so this could be the issue with the readings you are seeing as a result of overflow in the maths.
 

AllyCat

Senior Member
Hi hippy,

Thanks for your reply. Yes, I am confident that the chip did get down to around -20 degrees C. My freezer thermometer says -22 degrees, the results were the same whether the PICaxe was in the freezer for one hour or two and it took around 20 minutes to get back near to room temperature.

Perhaps I should have linked to the Microchip Application Note AN1333 (and of course the relevant PIC base chip data sheet) in my first post. In particular the AN (and data sheet) say:

The output equations for the two modes of operation:
• Low range
Vtemp = VDD – 2*Vt
• High range
Vtemp = VDD – 4*Vt
Where:
Vtemp is the analog voltage output by the indicator


AFAIK, it's not directly specified in the PICaxe data/manuals, but I assume that the "IT_RAW" values are intended to present 10-bit A/D values, using a Vdd to Vss reference voltage, with either the "Low" or "High" temperature sensors connected. The AN quotes a typical temperature coefficient of each "diode" as -1.32 mV/degC, which is rather less (but not greatly so) than the normal "rule of thumb" value of minus 1.7 - 2.0 mV/degC assumed for most types of silicon diode/transistor Vbe. etc. It also implies that this slope (but not the offset) should be reasonably consistent between samples.

There are other possibly relevant items in the AN, but I decided it would be more productive to emulate the readinternaltemp command by direct SFR commands. My code is listed below, which I believe conclusively proves that the RAW_L and RAW_H values ARE exchanged. I've also added the 3V0 test which produced my original crazy values, perhaps because it's using the High sensor at an "illegal" voltage?

Code:
#picaxe 20m2
#no_data
symbol ADRESL = $3b		; A-D converter
symbol ADRESH = $3c
symbol ADCON0 = $3d
symbol ADCON1 = $3e
symbol FVRCON = $57		; Includes Temperature sensor TSEN & TSRNG flags

do
pokesfr ADCON1, %10010000 	; Right justify;clock/8; REF=Vdd to Vss
pokesfr FVRCON, %00100000	; Enable Temperature sensor with 2 diodes
pokesfr ADCON0, %01110100 	; Select Temperature input
pokesfr ADCON0, %01110101  	; Turn ADC On
pokesfr ADCON0, %01110111 	; Start conversion
pause 1
peeksfr ADRESH,b3 		; Read upper byte
peeksfr ADRESL,b2 		; Read Low byte

pokesfr FVRCON, %00110000	; Enable Temperature sensor with 4 diodes
pokesfr ADCON0, %01110111 	; Start conversion
pause 1
peeksfr ADRESH,b5 		; Read upper byte
peeksfr ADRESL,b4			; Read lower byte

	readinternaltemp it_raw_L,0,w3
	readinternaltemp it_raw_H,0,w4
	readinternaltemp it_4v0,0,w5
	readinternaltemp it_4v5,0,w6
	readinternaltemp it_3v0,0,w7	
	calibadc10 w0
	sertxd(#w0," ",#w1," ",#w2," ",#w3," ",#w4," ",#w5," ",#w6," ",#w7,cr,lf)
	pause 1000
loop

#rem  4.32v supply

Vdd ADL ADH ITL ITH 4v0 4v5 3v0

246 738 441 441 738 285 272 6323  26 degrees C

247 717 399 399 717 268 254 6264   ~ -20 degrees C
248 717 399 398 717 268 254 6264
248 717 399 399 717 268 254 6264
248 717 399 399 717 268 254 6264
248 717 399 399 717 268 254 6264
248 717 399 399 717 268 254 6264
Interestingly, these results are much "better" (more revealing) than in my first post. The "High" (4 diode) drop of 582 (1023 - 441) below the supply rail is about twice the "Low" (2 diode) drop of 285 (1023 - 738) and the voltage rise when put in the freezer is twice as large for 4 diodes than 2 (42 versus 21). Note that the 3 volt measurement is over-estimating the temperature change (because it's reading 4 diodes?) whilst the 4V are under-reading (using only 2 diodes?).

I can't be certain why these results are now much more "as expected", but my new code above does specifically disable the FVR so it may be that the readinternaltemp code is also not initialising the A-D converter reference correctly.

Cheers, Alan.
 

hippy

Technical Support
Staff member
Thanks for the efforts you have put in and we will have to look into the issue further.

The IT_3V0 result appears to be that the IT_RAW_L value is too low for the equation being applied -

temperature = IT_RAW_L - 609 * 14 / 10 + 5

With IT_RAW_L value less than 609 that goes negative so becomes a large positive number, and the *14 causes a further overflow.
 

AllyCat

Senior Member
Thanks hippy,

Yes, looking again at the 3V0 (and other) equations, they really are't very "clever". They could be more simply rewritten as, for example:

temperature = IT_RAW_L - 606 * 14 / 10, or (like many temperature sensors) referenced to -40 degrees (which of course is conveniently the same in degrees C and F) as:

temperature = IT_RAW_L - 641 * 14 / 10 + 40. Or go the whole hog to:

temperature = IT_RAW_L * 14 / 10 - 848 to handle all temperatures within the PIC's range. I presume that these are just a macro in the PE Compilier (which can be corrected), not in the PICaxe Interpreter (since I see the xVx parameter takes more program space than the RAW parameter) .

However, IMHO the algorithm really ought to compensate for the supply voltage even (or particularly) for an "over-temperature protection" application, rather than rely on a "guess" of the supply voltage by the programmer. If the PICaxe is dissipating a "dangerous" amount of power, then the supply rail might well be "wrong" anyway, either over-voltage (causing the high dissipation) or perhaps "sagging" due to excessive current drain. However, I guess that the amount of scratchpad/workspace available to the "PE macros" must be very limited (judging by the amount of program space consumed by a command as simple as "Swap").

Here's my latest attempt, but not fully checked for potential overflows, etc.. The gradient (I've used 1.32mV/degC) seems similar to that in the original equations, now gives negative results, but still doesn't seem to get as low as my freezer thermometer claims. I've removed most of my SFR checking code, but writing the "4-diode" configuration to FVRCON seems to be essential to get the correct RAW_H value (currently being written into RAW_L, w3).

Code:
#picaxe 20m2
#no_data
symbol ADRESL = $3b		; A-D converter
symbol ADRESH = $3c
symbol ADCON0 = $3d
symbol ADCON1 = $3e
symbol FVRCON = $57		; Includes Temperature sensor TSEN & TSRNG flags

do
;pokesfr ADCON1, %10010000 	; Right justify;clock/8; REF=Vdd to Vss
;pokesfr FVRCON, %00100000	; Enable Temperature sensor with 2 diodes
;pokesfr ADCON0, %01110100 	; Select Temperature input
;pokesfr ADCON0, %01110101  	; Turn ADC On
;pokesfr ADCON0, %01110111 	; Start conversion
;peeksfr ADRESH,b3 		; Read upper byte
;peeksfr ADRESL,b2 		; Read Low byte

pokesfr FVRCON, %00110000	; Enable Temperature sensor with 4 diodes THIS IS ESSENTIAL FOR CORRECT W3 !
;												**********************************
;pokesfr ADCON0, %01110111 	; Start conversion
;peeksfr ADRESH,b5 		; Read upper byte
;peeksfr ADRESL,b4		; Read lower byte

	readinternaltemp it_raw_L,0,w3	; ACTUALLY READS RAW_H
	readinternaltemp it_raw_H,0,w4	; ACTUALLY READS RAW_L
	readinternaltemp it_4v0,0,w5		; ********************

	calibadc10 w0

	w0 = w0 + 2 / 4		; Round and scale down the supply voltage (or just use calibadc (8 bits))
	w6 = 1023 - w4 * 97	; With 4.1v supply rail: 97 = 4 (mV/step) / 2.64 (mV/degC) * 64 (calibadc)
	w7 = w6 / w0		; Correct for the Supply voltage
	b16 = 477 - w7		; Negate and Subtract Diode Offset Voltage (empirically) 

	w9 = 1023 - w3 * 49	; With 4.1v supply rail: 49 = 4 (mV/step) / 5.28 (mV/degC) * 64 (calibadc)
	w10 = w9 / w0 		; Correct for the Supply voltage
	b17 = 490 - w10		; Negate and subtract Diode Offset Voltage 

	sertxd(#w0," ",#w1," ",#w2," ",#w3," ",#w4," ",#w5," ",#w6," ",#w7," ",#b16," ",#w9," ",#w10," ",#b17,cr,lf)
	pause 1000
	
loop

#rem   Sample output at room temperature

60 0 0 454 744 289 27063 451 26 27881 464 26
60 0 0 455 744 289 27063 451 26 27832 463 27
60 0 0 454 744 289 27063 451 26 27881 464 26
Cheers, Alan.
 

humphpicaxe

New Member
I guess this explains why, when I run an 08M2+ at room temp I get these rather crazy values:
actual supply 4.6 3.0
readinternaltemp IT_5V0, 0, b10 ...240 87
readinternaltemp IT_4V5, 0, b9 ...7 131
readinternaltemp IT_4V0, 0, b8 ...20 166
readinternaltemp IT_3V5, 0, b7 ...200 142
readinternaltemp IT_3V0, 0, b6 ...27 225

other chips give with 10% of these values.
 

AllyCat

Senior Member
Hi,

I believe the "bug" (reversed Hi and Lo RAW values) was (and still is) in PE5, but that particular aspect has been fixed in PE6.

However, IMHO the (PIC hardware) temprature detection method is fundamentally unsound, at least when using an unregulated power supply. The tempco is also remarkably low (less than that of a single forward diode) which makes it difficult to get even a moderate resolution, let alone any useful accuracy.

One of the (many) items on my "to do list" is to (try to) get "usable" temperature measurements from the chip hardware (probably using mainly SFR accesses), but don't hold your breath. ;)

Cheers, Alan.
 
Top