12ビットXADC向けのサーミスタLUTを作成する

createTemperature.pyを使う

設定パラメータ
r0=100000.0 (100kΩ:25℃でのサーミスタの抵抗値R25)
t0=25(基準温度25℃)
r1=0.0 (低温時の発熱損失を押さえるための分流抵抗→使用しない)
r2=4700.0(4.7kΩ分圧抵抗)
beta=4267(サーミスタの定数B:データシートより)
max-adc=4096(12ビットA/Dコンバータ)

#!/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
"""Thermistor Value Lookup Table Generator
Updated by Shohei Aoki, 2017

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)
  --r2=...          R2 rating where # is the ohm rating of R2 (eg: 10K = 10000)
  --num-temps=...   the number of temperature points to calculate (default: 20)
  --max-adc=...     the max ADC reading to use.  if you use R1, it limits the top value for the thermistor circuit, and thus the possible range of ADC values
  --vcc=...         Supply voltage Vcc which coordinates with ADC reference Vadc
"""

from math import *
import sys
import getopt

class Thermistor:
    "Class to do the thermistor maths"
    def __init__(self, r0, t0, beta, r1, r2, max_adc, vcc):
        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 = vcc                     # ADC reference
        self.vcc = vcc                      # supply voltage to potential divider
        self.k = r0 * exp(-beta / self.t0)   # constant part of calculation
        self.max_adc = max_adc

        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 / self.max_adc # 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 * self.max_adc)  # the ADC reading

def main(argv):

    r0 = 100000;
    t0 = 25;
    beta = 4267;
    r1 = 0;
    r2 = 4700;
    num_temps = int(61);
    vcc = 5.0
    max_adc_raw = 1023

    try:
        opts, args = getopt.getopt(argv, "h", ["help", "r0=", "t0=", "beta=", "r1=", "r2=", "max-adc=", "vcc="])
    except getopt.GetoptError:
        usage()
        sys.exit(2)

    for opt, arg in opts:
        if opt in ("-h", "--help"):
            usage()
            sys.exit()
        elif opt == "--r0":
            r0 = float(arg)
        elif opt == "--t0":
            t0 = int(arg)
        elif opt == "--beta":
            beta = int(arg)
        elif opt == "--r1":
            r1 = float(arg)
        elif opt == "--r2":
            r2 = float(arg)
        elif opt == "--max-adc":
           max_adc_raw = int(arg)
        elif opt == "--vcc":
            vcc = float(arg)

    if r1:
        max_adc = int(max_adc_raw * r1 / (r1 + r2));
    else:
        max_adc = max_adc_raw
    increment = int(max_adc/(num_temps-1));

    t = Thermistor(r0, t0, beta, r1, r2, max_adc, vcc)

    adcs = list(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 --vcc=%s" % (r0, t0, r1, r2, beta, max_adc, vcc))
    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("// vcc: %s" % (vcc))
    print("#define NUMTEMPS %s" % (len(adcs)))
    print("short temptable[NUMTEMPS][2] = {")

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

def usage():
    print(__doc__)

if __name__ == "__main__":
    main(sys.argv[1:])
$ ./createTemperatureLookup.py --r0=100000 --t0=25 --r1=0 --r2=4700.0 --beta=4267 --max-adc=4096 --vcc=3.3


// Thermistor lookup table for RepRap Temperature Sensor Boards (http://make.rrrf.org/ts)
// Made with createTemperatureLookup.py (http://svn.reprap.org/trunk/reprap/firmware/Arduino/utilities/createTemperatureLookup.py)
// ./createTemperatureLookup.py --r0=100000.0 --t0=25 --r1=0.0 --r2=4700.0 --beta=4267 --max-adc=4096 --vcc=3.3
// r0: 100000.0
// t0: 25
// r1: 0.0
// r2: 4700.0
// beta: 4267
// max adc: 4096
// vcc: 3.3
#define NUMTEMPS 61
short temptable[NUMTEMPS][2] = {
   {1, 1179},
   {69, 320},
   {137, 267},
   {205, 240},
   {273, 222},
   {341, 208},
   {409, 198},
   {477, 189},
   {545, 181},
   {613, 175},
   {681, 169},
   {749, 164},
   {817, 159},
   {885, 155},
   {953, 150},
   {1021, 147},
   {1089, 143},
   {1157, 140},
   {1225, 137},
   {1293, 133},
   {1361, 131},
   {1429, 128},
   {1497, 125},
   {1565, 122},
   {1633, 120},
   {1701, 117},
   {1769, 115},
   {1837, 113},
   {1905, 110},
   {1973, 108},
   {2041, 106},
   {2109, 104},
   {2177, 101},
   {2245, 99},
   {2313, 97},
   {2381, 95},
   {2449, 93},
   {2517, 90},
   {2585, 88},
   {2653, 86},
   {2721, 84},
   {2789, 82},
   {2857, 79},
   {2925, 77},
   {2993, 75},
   {3061, 72},
   {3129, 70},
   {3197, 67},
   {3265, 64},
   {3333, 62},
   {3401, 59},
   {3469, 55},
   {3537, 52},
   {3605, 48},
   {3673, 44},
   {3741, 40},
   {3809, 35},
   {3877, 28},
   {3945, 20},
   {4013, 8},
   {4081, 0}
};