oPossum 1,083 Posted March 21, 2012 Share Posted March 21, 2012 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. The data sheet (SLAU144) has this formula for converting temperature in degrees Celsius to voltage. V = 0.00355 * C + 0.986 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. 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); } Rei Vilo, EngIP, Rickta59 and 28 others 31 Quote Link to post Share on other sites
fj604 34 Posted April 7, 2012 Share Posted April 7, 2012 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; Quote Link to post Share on other sites
oPossum 1,083 Posted April 7, 2012 Author Share Posted April 7, 2012 No explanation of how they are derived, and there are two mistakes in those formulas. They also take more code space, run slower, and are less accurate. Quote Link to post Share on other sites
RobG 1,892 Posted April 7, 2012 Share Posted April 7, 2012 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 Quote Link to post Share on other sites
B.Noll 5 Posted April 8, 2012 Share Posted April 8, 2012 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 Quote Link to post Share on other sites
jordantryon 0 Posted May 6, 2012 Share Posted May 6, 2012 Very Cool! Quote Link to post Share on other sites
websterling 12 Posted May 28, 2012 Share Posted May 28, 2012 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. Quote Link to post Share on other sites
jsolarski 94 Posted May 28, 2012 Share Posted May 28, 2012 it should be independent of supply voltage since there is an internal ref voltage 'generator' for the adc Quote Link to post Share on other sites
kff2 22 Posted June 13, 2012 Share Posted June 13, 2012 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. Quote Link to post Share on other sites
websterling 12 Posted June 15, 2012 Share Posted June 15, 2012 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. Quote Link to post Share on other sites
GeekDoc 226 Posted June 15, 2012 Share Posted June 15, 2012 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: Quote Link to post Share on other sites
kff2 22 Posted June 16, 2012 Share Posted June 16, 2012 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 Quote Link to post Share on other sites
GeekDoc 226 Posted June 16, 2012 Share Posted June 16, 2012 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: Quote Link to post Share on other sites
oPossum 1,083 Posted June 16, 2012 Author Share Posted June 16, 2012 The sample code I posted runs at the default clock of about 1.2 MHz, so the power dissipation is about 1 mW. Quote Link to post Share on other sites
kff2 22 Posted June 16, 2012 Share Posted June 16, 2012 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. tripwire 1 Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.