Jump to content

  • Log In with Google      Sign In   
  • Create Account

Photo

Thermistor code for MSP430


  • Please log in to reply
4 replies to this topic

#1 larsie

larsie

    Level 2

  • Members
  • 270 posts


Posted 03 April 2012 - 11:18 AM

I’ve made some MSP430 code for a high-temperature capable thermometer, by adapting the code from Reprap. The code uses the B57560G104F thermistor that can measure temperatures up to 300 Degrees C. You can for example use these for controlling a reflow oven temperature. Cheaper than thermo-couple. Maybe not quite as accurate. This high resistance version doesn't suffer so much from self-warming.

The picture shows the temperature in a display and in front the Thermistor. I'm using my new SPI-based display for this one, but it can obviously be used on SugarAddict's or other, or a character display such as this one (with code) on my blog.

These are really tiny glass beads that can handle high temperatures, but be careful with how you mount it.

Attached File  thermistor_msp430_lcd_launchpad.JPG   35.74KB   5 downloads

The circuit is basically

Vcc — 10K resistor — P1.2 — Thermistor — 0V

It’s also good to place a 1uF capacitor across the thermistor to remove noise.

IAR MSP430 code is below. It can easily be adapted to CCS or MSPGCC. Should also be pretty easy to make a MSP430-controlled heater by connecting this to a relay or transistor that handles the current. Maybe even adding a PID-controller.

thermistor.c:
 




/*

* Inspired by http://reprap.org/wiki/Temperature_Sensor_1_0

* No license info from that page, but some may claim it's GPL.

* Not sure if that is relevant for such a short code snippet.

*/



#include

#include "thermistor.h"



// Thermistor B57560G104F http://uk.farnell.com/epcos/b57560g104f/thermistor-ntc/dp/3878697?Ntt=3878697



// r0: 100000

// t0: 25

// r1: 0

// r2: 10000

// beta: 4036

// max adc: 1023

#define NUMTEMPS 20

int temptable[NUMTEMPS][2] = {

{1, 664}, // 664.64106912 C

{54, 210}, // 210.439979582 C

{107, 171}, // 171.052478604 C

{160, 149}, // 149.564016786 C

{213, 134}, // 134.640069513 C

{266, 123}, // 123.039739982 C

{319, 113}, // 113.394921511 C

{372, 104}, // 104.997832544 C

{425, 97}, // 97.4294169841 C

{478, 90}, // 90.4137427983 C

{531, 83}, // 83.7503688927 C

{584, 77}, // 77.2777873564 C

{637, 70}, // 70.8496463885 C

{690, 64}, // 64.314518844 C

{743, 57}, // 57.4917052426 C

{796, 50}, // 50.1314173911 C

{849, 41}, // 41.8303323287 C

{902, 31}, // 31.8031759831 C

{955, 18}, // 18.0092465547 C

{995, 0} // 0.112666936696 C

};



void initThermistor()

{

WDTCTL = WDTPW + WDTHOLD; // Stop WDT

ADC10CTL1 = INCH_2; // Conversion code singed format, input A1

ADC10AE0 |= BIT2; // P1.2 ADC option select

ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE; // ADC10ON, interrupt enabled

}



int rawValueThermistor()

{

ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start

__bis_SR_register(CPUOFF + GIE); // LPM0, ADC10_ISR will force exit

return ADC10MEM;

}



int readTemp()

{

int rawtemp = rawValueThermistor();

int current_celsius = 0;



int i = 0;

for (i=1;i < NUMTEMPS;i++) { if (temptable[i][0] > rawtemp)

{

int realtemp = temptable[i-1][1] + (rawtemp - temptable[i-1][0]) * (temptable[i][1] - temptable[i-1][1]) / (temptable[i][0] - temptable[i-1][0]);



if (realtemp > 255)

realtemp = 255;



current_celsius = realtemp;



break;

}

}



// Overflow: We just clamp to 0 degrees celsius

if (i == NUMTEMPS) {

current_celsius = 1000;

}



return current_celsius;

}



#pragma vector=ADC10_VECTOR

__interrupt void ADC10_ISR (void)

{

__bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)

}

thermistor.h
 




void initThermistor();

int rawValueThermistor(void);

int readTemp(void);




  • bluehash, Rickta59, oPossum and 3 others like this

#2 Rei Vilo

Rei Vilo

    Level 3

  • Members
  • 611 posts
  • LocationFrance

Posted 09 October 2012 - 05:22 PM

Thank oy larise!

Based on the information shared, I've developed a sketch to read the temperature from the FranchPad MSP430FR5739 built-in NTC and display in °C and °F.

See :arrow: viewtopic.php?p=24032#p24032

#3 rebeltaz

rebeltaz

    Level 1

  • Members
  • 129 posts

Posted 15 November 2012 - 11:44 PM

Your code looks like what I am looking for, but I am trying to adapt this to an Ametherm nt03 50169 thermistor (
www.ametherm.com/datasheetspdf/NT03%2050169.pdf ).

I see on the datasheet for your thermistor where you get the values for r0, t0 and beta but I'm not sure about the r1, r2 and max adc. Also, going on your datasheet, I can't figure out how you built the look up table. Maybe you could explain it... kinda of Thermistor Look-up Tables for Dummies :)

Thanks...

#4 rebeltaz

rebeltaz

    Level 1

  • Members
  • 129 posts

Posted 23 November 2012 - 07:43 AM

OK.. so I found this on my own. Here's what I found in case anyone else has the same questions I did:

The Python script used to generate the look up table is found here:
http://reprap.svn.so...up&pathrev=3448

This is the original schematic that goes with the script:
http://reprap.org/wi...r_2_0#Schematic

The values for R0, T0 and Beta are found in your thermistor's datasheet, where T0 typically equals 25 (degrees Celsius) and R0 is the thermistor's resistance at T0 (25 degrees Celsius). R1 should be 0 if you are not using a resistor in parallel with the thermistor. R2 is the value of the divider resistor you wish to use. The script then calculates the value MAX ADC as well as the look up table.

There is a small error in the script. One of the options shown in the help screen is num-temp. This option allows you to specify the number of entries in the table. The code for this option is missing from the script, however. I have added the missing code and I am adding the fixed code below if you need it.

For the thermistor shown in this topics code, the command line for the script would read:

python createTemperatureLookup.py --r0=100000 --t0=25 --r1=0 --r2=1000 --beta=4036

I hope that this helps save some headache and searching.

#!/usr/bin/python
#
# Creates a C code lookup table for doing ADC to temperature conversion
# on a microcontroller
# based on: http://hydraraptor.blogspot.com/2007/10/measuring-temperature-easy-way.html
#
# use sensor.jpg as a schematic reference - use '0' for r1 with no parallel resistor

"""Thermistor Value Lookup Table Generator

Generates lookup to temperature values for use in a microcontroller in C format based on:
http://hydraraptor.blogspot.com/2007/10/measuring-temperature-easy-way.html

The main use is for Arduino programs that read data from the circuit board described here:
http://make.rrrf.org/ts-1.0

Usage: python createTemperatureLookup.py [options]

Options:
  -h, --help            show this help
  --r0=...             thermistor rating where # is the ohm rating of the thermistor at t0 (eg: 10K = 10000)
  --t0=...             thermistor temp rating where # is the temperature in Celsuis to get r0 (from your datasheet)
  --beta=...            thermistor beta rating. see http://reprap.org/bin/view/Main/MeasuringThermistorBeta
  --r1=...            R1 rating where # is the ohm rating of R1 (eg: 10K = 10000) - typically 0
  --r2=...             R2 rating where # is the ohm rating of R2 (eg: 10K = 10000)
  --num-temps=...     the number of temperature points to calculate (default: 20)
"""

from math import *
import sys
import getopt

class Thermistor:
    "Class to do the thermistor maths"
    def __init__(self, r0, t0, beta, r1, r2):
	    self.r0 = r0					    # stated resistance, e.g. 10K
	    self.t0 = t0 + 273.15			   # temperature at stated resistance, e.g. 25C
	    self.beta = beta				    # stated beta, e.g. 3500
	    self.vadc = 5.0					 # ADC reference
	    self.vcc = 5.0					  # supply voltage to potential divider
	    self.k = r0 * exp(-beta / self.t0)   # constant part of calculation

	    if r1 > 0:
		    self.vs = r1 * self.vcc / (r1 + r2) # effective bias voltage
		    self.rs = r1 * r2 / (r1 + r2)	   # effective bias impedance
	    else:
		    self.vs = self.vcc                     # effective bias voltage
		    self.rs = r2						 # effective bias impedance

    def temp(self,adc):
	    "Convert ADC reading into a temperature in Celcius"
	    v = adc * self.vadc / 1024		  # convert the 10 bit ADC value to a voltage
	    r = self.rs * v / (self.vs - v)	 # resistance of thermistor
	    return (self.beta / log(r / self.k)) - 273.15	    # temperature

    def setting(self, t):
	    "Convert a temperature into a ADC value"
	    r = self.r0 * exp(self.beta * (1 / (t + 273.15) - 1 / self.t0)) # resistance of the thermistor
	    v = self.vs * r / (self.rs + r)	 # the voltage at the potential divider
	    return round(v / self.vadc * 1024)  # the ADC reading

def main(argv):

    r0 = 10000;
    t0 = 25;
    beta = 3947;
    r1 = 680;
    r2 = 1600;
    num_temps = int(20);
    
    try:
	    opts, args = getopt.getopt(argv, "h", ["help", "r0=", "t0=", "beta=", "r1=", "r2=", "num-temps="])
    except getopt.GetoptError:
	    usage()
	    sys.exit(2)
	    
    for opt, arg in opts:
	    if opt in ("-h", "--help"):
		    usage()
		    sys.exit()
	    elif opt == "--r0":
		    r0 = int(arg)
	    elif opt == "--t0":
		    t0 = int(arg)
	    elif opt == "--beta":
	         beta = int(arg)
	    elif opt == "--r1":
		    r1 = int(arg)
	    elif opt == "--r2":
		    r2 = int(arg)
    elif opt == "--num-temps":
   	 num_temps = int(arg)

    if r1:
	    max_adc = int(1023 * r1 / (r1 + r2));
    else:
	    max_adc = 1023
		    
    increment = int(max_adc/(num_temps-1));
    
    t = Thermistor(r0, t0, beta, r1, r2)

    adcs = range(1, max_adc, increment);
#    adcs = [1, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100, 110, 130, 150, 190, 220,  250, 300]
    first = 1

    print "// Thermistor lookup table for RepRap Temperature Sensor Boards (http://make.rrrf.org/ts)"
    print "// Made with createTemperatureLookup.py (http://svn.reprap.org/trunk/reprap/firmware/Arduino/utilities/createTemperatureLookup.py)"
    print "// ./createTemperatureLookup.py --r0=%s --t0=%s --r1=%s --r2=%s --beta=%s --max-adc=%s" % (r0, t0, r1, r2, beta, max_adc)
    print "// r0: %s" % (r0)
    print "// t0: %s" % (t0)
    print "// r1: %s" % (r1)
    print "// r2: %s" % (r2)
    print "// beta: %s" % (beta)
    print "// max adc: %s" % (max_adc)
    print "#define NUMTEMPS %s" % (len(adcs))
    print "short temptable[NUMTEMPS][2] = {"

    counter = 0
    for adc in adcs:
	    counter = counter +1
	    if counter == len(adcs):
		    print "   {%s, %s}" % (adc, int(t.temp(adc)))
	    else:
		    print "   {%s, %s}," % (adc, int(t.temp(adc)))
    print "};"
    
def usage():
    print __doc__

if __name__ == "__main__":
    main(sys.argv[1:])


#5 JackPP

JackPP

    Noob Class

  • Members
  • 1 posts

Posted 11 October 2013 - 04:43 PM

Hi guys!

I would make a question inherent to larsie's code. If i would use it in Code Composer Studio 5.5, how can i adapt it?

Thanks!!






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users