Go Down

Topic: Do I need to normalize the response of internal temp sensor by 1.1V Vref? (Read 189 times) previous topic - next topic

GolamMostafa

Aim: Measure and display chip (ATmega328) temperature on 4-digit cc-type 7-segment multiplexed display unit

1.  The data sheet says to use internal 1.1V as Vref for the ADC while measuring the output of the internal temperature sensor.
2.  The data sheet has given the following two-point known responses for the internal temp sensor.
A(VDT1, TT1) = A(0.314V, 250C)
B(VDT2, TT2) = B(0.380V, 850C)
C(VDT, T) = the unknown point to be determined

Here: VDT stands for DC Voltage (response of temperature sensor) when the temperature is T0C.

3. Through algebraic manipulation, I have found the response equation as:
T = 909.0909*VDT - 260.4545

4. Now, I need to transform VDT from decimal (analog) domain into Binary (Hex = compact form of Binary) domain. I have the following options:
(a)  VDT = 5*VHT/10231024     where: 5 is the Vref = 5V, VHT = ADC value when the input analog is VDT.
(b)  VDT = 1.1*VHT/10231024 where: 1.1 is the Vref = 1.1V, VHT = ADC value when the input analog is VDT.

My question:
Which option out of out 4(a) and 4(b) should I use?
Say, I have chosen option 4(b), then should I normalize the responses of A(0.314V, 250C) and B(0.380V, 850C) with respect to 1.1V?


GolamMostafa

Quote
The divisor is 1024.
OK! To remain in compliance with Atmel data sheets.

Jiggy-Ninja

It's helpful if you don't call a variable V when it doesn't represent a voltage.

You're doing this backwards. Instead of converting ADC counts to voltages, you should be converting the voltages to ADC counts based on your chosen reference (1.1V). In other words, use formula (b) but solve for VHT instead of VDT.

That lets you use the datasheet's recommended equation T = (ADC - TOS)/k. You can calculate values for TOS and k based on the nominal 1.1V reference and the typical sensor outputs in Table 28-2, but the tolerance on those values is pretty bad. If you need accurate results, you will have to do a two point calibration in order to measure appropriate values for TOS and k, but it would be better to just get an external temperature sensor anyway.

Only very rarely is the voltage on the ADC input the actual value of interest. Most of the time it is a proxy for some other quantity, like temperature, pressure, or light intensity. The sensor circuitry converts the measurement to a voltage, and the ADC converts the voltage to a digital number. The voltage is an uninteresting intermediate stage that should be factored out of the equation as much as possible, so you can arrange a function to directly convert the ADC result to the quantity of interest. That's how the datasheet's formula was created.
Hackaday: https://hackaday.io/MarkRD

GolamMostafa

Quote
It's helpful if you don't call a variable V when it doesn't represent a voltage.
The closest alternative symbolic names to me (in lieu of VHT) : ADCHT or ADCT. I think that I will use ADCT to mean ADC value (output binary value of ADC) when the ambient temperature is T. Do you have any suggestion?

//----------------------------------------------------------------------------------------------------------

I am going through the rest of your message, and I am finding it increasingly interesting and encouraging. I will do some experiments to clear up some of the conceptual things of your post/the data sheet.

//----------------------------------------------------------------------------------------------------------

Thank you for the reply and expecting more in due time.

Smajdalf

The divisor is 1024.
Again this stupid pedantic nonsense.
MUCH more important are other errors.
If Vref is Vcc it may be anything between 5.5V and 4.5V (or even wider ofc). The 1.1 V voltage reference is 1.1 nominal. It should be somewhat stable but it is NOT callibrated. Once I measured it on my ATMega and it was 1.082V (if you trust my DMM). Worst of all is the temp sensor which is ABOUT 1mV/°C and +/-10°C (according the datasheet). It's funny you point at source of up to 1‰ error and not all those other much more important problems.
And I also forgot to mention inaccuracy of the ADC itself which is also more important than the "right" divisor.
On 8-bit (i.e. Uno) use "byte" instead of "int" if possible - it is faster and saves resources!

GolamMostafa

Quote
You're doing this backwards. Instead of converting ADC counts to voltages, you should be converting the voltages to ADC counts based on your chosen reference (1.1V). In other words, use formula (b) but solve for VHT instead of VDT.
The implementation of the above statement has lead to arrive at the right conclusion that no normalization is required on the given response points (Table-28.2 of data sheet) of the sensor:

1. Based on response points of Table-28.2 (A(VDT1, T1) = A(0.314V, 250C); B(VDT2, T2) = B(0.380V, 850C); and C(VDT, T) = the unknown point to be determined), we have response equation as:

T = 909.0909*VDT - 260.4545  (Original Post)-----------------------------------------(1)

2. Replacing VDT by 1.1*ADCT/1024, we get:

T = 909.0909*1.1*(1/1024)*ADCT - 260.4545
==> T =  0.9765*ADCT - 260.4545 ------------------------------------------------(1A)
==> T*104 = 9765*ADCT - 2604545
==> T*104 =  2625h * ADCT - 27BE01h  ---------------------(2)

The above equation (2) agrees with the following equation (3) what the data sheet (Page-316) has said:

T = {[ADCH<<8)|ADCL] - TOS}/k
==> T = (ADCT - TOS)/k
==> T = k-1*ADCT - k-1*TOS --------(3)

Here:
k-1 = fixed co-efficient (gain of the system) = 2625h from Egn.(2).
k-1*T0S = fixed co-efficient*temperature sensor offset (offset of the system) = 27BE01h from Eqn.(2).

3. Validity check of Eqn.(2) for 850C by substitution:
Table-28.2 of data sheet has shown that at 850C temperature, the temperature sensor produces VDT = 380 mV. From this VDT, we get:
ADCT = 0.380*1024*/1.1 =~ 353.745 =~ 0162h.

After putting the value of ADCT in Eqn.(2), we get:
T*104 =  2625h * 0162h - 27BE01h
==> T*104 =  34BF2Ah - 27BE01h
==> T*104 =  D0129h
==> T*104 =  8522650C

==> T = 85.22650C         (proved)

4. The next job is to make the real measurement using Arduino UNO and see that the display shows sensible result indicating the internal temperature of the ATmega328 within +/- 100C.

Jiggy-Ninja

The derivation looks correct.

I will note for completeness's sake that 1 check is not enough to check a linear equation like this. If you check just one point, there is a chance that you picked the one point shared between the real function and the improperly calculated one. 2 points are needed to uniquely specify a line, so you need to test two points here.

Calculated with the (25, 0.314) point gives a result of 24.6835, so I looks like that equation is correct.

The (-45, 0.242) point gives a result of -40.7, so it looks like the sensor deviates from linear at lower temperatures. And indeed, when I graph the 3 points they do not form a perfectly straight line.  Unfortunately the datasheet does not have a graph with the temperature sensor output fully characterized, so the best you could do is a piecewise conversion function. Use one equation when the temperature is above 25, and another when it's below.

The datasheet only promises +/- 10oC accuracy for the temperature measurement. It's not meant to be good, it's just meant to be in the ballpark. If temperature is an important variable for your project (like for environment monitoring or process control), you should use an external sensor IC. Even an LM35 has more than 10x better accuracy.
Hackaday: https://hackaday.io/MarkRD

GolamMostafa

First of all, thanks for availing the opportunity  to pick up the fragrances of pleasure by doing the remaining 2-point checks which were, in fact, my job.

I have made a test run of the measurement process using the equation T =  0.9765*ADCT - 260.4545 and the Serial Monitor; the read out is about 79.170C. The room temperature is about 270C. When I put my fingers over the chip, the temperature seems to be changing!

The ATmega328's internal temperature measurement task is a part of a larger demonstrative project of ATmega328 based System Design using Arduino UNO of the 140 senior level students of electrical engineering. The aim of the project:

1. Observe the limitation of the Arduino in its inability to access ADC Channel-8 for internal temperature.

2. Compute 32-bit fixed point (amplified) temperature signal.

3. Converting 32-bit Binary temperature into equivalent BCD temperature by Horner Rule. Development of bcd adjustment algorithm for correcting incorrect BCD number into correct BCD number.

4. Converting BCD temperature into cc-coded temperature, and finally

5.  Transferring the cc-coded temperature onto 4-digit multiplexed type 7-segment display unit at 3-sec interval.

As a demonstrator, I assist the students!

Once the projects are done by the students, I will post the photos in this thread, if allowed.

Any suggestion in respect of alternative ways/methods/algorithms for realizing the project would be highly appreciated!

Jiggy-Ninja

First of all, thanks for availing the opportunity  to pick up the fragrances of pleasure by doing the remaining 2-point checks which were, in fact, my job.
I think you reached a little too far there for a fancy compliment. A "fragrance" typically refers to a nice smell, like flowers or perfume. "Fragrances of pleasure" sounds a bit erotic.

Most of the time I can understand the meaning of your broken English, but this one is just weird.
Quote
I have made a test run of the measurement process using the equation T =  0.9765*ADCT - 260.4545 and the Serial Monitor; the read out is about 79.170C. The room temperature is about 270C. When I put my fingers over the chip, the temperature seems to be changing!
Did you type that number incorrectly? 50 degrees of error is way too much.

How are you reading the temperature sensor? If you are doing analogRead(8), it won't work. Here are some lines pulled from the analogRead() function in the core:
Code: [Select]
if (pin >= 14) pin -= 14; // allow for channel or pin numbers
  ...
ADMUX = (analog_reference << 6) | (pin & 0x07);

The subtraction allows the symbols A0-A5 (defined as digital pins 14-19) to be used in analogRead(), so that A0 becomes channel 0, A1 becomes channel 1, etc. This part only gets in the way of trying to set the internal reference as the input, since that's channel 14. And it's easy to work around, since you can just add A0 to the intended channel number and it will be subtracted out. The temp sensor is channel 8, so it won't be affected by this. Just be aware that it's there.

It's the second line that's the real problem. It is the one thing in the Arduino core that I can say legitimately infuriates me. Masking the pin channel with 0x7 means that no matter what argument you pass into the function, only channels 0-7 can be selected. The temperature sensor (channel 8), the internal reference (channel 14, useful for trying to measure the Arduino's own supply voltage), and GND (channel 15) are impossible to select with analogRead().

Because the channel selection is masked, if you use the statement analogRead(8), you are actually selecting channel 0, which is pin A0. Since you've probably got that unconnected for this test, the reading will be pretty random.

If you are properly selecting the temperature input, then you might have a controller with a internal reference on the lower end of the tolerance range, and a temperature sensor reading higher than average.

Quote
Once the projects are done by the students, I will post the photos in this thread, if allowed.
Photos are definitely allowed.

Quote
Any suggestion in respect of alternative ways/methods/algorithms for realizing the project would be highly appreciated!
If the aim is to explore the limitations of the method itself and not just the Arduino software, a good exercise could be to have the students all share their results with each other, or have a few groups share them with you to write them up on a whiteboard, so they can see how the results vary over multiple chips and get a better idea of how rough and imprecise this sensor really is.

If resources allow it, another phase of the activity can be to use a more accurate external reference to see if that improves the results. Calculations can be made about how much inaccuracy is from the internal reference and how much is from the temperature sensor.

The datasheet doesn't say, but I'm pretty sure the temperature sensor is just a few diodes in series with a current source, like this diagram from a PIC datasheet:


That could lead into a discussion of what better ways might exist to measure temperature, such as an NTC resistor or a thermocouple.
Hackaday: https://hackaday.io/MarkRD

Go Up