Steinhard-Hart coefficients and parameters for the Thermistor we use

R0=10000.;B=3988.;
R[t_]:=R0*Exp[B*(1/(t+273.16)-1/(25+273.16))]
Temp[R_]:=1/(1/(25+273.16)+Log[R/R0]/B)-273.16

Temp[22000]

R[0]

Interpolation for an effective 14 bit resolution

Temperature in units of ADC conversion steps for a 4.7V reference supply and a 5V full range of a 14 bit ADX

m[t_]:=R[t]/(10000+R[t])*4.7/5.0*16384

Plot[m[t],{t,0,40},PlotRange->{0,15000}]

m[20]-m[21]

Function to convert a ADC reading int temperature; temperature is measured in 0.01 Celsius, e.g, a result of -20 corresponds to -2.0 degree

u[m1_]:=100t/.FindRoot[m[t]-m1,{t,0,40}]

u[8000]

Plot[u[m2],{m2,4000,12000}]

Fit[Table[u[m2],{m2,4000,12000}],{1,x},x]

Plot[u[m2]-(7270-m2/2-m2/8),{m2,4000,12000}]

try to fit

t[j_]:=Table[u[i+j*2048],{i,0,2047}]

ListPlot[t[2]]

table for 10 k from fit

ft2={{7800,0,5},{7800,0,7},{7700,0,6},{7680,0,7},{7280,0,7},{7000,0,7},{6900,0,6},{6850,0,5},{6830,0,5},{6830,0,7},{6810,0,6},{6770,0,7},{6800,0,7},{6800,0,7},{6800,0,6},{6800,0,5}};

newfifu2[n_]:=Module[{i,s0},s0=-n/2-n/8+n/16;i=IntegerPart[n/1024];
s0+ft2[[i+1,1]]+ft2[[i+1,2]]*(n-1024*i)/2^ft2[[i+1,3]]]

Plot[newfifu2[m2]-u[m2],{m2,3000,12000},PlotRange->{-20,500}]

u[500]

u[4000]

Table[u[i],{i,0,16383,256}]

u[2816]

u[11776]

ut2=Table[Round[u[256*i]],{i,13,48}]

fifu3[n_]:=Module[{i,offs},i=IntegerPart[n/256]-12;offs=Mod[n,256];If[(i<1 ),5678,If[(i>34),0,ut2[[i]]+(ut2[[i+1]]-ut2[[i]])*offs/256]]]

Plot[fifu3[n]-u[n],{n,3330,12000},PlotRange->All]

u[3300]
u[10000]

Transition to higher resolution

The following function gives the adc reading as a fuction of temp :

m[t_]:=R[t]/(10000+R[t])*102400

Plot[m[t],{t,-20,60}]

m[25.]

Function to convert a ADC reading int temperature; temperature is measured in 0.001 Celsius, e.g, a result of -2000 corresponds to -2.0 degree

u[m1_]:=1000t/.FindRoot[m[t]-m1,{t,0,40}]

u[1000]
u[50010]

Attempt to recover temperature via Taylor expansion

datalist=Table[{v-2^18,u[v]},{v,150000, 350000,1000}];

Length[datalist]

res=Fit[datalist,{1,x,x^2,x^3,x^4},x]

g[u_]:=res/.x->u

g[266000-2^18]

u[100000]
u[400000]

ParametricPlot[{u[meas]/1000,g[meas-2^18]-u[meas]},{meas,100000,400000}]

Try segmentwise linear interpolation again

define spacing between interpolation points, and generate  list of values at those points

steps=1024;
nodelist=Table[u[i],{i,0,100000,steps}];

First interpolation attempt: No integer arithmetic, use of direct points

interpol1[mt_]:=Module[{i,t0,delta},i=Floor[mt/steps];t0=nodelist[[i+1]];delta=nodelist[[i+2]]-t0;
t0+delta/steps*(mt-i*steps)
]

interpol1[50000]

Plot difference over temperature range between interpolation and true temp

Plot[interpol1[m[temp]]-temp*1000,{temp,-20,60}]

Transition to integer arithmetic in interpolation

An interpolation table contains integer values of t0, and delta, assuming that a 16*16->32 multiplication is carried out, and then shifted by 16 bits

nodelist2=Table[{Floor[u[i]+0.5],Floor[2^12*(u[i+steps]-u[i])/steps+0.5]},{i,0,102000,steps}];

interpol2[mt_]:=Module[{i,t0,delta},i=Floor[mt/steps];t0=nodelist2[[i+1,1]];delta=nodelist2[[i+1,2]];
t0+Floor[delta*(mt-i*steps)/2^12]
]

interpol2[50000]

Plot difference over temperature range between interpolation and true temp

Plot[interpol2[m[temp]]-temp*1000,{temp,-19,60},PlotRange->All]

To take care of the curvature between interpolation points, we modify the temperature at the interpolation nodes to minimize the errors by precompensating due to expected error:

precomp[i_]:=(u[i+steps/2]-(u[i+steps]+u[i])/2)/2

nodelist2pre=Table[{Floor[u[i]+0.5+precomp[i]],Floor[2^12*(-u[i+steps]-precomp[i+steps]+u[i]+precomp[i])/steps+0.5]},{i,0,96000,steps}];
Length[nodelist2pre]

interpol2p[mt_]:=Module[{i,t0,delta},i=Floor[mt/steps];t0=nodelist2pre[[i+1,1]];delta=nodelist2pre[[i+1,2]];
t0-Floor[delta*(mt-i*steps)/2^12+.5]
]

Plot difference over temperature range between interpolation and true temp, this time with precomp

Plot[interpol2p[Floor[m[temp]+.5]]-temp*1000,{temp,-20,70},PlotRange->All]

Try to find sensible range for interpolation table

nodelist2pre[[4]]
3*steps

nodelist2pre[[90]]
94*steps-1

interpol2p[2500]
interpol2p[95000]

A sensible measurement range would cover adc steps from 3072 to 95000, covering temperatures from -22C to +129 C.

Generation of C code list for this interpolation table:

This assumes that the table is stored as an array of struct interpol {int32_t basetemp, uint16_t delta}.

gg=Drop[nodelist2pre,3]

Length[gg]