TERWI's Hexenküche hat wieder was ausgebrutzelt ....
Neben meinem LiPo-Monitor zur Spannungsmessung der einzelnen Zellen war es letztendlich die Konsequenz, auch deren Temperatur zu erfasssen.
Muss nicht, aber "Nice to have!"
Ich stell euch das hier mal solo vor, denn es gibt sicherlich etliche unter euch, welche Temperaturen entweder so über den Daumen oder sogar relativ genau erfassen wollen / möchten / müssen.
Ein entsprechendes PDF der Schaltung ist angehängt.
Wie ihr seht, eine relativ simple Schaltung mit nur wenigen Bauteilen, die dennoch recht / sehr genau ist: Immerhin 1/8 Grad Auflösung am Analog-Eingang eines Arduino. Wenn man für alle Bauteile samt einer kleinen Vero-Board-Platte 10 € ausgibt, war's schon teuer ....
Messbereich: Weit unter 0°C bis knapp über 100°C - das sollte für viele Fälle reichen. In 0,125 V Schritten.
Schaltungsbeschreibung:
Alle Bauteile sind gängig und sowohl in bedrahteter Form wie auch in SMD erhältlich.
Die Widerstände entsprechen der E12 Reihe.
R1 und R3 bzw. R2 und R4 sollten schon 1% Toleranz haben oder besser für max. Genauigkeit auf gleiche Werte ausgemessen sein.
R4 und R5 sind unkritisch, der min. Strom durch die Referenzen sollte > 1mA sein.
P1 und P2 sollten Mehrgang-Cermet-Trimmer für akkurate Einstellung sein. (Kann man auch weglassen, s. u.)
D3 und D4 sind irgendwelche Standard-Kleinleistungsdioden. Dito.
Auch der OP ist unkritisch. Kann ein einfacher 741 sein oder auch ein Doppel-OP - zum drinnen und draussen messen ?!
Der LM335 ist von Haus aus ein hochpräziser, kalibrierbarer Temperatur-Sensor mit einer Spannngsdifferenz von 10mV/K.
Bei einem Strom von min. 1mA wird damit bei 25°C eine Spannung von 2,982V stabil erzeugt. (Einstellbar, wie hier gezeigt)
Der LM 336 ist von Haus aus eine hochstabile Zener-Referenz-Diode mit einer Spannung von 2,490V bei 25°C. Dito einstellbar.
Wer es nicht so genau braucht, kann auch P1, P2 und D3, D4 weglassen. Die "Einstell-Beinchen" vom LM 335/6 bleiben dann frei/offen.
Wer selber rechnen möchte bei anderen Betriebs- und Ausgangsspannungen / erforderlicher Auflösung:
R5, R6 = (Ub - Uzener) / > 1mA
R1 = R3, R2 = R4
Vout = R2 / R1 x (V2 - V1)
Der Arduino sampelt an seinen Analog-Eingängen mit 10-Bit - also eine Auflösung bei max. 5V / 1024 = 0,0078125 V / Schritt. Theorethisch....
Wer nun mit anderer Einstellung und / oder Verstärkung auf andere Ausgangsspannungen kommt, rechnet einfach:
Sample-Wert = Vout / 5V x 1024
Ich hoffe, vielen von euch damit geholfen zu haben.
Korrekturen und Anmerkungen willkommen.
Fast vergessen:
Den eigentlichen Temperatur-Sensor D1 kann man natürlich auch über ein längeres Kabel irgendwo anders hin verlegen.
Die Leitung sollte dann so etwas wie ein geschirmtes, 2-poliges Audio-Kabel sein, um Störungen auf langen Leitungen zu vermeiden.
Als Stecker kommen z.B. 2,5mm "Stereo"-Klinken in Betracht.
Und wie liest man das ganze am / mit dem Arduino aus ?
Hier ein Beispiel:
(Kommentare sind in Englisch - hab ich mir so angewöhnt ...)
#include <Streaming.h>
// var's for collecting average analog-value
#define MINANALOGREADSEQUENCE 25 // !!! this is a similiar delay time in ms for repeated use of analogRead
// a value of 25 results in max. 40 samples/second
// increase (up to 100 ?) will decrease cpu load in the loop !!
int time2sample = 0; // 0 (or <= 333, see bleow) = off, no reading
byte analogReadPin = 0; // the desired pin
byte nvalreaded = 0; // normally only internal use
long analogval = 0; // the the average value at least
long millis_lastval = 0; // normally only internal use
void setup()
{
Serial.begin(9600);
// ...
}
// used for checking valid keypress and
// for collecting average analog-value
long millis_act;
void loop()
{
// ... evaluate Serial for commands / values
// ... do something else in the loop ...
millis_act = millis();
// collect an average analog-value for a defined time
// set "time2sample" to 0 (or < 333) stops reading values
if (time2sample > 333) // 333 only to keep the monitor away from to much running
{ if (nvalreaded == 0) millis_lastval = millis_act; // remind time
if ((millis_lastval + nvalreaded * MINANALOGREADSEQUENCE) <= millis_act)
{ analogval = analogval + analogRead(analogReadPin); // add to value
nvalreaded++; // remind number of addings
}
if ((nvalreaded * MINANALOGREADSEQUENCE) >= time2sample) // Time to evaluate ?
{ analogval = analogval / nvalreaded + 0.5; // calc average value (0.5 for round up)
// ---> here we have the average result !
Serial << "Analog-value on Pin " << analogReadPin << " - Average value: " << analogval << " for " << millis_act - millis_lastval << " ms from " << nvalreaded << " values" << endl;
// ---> use "analogval" for your intended purpose
nvalreaded = 0; // reset the counter .... we start again
analogval = 0; // do not forget to delete the value ! It will fudge ther new result !
}
}
// ... do something else in the loop
}
Anwendung:
Je nach dem, wer was wie macht,
- analogReadPin übergeben (oder fest setzen)
- time2sample dito (0 oder <= 333 macht keine Prüfung)
-> analogval auslesen.
Das funktioniert hier bei mir ganz ausgezeichnet und bringt stabile (Mittel-) Werte ohne "Gezappel" !
Die vorgegebene Sample-Zeit ist dann auch die für Rückgabezyklen.
Oder nur einmal lesen und dann time2sample wieder auf 0 setzen.
Da blockiert kein Delay und es bleibt Zeit genug für anderes in der Loop.
Ist auch nicht Zeitkritisch.
TempMessung.pdf (97.3 KB)