Skip to content
This repository has been archived by the owner on Aug 27, 2023. It is now read-only.

Commit

Permalink
Refactor temp table optimization for any algorithm
Browse files Browse the repository at this point in the history
This should be squashed but is separated here for comparison.
  • Loading branch information
phord committed Apr 13, 2016
1 parent 0fc8212 commit 71ee7ce
Showing 1 changed file with 48 additions and 43 deletions.
91 changes: 48 additions & 43 deletions configtool/thermistortablefile.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 = ","
Expand Down Expand Up @@ -178,17 +141,17 @@ 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)
continue

r = int(thrm.adcInv(i))

if i + step >= int(hiadc):
if i == max(samples):
c = " "
else:
c = ","
Expand All @@ -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])

Expand Down

0 comments on commit 71ee7ce

Please sign in to comment.