Jump to content
oPossum

Using the internal temperature sensor

Recommended Posts

TI has some sample code for the internal temperature sensor, but it does not explain how to scale the ADC reading to useful units of degrees. Here is a step-by-step explanation of how to do the scaling with integer math for degrees C, K and F. There is also sample code to display the temperature on a Nokia 5110 LCD.

post-2341-135135543065_thumb.jpg

 

The data sheet (SLAU144) has this formula for converting temperature in degrees Celsius to voltage.

V = 0.00355 * C + 0.986

post-2341-135135543051_thumb.png

What we need is a formula for converting voltage to temperature.

 

Rewrite the data sheet fomula with temperature on the left

0.00355 * C + 0.986 = V

 

Divide both sides by 0.00355

C + 277.75 = V / 0.00355

 

Subtract 277.75 from both sides

C = V / 0.00355 - 277.75

 

Now we have a formula for converting voltage to temperature.

 

The data sheet has this formula for converting voltage to ADC value, once again the opposite of what we neeed.

post-2341-135135543061_thumb.png

For Vref- == 0

A = 1023 * V / Vref

 

Swap sides

1023 * V / Vref = A

 

Multiply by Vref

1023 * V = A * Vref

 

Divide by 1023

V = A * Vref / 1023

 

For a 1.5V reference

V = A * 1.5 / 1023

 

Simplify

V = A * 0.0014663

 

Substitute ADC conversion forumula for voltage in the temperature conversion formula.

C = A * 0.0014663 / 0.00355 - 277.75

 

Simplify

C = A * 0.413 - 277.75

 

Now we have a formula to convert ADC reading to temperature.

It uses real numbers, so floating point math is required for good precision.

Floating point is slow and requires more flash, so let's use integer math instead.

Multiply by 65536 (2^16) and then divide by the same.

C = (A * 27069 - 18202393) / 65536

 

Use a right shift instead of divide. This will become a move of high word to low word.

C = (A * 27069 - 18202393) >> 16

 

Add 0.5 * 65536 to impove rounding.

C = (A * 27069 - 18202393 + 32768) >> 16

 

Simplify.

C = (A * 27069 - 18169625) >> 16

 

So that is how to go from ADC to degrees Celsius.

 

 

To convert degrees C to degees K.

K = C + 273.15

 

Applied to ADC to degrees C conversion formula.

K = (A * 27069 - 18169625) >> 16 - 273.15

 

Implement with integer math by multiplying by 65536

K = (A * 27069 - 18169625 - 17,901,158) >> 16

 

Simplify.

K = (A * 27069 - 268467) >> 16

 

To convert degrees C to degrees F.

F = C * 9 / 5 + 32

 

Applied to voltage to degrees C conversion forumula

F = (V / 0.00355 - 277.75) * 9 / 5 + 32

 

Multiply by 9

F = (V / 0.0003944 - 2499.75) / 5 + 32

 

Divide by 5

F = (V / 0.0019722 - 499.95) + 32

 

Add 32

F = V / 0.0019722 - 467.95

 

Substitute ADC to voltage forumula

F = A * 0.0014663 / 0.0019722 - 467.95

 

Simplifiy

F = A * 0.7435 - 467.95

 

Convert to integer

F = (A * 48724 - 30667156) >> 16

 

Improve rounding

F = (A * 48724 - 30667156 + 32768) >> 16

 

Simplify

F = (A * 48724 - 30634388) >> 16

 

So now we have three formulas to convert ADC reading to degrees C, K and F using fast and compact integer math.

C = (A * 27069 - 18169625) >> 16

K = (A * 27069 - 268467) >> 16

F = (A * 48724 - 30634388) >> 16

 

Using the ADC value, rather than a different temperature scale, will ensure greatest precision for each temperature scale.

 

main.c

#include 
#include 
#include "lcd.h"

#define ADC_SLEEP       // Sleep during ADC conversion
//#define SHOW_ADC      // Show ADC raw and ADC millivolts

// Print integer from -999 to 9999 using 12 x 16 font
void print_int(int i, const unsigned y)
{
   if(i < -999 || i > 9999) return;
   const unsigned neg = i < 0;
   if(neg) i = -i;
   div_t d; d.quot = i;
   unsigned x = 48;
   do {
       d = div(d.quot, 10);
       pd12(d.rem, x -= 12, y);
   } while(d.quot);
   if(neg) pd12(14, x -= 12, y);
   while(x) pd12(10, x -= 12, y);
}

// Print integer from 0 to 9999 vertically using 6 x 8 font
void print_v(int i, unsigned x)
{
   unsigned y = 4;
   unsigned c;
   if(i < 0 || i > 9999) return;
   div_t d; d.quot = i;
   do {
       d = div(d.quot, 10);
       c = d.rem + '0';
       lcd_print((char *)&c, x, --y);
   } while(d.quot);
   c = ' ';
   while(y) lcd_print((char *)&c, x, --y);
}

void main(void)
{
   unsigned adc;                                       // ADC value
   int c, k, f;                                        // Temperature in degrees C, K, and F
   unsigned mv;                                        // ADC reading in millivolts
                                                       //
   WDTCTL = WDTPW | WDTHOLD;                           // Disable watchdog reset
                                                       //
   lcd_init();                                         // Initialize LCD
   lcd_clear(0);                                       //
   pd12(15, 48, 0);                                    // Degrees
   pd12(17, 59, 0);                                    // F
   pd12(15, 48, 2);                                    // Degrees
   pd12(16, 58, 2);                                    // C
   pd12(15, 48, 4);                                    // Degrees
   pd12(18, 59, 4);                                    // K
#ifdef SHOW_ADC                                         //
   lcd_print("Am", 72, 4);                             // AD / mV
   lcd_print("DV", 72, 5);                             //
#endif                                                  //
                                                       //
   ADC10CTL0 = 0;                                      // Configure ADC
   ADC10CTL1 = INCH_10 | ADC10DIV_3;                   //
   ADC10CTL0 = SREF_1 | ADC10SHT_3 | REFON | ADC10ON | ADC10IE;
   //ADC10CTL0 = SREF_1 | ADC10SHT_3 | REFON | ADC10ON | ADC10IE | REF2_5V;
#ifdef ADC_SLEEP                                        //
   ADC10CTL0 |= ADC10IE;                               // Enable ADC conversion complete interrupt
#endif                                                  //
                                                       //
   for(; {                                           // for-ever
#ifdef ADC_SLEEP                                        //
       ADC10CTL0 |= (ENC | ADC10SC);                   // Begin ADC conversion
       __bis_SR_register(LPM0_bits + GIE);             // Sleep until conversion complete
#else                                                   //
       ADC10CTL0 &= ~ADC10IFG;                         // Clear conversion complete flag
       ADC10CTL0 |= (ENC | ADC10SC);                   // Begin ADC conversion
       while(!(ADC10CTL0 & ADC10IFG));                 // Wait for conversion to complete
#endif                                                  //
                                                       //
       adc = ADC10MEM;                                 // Read ADC
                                                       //
                                                       // Convert to temperature
       c = ((27069L * adc) -  18169625L) >> 16;        // Vref = 1.5V
       //c = ((45115L * adc) -  18169625L) >> 16;      // Vref = 2.5V
                                                       //
       k = ((27069L * adc) -  268467L) >> 16;          // Vref = 1.5V
       //k = ((45115L * adc) -  268467L) >> 16;        // Vref = 2.5V
                                                       //
       f = ((48724L * adc) -  30634388L) >> 16;        // Vref = 1.5V
       //f = ((81206L * adc) -  30634388L) >> 16;      // Vref = 2.5V
                                                       //
                                                       // Convert to millivolts
       mv = (96094L * adc + 32768) >> 16;              // Vref = 1.5V
       //mv = (160156L * adc + 32768) >> 16;           // Vref = 2.5V
                                                       //
                                                       // Display on LCD
       print_int(f, 0);                                // Degrees F
       print_int(c, 2);                                // Degrees C
       print_int(k, 4);                                // Degrees K
                                                       //
#ifdef SHOW_ADC                                         //
       print_v(adc, 72);                               // ADC
       print_v(mv, 78);                                // ADC millivolts
#endif                                                  //
                                                       //
       //__delay_cycles(100000);                       //
   }                                                   //
}

#pragma vector = ADC10_VECTOR                           // ADC conversion complete interrupt
__interrupt void ADC10_ISR(void)                        //
{                                                       //
   __bic_SR_register_on_exit(LPM0_bits);               // Wakeup main code
}                                                       //

 

lcd.h

typedef enum {
   lcd_command = 0,        // Array of one or more commands
   lcd_data = 1,           // Array of one or more bytes of data
   lcd_data_repeat = 2     // One byte of data repeated
} lcd_cmd_type;

void lcd_send(const unsigned char *cmd, unsigned len, const lcd_cmd_type type);
void lcd_home(void);
void lcd_pos(unsigned char x, unsigned char y);
void lcd_clear(unsigned char x);
void lcd_init(void);
void lcd_print(char *s, unsigned x, unsigned y);
void pd12(unsigned n, unsigned x, unsigned y);

 

lcd.c

#include 
#include "lcd.h"

//static const unsigned TXD = BIT1;
static const unsigned RXD = BIT2;
static const unsigned SWITCH = BIT3;
static const unsigned LCD_CLK = BIT5;
static const unsigned LCD_BACKLIGHT = BIT6;
static const unsigned LCD_DATA = BIT7;

static const unsigned LCD_DC = BIT0;    // PORT2
static const unsigned LCD_CE = BIT1;    // PORT2

void lcd_send(const unsigned char *cmd, unsigned len, const lcd_cmd_type type)
{
   register unsigned mask;

   P2OUT &= ~LCD_CE;
   do {
       mask = 0x0080;
       do {
           if(*cmd & mask) {
               P1OUT &= ~LCD_CLK;
               P1OUT |= LCD_DATA;
           } else {
               P1OUT &= ~(LCD_CLK | LCD_DATA);
           }
           P1OUT |= LCD_CLK;
           mask >>= 1;
       } while(!(mask & 1));
       if(!type) P2OUT &= ~LCD_DC;
       if(*cmd & mask) {
           P1OUT &= ~LCD_CLK;
           P1OUT |= LCD_DATA;
       } else {
           P1OUT &= ~(LCD_CLK | LCD_DATA);
       }
       P1OUT |= LCD_CLK;
       P2OUT |= LCD_DC;
       if(!(type & 2)) ++cmd;
   } while(--len);
   P2OUT |= LCD_CE;
}

static const unsigned char home[] = { 0x40, 0x80 };

void lcd_home(void)
{
   lcd_send(home, sizeof(home), lcd_command);
}

void lcd_pos(unsigned char x, unsigned char y)
{
   unsigned char c[2];
   c[0] = 0x80 | x;
   c[1] = 0x40 | y;
   lcd_send(c, sizeof(c), lcd_command);
}

void lcd_clear(unsigned char x)
{
   lcd_home();
   lcd_send(&x, 504, lcd_data_repeat);
   lcd_home();
}

void lcd_init(void)
{
   static const unsigned char init[] = {
       0x20 + 0x01,    // function set - extended instructions enabled
       //0x80 + 64,    // set vop (contrast) 0 - 127
       0x80 + 66,    // set vop (contrast) 0 - 127
       0x04 + 0x02,    // temperature control
       0x10 + 0x03,    // set bias system
       0x20 + 0x00,    // function set - chip active, horizontal addressing, basic instructions
       0x08 + 0x04     // display control - normal mode
   };

   P1REN = RXD | SWITCH;
   P1DIR = LCD_CLK | LCD_BACKLIGHT | LCD_DATA;
   P1OUT = LCD_CLK | RXD | SWITCH | LCD_BACKLIGHT;

   P2REN = 0;
   P2DIR = LCD_DC | LCD_CE;
   P2OUT = LCD_CE;

   __delay_cycles(20000);
   P2OUT |= LCD_DC;
   __delay_cycles(20000);

   lcd_send(init, sizeof(init), lcd_command);
}

static const unsigned char font6x8[96][5] = {
   0x00, 0x00, 0x00, 0x00, 0x00, // 20  32   
   0x00, 0x00, 0x5F, 0x00, 0x00, // 21  33   !
   0x00, 0x07, 0x00, 0x07, 0x00, // 22  34   "
   0x14, 0x7F, 0x14, 0x7F, 0x14, // 23  35   #
   0x24, 0x2A, 0x7F, 0x2A, 0x12, // 24  36   $
   0x23, 0x13, 0x08, 0x64, 0x62, // 25  37   %
   0x36, 0x49, 0x56, 0x20, 0x50, // 26  38   &
   0x00, 0x08, 0x07, 0x03, 0x00, // 27  39   '
   0x00, 0x1C, 0x22, 0x41, 0x00, // 28  40   (
   0x00, 0x41, 0x22, 0x1C, 0x00, // 29  41   )
   0x2A, 0x1C, 0x7F, 0x1C, 0x2A, // 2A  42   *
   0x08, 0x08, 0x3E, 0x08, 0x08, // 2B  43   +
   0x00, 0x40, 0x38, 0x18, 0x00, // 2C  44   ,
   0x08, 0x08, 0x08, 0x08, 0x08, // 2D  45   -
   0x00, 0x00, 0x60, 0x60, 0x00, // 2E  46   .
   0x20, 0x10, 0x08, 0x04, 0x02, // 2F  47   /
   0x3E, 0x51, 0x49, 0x45, 0x3E, // 30  48   0
   0x00, 0x42, 0x7F, 0x40, 0x00, // 31  49   1
   0x42, 0x61, 0x51, 0x49, 0x46, // 32  50   2
   0x21, 0x41, 0x49, 0x4D, 0x33, // 33  51   3
   0x18, 0x14, 0x12, 0x7F, 0x10, // 34  52   4
   0x27, 0x45, 0x45, 0x45, 0x39, // 35  53   5
   0x3C, 0x4A, 0x49, 0x49, 0x30, // 36  54   6
   0x41, 0x21, 0x11, 0x09, 0x07, // 37  55   7
   0x36, 0x49, 0x49, 0x49, 0x36, // 38  56   8
   0x06, 0x49, 0x49, 0x29, 0x1E, // 39  57   9
   0x00, 0x00, 0x14, 0x00, 0x00, // 3A  58   :
   0x00, 0x00, 0x40, 0x34, 0x00, // 3B  59   ;
   0x00, 0x08, 0x14, 0x22, 0x41, // 3C  60   <
   0x14, 0x14, 0x14, 0x14, 0x14, // 3D  61   =
   0x00, 0x41, 0x22, 0x14, 0x08, // 3E  62   >
   0x02, 0x01, 0x51, 0x09, 0x06, // 3F  63   ?
   0x3E, 0x41, 0x5D, 0x59, 0x4E, // 40  64   @
   0x7C, 0x12, 0x11, 0x12, 0x7C, // 41  65   A
   0x7F, 0x49, 0x49, 0x49, 0x36, // 42  66   B
   0x3E, 0x41, 0x41, 0x41, 0x22, // 43  67   C
   0x7F, 0x41, 0x41, 0x41, 0x3E, // 44  68   D
   0x7F, 0x49, 0x49, 0x49, 0x41, // 45  69   E
   0x7F, 0x09, 0x09, 0x09, 0x01, // 46  70   F
   0x3E, 0x41, 0x49, 0x49, 0x7A, // 47  71   G
   0x7F, 0x08, 0x08, 0x08, 0x7F, // 48  72   H
   0x00, 0x41, 0x7F, 0x41, 0x00, // 49  73   I
   0x20, 0x40, 0x41, 0x3F, 0x01, // 4A  74   J
   0x7F, 0x08, 0x14, 0x22, 0x41, // 4B  75   K
   0x7F, 0x40, 0x40, 0x40, 0x40, // 4C  76   L
   0x7F, 0x02, 0x1C, 0x02, 0x7F, // 4D  77   M
   0x7F, 0x04, 0x08, 0x10, 0x7F, // 4E  78   N
   0x3E, 0x41, 0x41, 0x41, 0x3E, // 4F  79   O
   0x7F, 0x09, 0x09, 0x09, 0x06, // 50  80   P
   0x3E, 0x41, 0x51, 0x21, 0x5E, // 51  81   Q
   0x7F, 0x09, 0x19, 0x29, 0x46, // 52  82   R
   0x26, 0x49, 0x49, 0x49, 0x32, // 53  83   S
   0x01, 0x01, 0x7F, 0x01, 0x01, // 54  84   T
   0x3F, 0x40, 0x40, 0x40, 0x3F, // 55  85   U
   0x1F, 0x20, 0x40, 0x20, 0x1F, // 56  86   V
   0x3F, 0x40, 0x38, 0x40, 0x3F, // 57  87   W
   0x63, 0x14, 0x08, 0x14, 0x63, // 58  88   X
   0x03, 0x04, 0x78, 0x04, 0x03, // 59  89   Y
   0x61, 0x51, 0x49, 0x45, 0x43, // 5A  90   Z
   0x00, 0x7F, 0x41, 0x41, 0x41, // 5B  91   [
   0x02, 0x04, 0x08, 0x10, 0x20, // 5C  92   '\'
   0x00, 0x41, 0x41, 0x41, 0x7F, // 5D  93   ]
   0x04, 0x02, 0x01, 0x02, 0x04, // 5E  94   ^
   0x80, 0x80, 0x80, 0x80, 0x80, // 5F  95   _
   0x00, 0x03, 0x07, 0x08, 0x00, // 60  96   '
   0x20, 0x54, 0x54, 0x54, 0x78, // 61  97   a
   0x7F, 0x28, 0x44, 0x44, 0x38, // 62  98   b
   0x38, 0x44, 0x44, 0x44, 0x28, // 63  99   c
   0x38, 0x44, 0x44, 0x28, 0x7F, // 64  100  d
   0x38, 0x54, 0x54, 0x54, 0x18, // 65  101  e
   0x00, 0x08, 0x7E, 0x09, 0x02, // 66  102  f
   0x18, 0xA4, 0xA4, 0xA4, 0x7C, // 67  103  g
   0x7F, 0x08, 0x04, 0x04, 0x78, // 68  104  h
   0x00, 0x44, 0x7D, 0x40, 0x00, // 69  105  i
   0x00, 0x20, 0x40, 0x40, 0x3D, // 6A  106  j
   0x00, 0x7F, 0x10, 0x28, 0x44, // 6B  107  k
   0x00, 0x41, 0x7F, 0x40, 0x00, // 6C  108  l
   0x7C, 0x04, 0x78, 0x04, 0x78, // 6D  109  m
   0x7C, 0x08, 0x04, 0x04, 0x78, // 6E  110  n
   0x38, 0x44, 0x44, 0x44, 0x38, // 6F  111  o
   0xFC, 0x18, 0x24, 0x24, 0x18, // 70  112  p
   0x18, 0x24, 0x24, 0x18, 0xFC, // 71  113  q
   0x7C, 0x08, 0x04, 0x04, 0x08, // 72  114  r
   0x48, 0x54, 0x54, 0x54, 0x24, // 73  115  s
   0x04, 0x04, 0x3F, 0x44, 0x24, // 74  116  t
   0x3C, 0x40, 0x40, 0x20, 0x7C, // 75  117  u
   0x1C, 0x20, 0x40, 0x20, 0x1C, // 76  118  v
   0x3C, 0x40, 0x30, 0x40, 0x3C, // 77  119  w
   0x44, 0x28, 0x10, 0x28, 0x44, // 78  120  x
   0x4C, 0x90, 0x90, 0x90, 0x7C, // 79  121  y
   0x44, 0x64, 0x54, 0x4C, 0x44, // 7A  122  z
   0x00, 0x08, 0x36, 0x41, 0x00, // 7B  123  {
   0x00, 0x00, 0x77, 0x00, 0x00, // 7C  124  |
   0x00, 0x41, 0x36, 0x08, 0x00, // 7D  125  }
   0x02, 0x01, 0x02, 0x04, 0x02, // 7E  126  ~
   0x00, 0x06, 0x09, 0x09, 0x06, // 7F  127 degrees
};

void lcd_print(char *s, unsigned x, unsigned y)
{
   unsigned char c[2];
   c[0] = 0x80 | x;
   c[1] = 0x40 | y;
   lcd_send(c, sizeof(c), lcd_command);
   while(*s) {
       lcd_send(&font6x8[*s - 32][0], 5, lcd_data);
       lcd_send(&font6x8[0][0], 1, lcd_data);
       ++s;
   }
}

static const unsigned char num11x16[19][11 * 2] = {
   0x00,0xF0,0xFC,0xFE,0x06,0x02,0x06,0xFE,0xFC,0xF0,0x00, // 0
   0x00,0x07,0x1F,0x3F,0x30,0x20,0x30,0x3F,0x1F,0x07,0x00,
   0x00,0x00,0x08,0x0C,0xFC,0xFE,0xFE,0x00,0x00,0x00,0x00, // 1
   0x00,0x20,0x20,0x20,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x00,
   0x00,0x0C,0x0E,0x06,0x02,0x02,0x86,0xFE,0x7C,0x38,0x00, // 2
   0x00,0x30,0x38,0x3C,0x36,0x33,0x31,0x30,0x30,0x38,0x00,
   0x00,0x0C,0x0E,0x86,0x82,0x82,0xC6,0xFE,0x7C,0x38,0x00, // 3
   0x00,0x18,0x38,0x30,0x20,0x20,0x31,0x3F,0x1F,0x0E,0x00,
   0x00,0x00,0xC0,0x20,0x18,0x04,0xFE,0xFE,0xFE,0x00,0x00, // 4
   0x00,0x03,0x02,0x02,0x02,0x22,0x3F,0x3F,0x3F,0x22,0x02,
   0x00,0x00,0x7E,0x7E,0x46,0x46,0xC6,0xC6,0x86,0x00,0x00, // 5
   0x00,0x18,0x38,0x30,0x20,0x20,0x30,0x3F,0x1F,0x0F,0x00,
   0x00,0xC0,0xF0,0xF8,0xFC,0x4C,0xC6,0xC2,0x82,0x00,0x00, // 6
   0x00,0x0F,0x1F,0x3F,0x30,0x20,0x30,0x3F,0x1F,0x0F,0x00,
   0x00,0x06,0x06,0x06,0x06,0x06,0xC6,0xF6,0x3E,0x0E,0x00, // 7
   0x00,0x00,0x00,0x30,0x3C,0x0F,0x03,0x00,0x00,0x00,0x00,
   0x00,0x38,0x7C,0xFE,0xC6,0x82,0xC6,0xFE,0x7C,0x38,0x00, // 8
   0x00,0x0E,0x1F,0x3F,0x31,0x20,0x31,0x3F,0x1F,0x0E,0x00,
   0x00,0x78,0xFC,0xFE,0x86,0x02,0x86,0xFE,0xFC,0xF8,0x00, // 9
   0x00,0x00,0x00,0x21,0x21,0x31,0x1D,0x1F,0x0F,0x03,0x00,
   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 
   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
   0x00,0x70,0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // :
   0x00,0x0E,0x0E,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // .
   0x00,0x38,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
   0x00,0x00,0x00,0x00,0xC0,0x30,0x0C,0x00,0x00,0x00,0x00, // /
   0x00,0x30,0x0C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
   0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, // -
   0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
   0x00,0x18,0x3C,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x00, // 
   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
   0xF0,0xF8,0x0C,0x06,0x02,0x02,0x02,0x02,0x0E,0x0C,0x00, // C
   0x03,0x07,0x0C,0x18,0x10,0x10,0x10,0x10,0x1C,0x0C,0x00,
   0xFE,0xFE,0x42,0x42,0x42,0x42,0x42,0x42,0x00,0x00,0x00, // F
   0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
   0xFE,0xFE,0x40,0xE0,0xB0,0x18,0x0C,0x06,0x02,0x00,0x00, // K
   0x1F,0x1F,0x00,0x00,0x01,0x03,0x06,0x0C,0x18,0x10,0x00
};

void pd12(unsigned n, unsigned x, unsigned y)
{
   unsigned char c[2];
   c[0] = 0x80 | x;
   c[1] = 0x40 + y; lcd_send(c, 2, lcd_command);   lcd_send(num11x16[n], 11, lcd_data);
   c[1] = 0x41 + y; lcd_send(c, 2, lcd_command);   lcd_send(num11x16[n] + 11, 11, lcd_data);
}

Share this post


Link to post
Share on other sites

slac467a has these formulas in msp430g2x32_adc10_10.c:

 

    // oF = ((A10/1024)*1500mV)-923mV)*1/1.97mV = A10*761/1024 - 468
   temp = ADC10MEM;
   IntDegF = ((temp - 630) * 761) / 1024;

   // oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278
   temp = ADC10MEM;
   IntDegC = ((temp - 673) * 423) / 1024;

Share this post


Link to post
Share on other sites

TI's code examples seem to have a lot of issues. I did try those formulas in my project before, but since I wasn't getting proper results, ended up using ADC values instead. Now I know it's not just me :)

Share this post


Link to post
Share on other sites

There is no need to use these formulas as there is a more simple way to do such conversion. Simply get the ADC Value for 2 exact temperatures like 0 Celsius and 37 Celsius so we can use Ice as a reference and the temperature of our body :-) then make the equation.

 

I have attached a code that I wrote a while ago, find it attached. Sorry that the comments are in German but I guess the code is so simple that you don't need a translation.

msp430x2xxTemperatur.c

Share this post


Link to post
Share on other sites

Is the result of the temperature calculation dependent on the supply voltage to the MSP430? If so, what supply voltage does this code expect.

 

Using a 2231 on a Launchpad, my calculated temperatures are about 20 degrees F higher than a nearby thermometer.

Share this post


Link to post
Share on other sites
Is the result of the temperature calculation dependent on the supply voltage to the MSP430? If so, what supply voltage does this code expect.

 

Using a 2231 on a Launchpad, my calculated temperatures are about 20 degrees F higher than a nearby thermometer.

 

The temperature is higher because the temperature sensor is likely on the same die as the microprocessor, and there is some heating due to power dissipation.

Share this post


Link to post
Share on other sites
Is the result of the temperature calculation dependent on the supply voltage to the MSP430? If so, what supply voltage does this code expect.

 

Using a 2231 on a Launchpad, my calculated temperatures are about 20 degrees F higher than a nearby thermometer.

 

The temperature is higher because the temperature sensor is likely on the same die as the microprocessor, and there is some heating due to power dissipation.

 

I can't remember the specifics, but I think my problem was in the programming.

 

I don't think power dissipation could cause the chip to run 20 degrees higher than ambient.

Share this post


Link to post
Share on other sites
I don't think power dissipation could cause the chip to run 20 degrees higher than ambient.

I don't think I've ever had an MSP430 be noticeably warm to the touch (as +20 degrees would be).

This excludes, of course, cases of mis-wiring. :oops:

Share this post


Link to post
Share on other sites

Keep in mind that the actual microprocessor is tiny compared to the volume of the plastic that surrounds it. The core could easily be 20 degrees warmer than ambient, and you wouldn't necessarily feel it on the outside of the chip. Also, an msp430 running at 16Mhz at 3.6V dissipates about 15 milliwatts of power, nearly all of it as heat (the energy that goes into entropy changes is negligible). That's not insignificant -- 0603 resistors are typically only rated to 100 milliwatts

Share this post


Link to post
Share on other sites
The core could easily be 20 degrees warmer than ambient, and you wouldn't necessarily feel it on the outside of the chip.

But that 20 degree difference doesn't stay in the core. It has to dissipate through the package, thus raising the temperature of the entire package.

Also, an msp430 running at 16Mhz at 3.6V dissipates about 15 milliwatts of power

0.015W is equivalent to 0.015 joules/second. One gram of water requires approximately 4.2 joules to raise its temperature by 1 degree Centigrade. I can't see 15mw creating much temperature change, even in a tiny area.

I could easily be wrong on all of this (see my sig), but I still can't see 15mw causing a 20 degree difference from ambient. :think:

Share this post


Link to post
Share on other sites
The core could easily be 20 degrees warmer than ambient, and you wouldn't necessarily feel it on the outside of the chip.

But that 20 degree difference doesn't stay in the core. It has to dissipate through the package, thus raising the temperature of the entire package.

Also, an msp430 running at 16Mhz at 3.6V dissipates about 15 milliwatts of power

0.015W is equivalent to 0.015 joules/second. One gram of water requires approximately 4.2 joules to raise its temperature by 1 degree Centigrade. I can't see 15mw creating much temperature change, even in a tiny area.

I could easily be wrong on all of this (see my sig), but I still can't see 15mw causing a 20 degree difference from ambient. :think:

 

One gram of water is actually A LOT of matter: one cubic centimeter to be precise. By comparison, the entire MSP430 silicone layer is probably on the order of 2 mm x 2 mm x a few microns, which could be 1 / 100,000th of a gram. The power dissipates through the plastic of course, but you could still have significant temperature gradients as you get closer to the die (consider our planet -- molten rock inside, but relatively cold on the outside).

 

The reason I think heat is responsible for inaccurate temperature readings is that I tried oPossum's code and noticed that temperatures are fairly accurate when I first turn on the launchpad, but then go up 10-20 degrees over time. It's hard to imagine anything else causing this shift.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...