Jetzt habe ich auch die Umrechnung des gemessenen Widerstand in eine Temperatur eingebaut.
Was ich mit einem angeschlossenen Pt100 an Messergebnissen erhalte sieht vielversprechend aus.
Das Programm für den Arduino:
/*
Pt100 Temperaturmessung mit HX711 in Vierleiterschaltung
Datenblatt: https://cdn.sparkfun.com/datasheets/Sensors/ForceFlex/hx711_english.pdf
Es wird Kanal B des HX711 mit einer Eingangsverstärkung von 32 verwendet.
Anschluss HX711:
VCC an Arduino 5V, GND an Arduino GND
SCK an Arduino A0, DT an Arduino A1
Widerstand 15kΩ zwischen E+ und B+ des HX711 anschließen
Widerstand 15kΩ zwischen E- und B- des HX711 anschließen
Messwiderstand (60 ... 400Ω)zwischen B+ und B- des HX711 anschließen
Bevor eine Temperaturmessung durchgeführt werden kann, muss die Messschaltung erst abgeglichen werden.
Hierzu werden Abgleichwiderstände benötigt deren Tolerenz möglichst besser als 1% ist.
Zuerst wird die untere Messbereichsgrenze abgeglichen. (Widerstand z.B 62Ω)
Dazu wird ein Widerstand, dessen Wert nahe an der unteren Messbereichsgrenze
liegt, an den HX711 als Messwiderstand angeschlossen und das Programm gestartet.
Das Programm liefert einen Messert der per Copy&Paste der Variablen 'Uu' zugeordnet wird.
Der Widerstandswert des verwendeten Messwiderstandes wird der Variablen 'Ru' zugeordnet.
Dann das Programm neu auf den Arduino übertragen.
Dann wird die obere Messbereichsgrenze abgeglichen. (Widerstand z.B 4x 100Ω in Reihenschaltung)
Dazu wird ein Widerstand, dessen Wert nahe an der oberen Messbereichsgrenze
liegt, an den HX711 als Messwiderstand angeschlossen und das Programm erneut gestartet.
Das Programm liefert einen Messert der per Copy&Paste der Variablen 'Uo' zugeordnet wird.
Der Widerstandswert des verwendeten Messwiderstandes wird der Variablen 'Ro' zugeordnet.
Dann das Programm neu auf den Arduino übertragen.
Damit ist der Abgleich abgeschlossen und man kann sich die Messergebnisse mit anderen (bekannten) Widerständen,
deren Wert zwischen den Messbereichsgrenzen liegt, anschauen oder gleich einen Pt100 Thermometer anschließen.
Die beiden 15kΩ Widerstände, das HX711 Modul und die Werte der Variablen Uu, Uo, Ru, Ro gehören jetzt zusammen.
Wird ein Teil ausgetauscht, ist ein neuer Ableich erforderlich.
Um einen neuen Ableich zu ermöglichen sind die Werte der Variablen Uu, Uo, Ru, Ro auf 0 zu setzen
und das Programm neu hochzuladen.
Messbereichsgrenze unten 60Ω - Ru
Messbereichsgrenze oben 400Ω - Ro
Quelle der Formeln zur Umrechnung von Widerstand nach Temperatur
http://www.abmh.de/pt100/index.html#pt100_Werte
Die Messgenauigkeit ist stark von der Genauigkeit der verwendeten Widerstände beim Abgleich abhängig.
Werden dabei Widerstände mit einer Toleranz von ±1% eingesetzt ergibt das rechnerisch bei der Temperatur
einen Fehler von ±1.48°C an der unteren Messbereichsgrenze und ±13.92°C am oberen Ende.
Es lohnt also Widerstände mit einer Toleranz von ±0.1% zu beschaffen um damit den Abgleich durchzuführen.
Der mögliche Fehler bei der Temperatur wird dann auf 1/10 reduziert.
Rechenbeispiel mit einem 400Ω Widerstand und einer Toleranz von ±1%.
Der Widerstandwert liegt zwischen 396Ω und 404Ω.
396Ω -> 869.72°C
400Ω -> 883.55°C
404Ω -> 897.47°C
Version 0.0 vom 04.11.2016
*/
#include "HX711.h" //https://github.com/bogde/HX711
#define UMIN 900000
#define UMAX 8000000
#define RMIN 60.0
#define RMAX 400.0
const long Uu = 0; // Rohmesswert unteres Ende
const long Uo = 0; // Rohmesswert oberes Ende
const float Ru = 0.0; // Widerstandswert unteres Ende
const float Ro = 0.0; // Widerstandswert oberes Ende
long Umess;
float Rx, T;
HX711 get_U;
void setup() {
int i;
long buf = 0;
long U = 0;
Serial.begin(115200);
Serial.println(F("HX711 Temperaturmessung mit Pt100 Widerstandsthermometer"));
get_U.begin(A1, A0, 32);
// Abgleich Messbereichsgrenze unten
if (Uu <= UMIN || Ru == RMIN) {
Serial.println(F("Widerstand fuer untere Messbereichsgrenze eingesetzt ??"));
Serial.println(F("Messung fuer Messbereichsgrenze unten laeuft - bitte warten ..."));
for (i = 0; i < 5; i++) {
U = get_U.read_average(40);
buf = buf + U;
Serial.print(U); Serial.print(" ");
}
if (buf / 5 < UMIN || buf / 5 > UMAX) {
Serial.println(); Serial.println();
Serial.println(F("Messfehler, bitte Schaltung ueberpruefen"));
while (1);
}
else {
Serial.println(); Serial.println();
Serial.print(F( "Bitte "));
Serial.print(buf / 5);
Serial.println(F( " bei Variable 'Uu' und den Wert des eingesetzten Widerstandes in Ohm bei Variable 'Ru' eintragen "));
Serial.println(F("Dann das Programm neu hochladen"));
Serial.println();
while (1);
}
}
// Abgleich Messbereichsgrenze oben
if (Uo <= UMIN || Ro == RMIN) {
Serial.println(F("Widerstand fuer obere Messbereichsgrenze eingesetzt ??"));
Serial.println(F("Messung fuer Messbereichsgrenze oben laeuft - bitte warten ..."));
for (i = 0; i < 5; i++) {
U = get_U.read_average(40);
buf = buf + U;
Serial.print(U); Serial.print(" ");
}
if (buf / 5 < UMIN || buf / 5 > UMAX) {
Serial.println(); Serial.println();
Serial.println(F("Messfehler, bitte Schaltung ueberpruefen"));
while (1);
}
else {
Serial.println(); Serial.println();
Serial.print(F( "Bitte "));
Serial.print(buf / 5);
Serial.println(F( " bei Variable 'Uo' und den Wert des eingesetzten Widerstandes in Ohm bei Variable 'Ro' eintragen "));
Serial.println(F("Dann das Programm neu hochladen"));
Serial.println();
while (1);
}
}
// Prüfung der Abgleichwerte
if ( Uu < UMIN || Uu > UMAX || Uo < UMIN || Uo > UMAX || Ru < RMIN || Ru > RMAX || Ro < RMIN || Ro > RMAX ||
Uu > Uo || Uo < Uu || Ru > Ro || Ro < Ru) {
Serial.println(F( "Abgleichfehler - Bitte Abgleich wiederholen"));
Serial.println();
while (1);
}
else {
Serial.println(F( "Abgleich plausiebel"));
Serial.println();
}
}
void loop() {
float k1, k2, k3, k4, k5, k6, k7, k8, k9;
// Messwert für die Spannung an Rx einlesen
Umess = get_U.read();
// Aus der gemessenen Spannung den Widerstand Rx ausrechnen
if (Umess >= UMIN && Umess <= UMAX) {
Rx = ((((Ro - Ru) / (Uo - Uu)) * (Umess - Uu)) + Ru );
//Serial.print("Umess = "); Serial.print(Umess); Serial.print(" ");
Serial.print("R = "); Serial.print(Rx, 3); Serial.print(" Ohm -> ");
// Temperatur für Rx >= 100 Ohm berechnen
if (Rx >= 100.0) {
k1 = 3.90802 * pow(10, -1);
k2 = 2 * 5.802 * pow(10, -5);
k3 = pow(3.90802 * pow(10, -1), 2);
k4 = 4.0 * (pow(5.802 * pow(10, -5), 2));
k5 = Rx - 100.0;
k6 = 5.802 * pow(10, -5);
k7 = k1 / k2;
k8 = (k3 / k4) - (k5 / k6);
k9 = sqrt(k8);
T = k7 - k9;
}
// Temperatur für Rx < 100 Ohm berechnen
else {
k1 = pow (Rx, 5) * 1.597 * pow(10, -10);
k2 = pow (Rx, 4) * 2.951 * pow(10, -8);
k3 = pow (Rx, 3) * 4.784 * pow(10, -6);
k4 = pow (Rx, 2) * 2.613 * pow(10, -3);
k5 = 2.219 * Rx - 241.9;
T = k1 - k2 - k3 + k4 + k5;
}
Serial.print("T = "); Serial.print(T, 3); Serial.println(" GrdC");
}
else {
Serial.println("Messfehler");
}
delay(1000);
}
Es gibt im Code sicherlich noch viel Potential für Optimierungen. Besonders bei der Berechnung der Temperatur. Aber dort habe ich versucht den Code gemäß den Formeln aus der verlinkten Webseite nachvollziehbar zu gestalten. Vieles was jetzt noch gerechnet wird könnte man als Konstante hinterlegen.
Der Anschlussplan:
Mein Testmodul mit dem HX711 sieht aus wie in diesem Angebot.
Es gibt auch andere Module mit evtl. anderer Schaltung. Davon habe ich aber keine und konnte deshalb auch nicht testen.
Gruß Peter