Temperatursensor bis 150°C gesucht
Hallo zusammen,
ich bin derzeit auf der Suche nach einem Temperatursensor der bis zu 150°C messen kann. In der späteren Anwendung wird er hauptsächlich Temperaturen zwischen 70-140°C messen werden.
Ich würde am liebsten einen Digitalen Sensor nehmen, um mir die Rechnerei zu ersparen, aber ich habe kaum bzw. keinen gefunden der diesen Bereich abdeckt.
Wenn ich einen NTC nehmen würde, was macht dann mehr Sinn? Eine Konstantstromquelle oder einfach nur einen 2. Widerstand in Reihe schalten?
Die Genauigkeit kann ruhig 2-3° betragen. So genau muss es nicht sein. Welchen Mikrocontroller ich verwende steht noch nicht ganz fest, aber es wird ein Atmel sein.
Oder habt Ihr eine ganz andere Idee? Bin für jeden Vorschlag offen.
Ich hoffe Ihr könnt mir da weiter helfen :)
MfG
Martin
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab bei meiner Heizungssteuerung genau diese Aufgabe so gelöst:
Hier lasse ich genau 0.88mA durch den KTY-81 und kann damit exakt sagen, nach Tabelle, welcher Widerstand anliegt. Der µC hat im EEPROM eine Stützpunkttabelle welche R auf Temperatur abbildet (aus dem Datenblatt abgetippt). Liegt die Spannung zwischen 2 Stützpunkten wird linear interpoliert. So komme ich mit einem MAX1270 (ok, teuer *hust* aber 12 Bit) auf unter 1°C Genauigkeit. Mit dem eingebauten ADC geht das ganze auch aber die Auflösung ist etwas schlechter.
Anhang 30708
Code:
const sensorvalues_flash t_kt81_110[] PROGMEM =
{ // r t
{ 490, -55},
{ 515, -50},
{ 567, -40},
{ 624, -30},
{ 684, -20},
{ 747, -10},
{ 815, 0},
{ 886, 10},
{ 961, 20},
{ 1000, 25},
{ 1040, 30},
{ 1122, 40},
{ 1209, 50},
{ 1299, 60},
{ 1392, 70},
{ 1490, 80},
{ 1591, 90},
{ 1696, 100},
{ 1805, 110},
{ 1915, 120},
{ 2023, 130},
{ 2124, 140},
{ 2211, 150},
};
const sensorvalues_flash t_kt81_210[] PROGMEM =
{ // r t
{ 1383, -20},
{ 1408, -18},
{ 1434, -16},
{ 1459, -14},
{ 1485, -12},
{ 1511, -10},
{ 1537, -8},
{ 1563, -6},
{ 1590, -4},
{ 1617, -2},
{ 1644, 0},
{ 1671, 2},
{ 1699, 4},
{ 1727, 6},
{ 1755, 8},
{ 1783, 10},
{ 1812, 12},
{ 1840, 14},
{ 1869, 16},
{ 1898, 18},
{ 1928, 20},
{ 2002, 25},
{ 2078, 30},
{ 2155, 35},
{ 2234, 40},
{ 2314, 45},
{ 2395, 50},
{ 2478, 55},
{ 2563, 60},
{ 2648, 65},
{ 2735, 70},
{ 2824, 75},
{ 2914, 80},
{ 3005, 85},
{ 3098, 90},
{ 3192, 95},
{ 3287, 100},
};
Um den langsammen Zugriff auf den Flash zu reduzieren, nutze ich eine binäre Suche, so brauche ich nur log(n)/log(2) zugriffe statt n:
Das bedeutet, statt 37 Versuchen beim kt81_210 brauche ich nur log(37)/log(2) = 6.
Code:
avr::units::temperature
convert(sensor_t s, avr::units::resistor r)
{
sensorvalues t1, t2;
const sensorvalues_flash* current = &t_kt81_210[0];
switch (s)
{
case kt81_210: current = &t_kt81_210[0]; break;
case kt81_110: current = &t_kt81_110[0]; break;
}
// binary search without recursion
unsigned char st = 0;
unsigned char en;
unsigned char m;
switch (s)
{
case kt81_210: en = sizeof(t_kt81_210)/sizeof(sensorvalues_flash)-2; break;
case kt81_110: en = sizeof(t_kt81_110)/sizeof(sensorvalues_flash)-2; break;
default:
return 0.0_celcius;
}
sensorvalues_flash tmp;
while (en-st>1)
{
m = st + (en-st)/2;
memcpy_P(&tmp, ¤t[m], sizeof(sensorvalues_flash)); t1 = tmp;
if (r > t1.r) // if we use at sometime a NTC, we need to adjust this
{
// right side
st = m;
}
else
{
// left side
en = m;
}
}
// read the best matching lines
memcpy_P(&tmp, ¤t[st+0], sizeof(sensorvalues_flash)); t1 = tmp;
memcpy_P(&tmp, ¤t[st+1], sizeof(sensorvalues_flash)); t2 = tmp;
// interpolate
resistor dr = t2.r-t1.r;
float f = static_cast<float>((r-t1.r)/dr);
return t1.t+(t2.t-t1.t)*f;
}
Hier wird eingelesen. vom ADC wird dann in Volt gewandelt. Über R=V/I wird dann R berechnet, welcher dann über die obige convert Funktion in Temperatur umgewandelt wird.
sys.configuration.adc_constant_current[avr::free_7-active_adc] enthält den exakt gemessenen Konstantstrom welcher über das Menü angepasst werden kann. (Messung per Scopemeter)
Code:
tmp = (uint16_t(in[0]) << 8) | uint16_t(in[1]);
tmp = tmp >> 4; // shift the last 4 zero bits out
sys.max1270_select.on();
// fill the sensor structure
sys.sensor.dt = sys.dt;
using namespace avr::units;
voltage v((float(tmp)/(1<<12))*5.0f);
resistor r = v/sys.configuration.adc_constant_current[avr::free_7-active_adc];
// prevent short spikes
if (abs(tmp-sys.sensor.raw[avr::free_7-active_adc]) < 10 || first[active_adc])
{
first[active_adc] = false;
sys.sensor.raw[avr::free_7-active_adc] = tmp;
sys.sensor.temperature[avr::free_7-active_adc] =
convert(sys.configuration.adc_sensor_type[avr::free_7-active_adc],r);
}