diff --git a/configtool/thermistortablefile.py b/configtool/thermistortablefile.py index e28292d51..c855a05d8 100644 --- a/configtool/thermistortablefile.py +++ b/configtool/thermistortablefile.py @@ -100,45 +100,8 @@ def BetaTable(ofp, params, names, settings, finalTable): hiadc = thrm.setting(0)[0] N = int(settings.numTemps) - # This is a variation of the Ramer-Douglas-Peucker algorithm, see - # https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm - # - # It works like this: - # - # - Calculate all (1024) ideal values. - # - Insert the two extremes into our sample list. - # - Calculate the linear approximation of the remaining values. - # - Insert the correct value for the "most-wrong" estimation into our - # sample list. - # - Repeat until "N" values are chosen as requested. - - # Calculate actual temps for all ADC values. - actual = dict([(x, thrm.temp(1.0 * x)) for x in range(1, int(hiadc + 1))]) - - # Limit ADC range to 0C to 500C - MIN_TEMP = 0 - MAX_TEMP = 500 - actual = dict([(adc,actual[adc]) for adc in actual if actual[adc] <= MAX_TEMP and actual[adc] >= MIN_TEMP]) - - # Build a lookup table starting with the extremes. - - A = min(actual) - B = max(actual) - lookup = dict([(x, actual[x]) for x in [A,B]]) - error = dict({}) - while len(lookup) < N: - error.update(dict([(x, abs(actual[x] - LinearTableEstimate(lookup, x))) - for x in range(A + 1, B)])) - - # Correct the most-wrong lookup value. - next = max(error, key = error.get) - lookup[next] = actual[next] - - # Prepare to update the error range. - A = before(lookup, next) - B = after(lookup, next) - - for i in sorted(lookup.keys()): + samples = optimizeTempTable(thrm, N, hiadc) + for i in samples: t = int(thrm.temp(i)) if t is None: ofp.output("// ERROR CALCULATING THERMISTOR VALUES AT ADC %d" % i) @@ -149,7 +112,7 @@ def BetaTable(ofp, params, names, settings, finalTable): vTherm = i * vadc / 1024 ptherm = vTherm * vTherm / r - if i == max(lookup): + if i == max(samples): c = " " else: c = "," @@ -178,9 +141,9 @@ def SteinhartHartTable(ofp, params, names, settings, finalTable): hiadc = thrm.setting(0)[0] N = int(settings.numTemps) - step = int(hiadc / (N - 1)) - for i in range(1, int(hiadc), step): + samples = optimizeTempTable(thrm, N, hiadc) + for i in samples: t = int(thrm.temp(i)) if t is None: ofp.output("// ERROR CALCULATING THERMISTOR VALUES AT ADC %d" % i) @@ -188,7 +151,7 @@ def SteinhartHartTable(ofp, params, names, settings, finalTable): r = int(thrm.adcInv(i)) - if i + step >= int(hiadc): + if i == max(samples): c = " " else: c = "," @@ -200,6 +163,48 @@ def SteinhartHartTable(ofp, params, names, settings, finalTable): else: ofp.output(" },") +def optimizeTempTable(thrm, length, hiadc): + # This is a variation of the Ramer-Douglas-Peucker algorithm, see + # https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm + # + # It works like this: + # + # - Calculate all (1024) ideal values. + # - Insert the two extremes into our sample list. + # - Calculate the linear approximation of the remaining values. + # - Insert the correct value for the "most-wrong" estimation into our + # sample list. + # - Repeat until "N" values are chosen as requested. + + # Calculate actual temps for all ADC values. + actual = dict([(x, thrm.temp(1.0 * x)) for x in range(1, int(hiadc + 1))]) + + # Limit ADC range to 0C to 500C + MIN_TEMP = 0 + MAX_TEMP = 500 + actual = dict([(adc,actual[adc]) for adc in actual + if actual[adc] <= MAX_TEMP and actual[adc] >= MIN_TEMP]) + + # Build a lookup table starting with the extremes. + + A = min(actual) + B = max(actual) + lookup = dict([(x, actual[x]) for x in [A,B]]) + error = dict({}) + while len(lookup) < length: + error.update(dict([(x, abs(actual[x] - LinearTableEstimate(lookup, x))) + for x in range(A + 1, B)])) + + # Correct the most-wrong lookup value. + next = max(error, key = error.get) + lookup[next] = actual[next] + + # Prepare to update the error range. + A = before(lookup, next) + B = after(lookup, next) + + return sorted(lookup) + def after(lookup, value): return min([x for x in lookup.keys() if x > value])