Ich würde dir bis 150 °C den linearen LM35 empfehlen: http://www.datasheetcatalog.com/data...3/5/LM35.shtml .
Werbung
Ich würde dir bis 150 °C den linearen LM35 empfehlen: http://www.datasheetcatalog.com/data...3/5/LM35.shtml .
MfG (Mit feinem Grübeln) Wir unterstützen dich bei deinen Projekten, aber wir entwickeln sie nicht für dich. (radbruch) "Irgendwas" geht "irgendwie" immer...(Rabenauge) Machs - und berichte.(oberallgeier) Man weißt wie, aber nie warum. Gut zu wissen, was man nicht weiß. Zuerst messen, danach fragen. Was heute geht, wurde gestern gebastelt. http://www.youtube.com/watch?v=qOAnVO3y2u8 Danke!
Wirklich lineare Widerstandskennlinien gibt es nicht. Nur solche, die innerhalb eines gewissen Bereichs annähernd linear sind.
Wieso? Ausdrücke wie b*(a*a)+c*a sollte doch selbst Bascom verarbeiten können. Oder nicht?Ich programmiere in Bascom. Da macht rechnen eher wenig Spaß.
Hallo nochmal,
danke für den Tipp mit dem LM35. Ich denke der wirds werden. Kompakt, aber trotzdem schon mit einem gescheitem Ausgang! So muss das sein. Zudem hat der Sensor selbst bei 140°C noch eine gute Genauigkeit.
Nicht direkt. Man muss jeden Schritt in einer neuen Zeile rechnen. Das heißt man braucht jede Menge zwischen Variablen und muss selbst beachten wann was zuerst usw. gerechnet werden muss. Ist also nicht ganz so einfach...Wieso? Ausdrücke wie b*(a*a)+c*a sollte doch selbst Bascom verarbeiten können. Oder nicht?
Ich wollte ja schonmal auf C umsteigen, war mir aber damals zu komplex. Vielleicht kommt das ja aber auch noch mal irgendwann.
MfG
Martin
- - - Aktualisiert - - -
Ok... Auf der Suche nach dem LM35 hat sich ein kleines Problemchen ergeben.
Man findet in der Regel nur den LM35DZ. Dieser geht jedoch nur bis 110°C. Die einigen die bis 150°C gehen, sind in einem Metallgehäuse eingefasst und sind leider zu groß, als das ich diese in der nähe des Zylinderkopfes montieren könnte. Demnach wider alles auf Anfang und eine alternative suchen / finden.
LG
C sieht nur komplex aus wegen den geschweiften Klammern. Bascom verschint dich nur mit den richtigen Registerbezeichnungen, die stehen aber alle im Datenblatt, probiers mal aus.
Hallo,
hier gibt es noch etwas Lesestoff, das für die Auswahl hilfreich sein könnte:
https://www.mikrocontroller.net/arti...mperatursensor
Grüße, Bernhard
"Im Leben geht es nicht darum, gute Karten zu haben, sondern auch mit einem schlechten Blatt gut zu spielen." R.L. Stevenson
Bist du dir sicher das 140°C ausreichen werden? an meinen Verbrenner hab ich schon gut über 200°C gemessen. Und meistens läuft der mit 140-160°C.
Gemessen wird da am Zylinderkopf in den Kühlrippen, mit einen NTC und an der Funke angezeigt (Telemetrie). Obwohl ich die Messung der Glühkerze per Infrarot aussagekräftiger finde.
Falls du nicht rechnen willst, wie wäre es mit einer Tabelle? 70-140 sind ja nur 70 Werte, 256 sind ja problemlos möglich.
P.S. den Umstieg von Bascom auf C habe ich auch wegen der rechnerrei gemacht, und nie bereut. So schlimm fand ich das auch nicht, mit der Einarbeitungszeit.
NTC mit Parallel- und, je nach Widerstandsbereich, Reihenwiderstand. Messbrücke, OP und an den ADC des uC.
Oder einen PT1000 .... ebenfalls Brücke und OP.
Gruss
Harry
Ich programmiere mit AVRCo
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.
![]()
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: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}, };
Das bedeutet, statt 37 Versuchen beim kt81_210 brauche ich nur log(37)/log(2) = 6.
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.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; }
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); }
Geändert von schorsch_76 (23.09.2015 um 19:37 Uhr)
Lesezeichen