Wednesday, November 30, 2016

Freestyle Libre external thermistor data dump

I’ve received a couple of questions about the Libre thermistor temperature curves in my previous blog post. One of the reason I did not post actual data is that I wasn’t 100% sure of their absolute validity (in relative terms, they were enough for my purpose). The data I used last year was derived through a polynomial fit, not the ideal option, when there is a better approximation formula that is commonly used for NTC thermistors.
That is why, today, I decided to double check the data and provide it.
Usual caveats
  • thermistor have tolerances, 5%, 10%, generating errors.
  • my multimeter probably suffers for a certain error.
  • my contraption may introduce additional resistance.
  • my heating bed’s thermistor also has its own error.
  • the thermistor is extremely reactive: breathing on it changes its resistance, testing it in an open environment or under some insulation changes the values.
  • I have seen thermistors not behaving as expected.
As usual, take your own measures.
Here is the test environment. The glass bowl serves as a temperature stabilizer. I am patching on an old Libre sensor.
I ran a few measures at 55°C, 35°C, 0°C (separately), averaged them and solved the 3 equation system
1/T1 = a +b(log(R1))+c(log(R1))^3
1/T2 = a +b(log(R2))+c(log(R2))^3
1/T3 = a +b(log(R3))+c(log(R3))^3
to derive the Steinhart-Hart coefficients (working in kOhms rather than Ohms.
The Wolfram Alpha query for that system is
1/328=x+y*(ln(31.5))+z*(ln(31.5))^3, 1/308 = x +y*(ln(83))+z*(ln(83))^3, 1/273= x +y*(ln(330))+z*(ln(330))^3
It matches closely the solution I got in numpy. Here’s the plotted “theoretical“ curve versus the separately observed data. Please note that this can’t be directly converted in the Libre bits and bytes and is not necessarily exactly what the Libre sees.
The thermistor seems to be a 120k NTC thermistor and not a 100k thermistor. That was either a quick wrong assumption back in 2015, or a thermistor variation (I don’t remember and don’t have that thermistor for a retest anyway).

Edit 30/11 – after additional measures with a third thermistor, taking the gradient over my bed in consideration and testing older thermistors, the old assumption of a 100k thermistor could very well be the correct one, in that case, the curve below simply shifts to the left. It is correct in relative, but not absolute terms
And here is is the python code containing the experimental data. Again, if you are interested, by all means, take your own measures (and eventually let me know). I have observed slightly different values, possibly a 100k NTC and, at least in one case, drastically different values. It is hard for me to know if the thermistor was damaged of if Abbott uses two different types. And yes, I am aware that the decimals in the data dump are probably pointless, but I just noted the values as the rig stabilized.
import matplotlib.pyplot as plt
import numpy as np
import math as m

# 0C
K = 273

# takes the coefficients, measured resistance, returns temp in celsius (note kOhms)
def SteinhartHart(a, b, c, r):
    invT = a + b * m.log(r) + c * (m.pow(m.log(r), 3))
    TK = 1 / invT
    T = TK - K
    return T

# thermistor measures
Observed = [(40, 69), (40, 66), (39, 72), (39, 69), (38, 74), (38, 72), (37, 76), (37, 76.5), (36, 79),
            (36, 78.34), (35, 83), (34, 86), (33, 89), (32, 93), (32, 93), (31, 96.8), (31.3, 95), (30.5, 98),
            (30.5, 99), (29.9, 101), (27.6, 111), (27, 114), (25.8, 116.6), (25.2, 122.2), (25.9, 117.4),
            (30, 100), (29, 104), (28, 108), (27, 112), (26.7, 114), (26.2, 116.8), (25.7, 118.4), (24.8, 123.3),
            (55, 32.9), (62.2, 20), (0.1, 340), ]

fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_title('Ext. Therm (Steinhart-Hart)')
ax.set_ylabel('Temp. Celsius')

# plot observed data
v, t = zip(*Observed)
line2 = ax.scatter(t, v, c='r', marker='.', label="Measures")

# steinhart - hart, linalg code omitted, double checked with wolfram alpha kOhms
a = 0.00270712
b = 0.0000629848
c = 0.00000302854

# generates Steinhart-Hart Curve
x = np.linspace(1, 350, 350)
s = []
for i in x:
    s.append((SteinhartHart(a, b, c, i)))
line = ax.plot(x, s, c='g', label="Steinhart-Hart")


  1. Hi Pierre, where can I found the thermistor value in libre sensor memory? if it's there

  2. Have you noticed that the greenish SMD component that ist soldered in series to the other 999 Ohm resistor is a thermistor as well? So there are actually 3 possible temperature measuring sites on the libre PCB.