Ich habe natürlich damit wieder meine Test´s gemacht und bin mit dem Messberreich 0-16 Volt seeeehr zufrieden.
Aber dann habe ich den 0-45 Volt Messeingang benutzt, das gefällt mir überhaupt nicht. Ich habe natürlich auch die Umrechnung auf diesen Teiler in der Software angepasst. Man sieht auf der Schaltung dem 100KOhm Messeingang oberhalb dess 30KOhm Messeingang.
Da ist das Messergebnis nicht zwei Stellen hinterm Komma um höchstens 1-2 Zähler falsch, sondern es ist an der ersten Stelle hinterm Komma schon um 1-2 Zähler falsch. UND der Fehler geht nicht über den ganzen Spannungsbereich gleichmässig in der selben Abweichung, dann wäre es ja rel. einfach, sondern wenn ich korrekt umrechne wird der Messfehler nach oben hin kleiner. Wenn ich die Umrechnung anpasse, dass der Fehler im Unteren Bereich weg ist, dann stellt er sich nach oben hin immer deutlicher ein. Wo muss ich den Grund für diese Abweichung suchen? Ich finde gerade keinen Ansatz. Der Unterschied ist ja nur, dass im Spannungsteiler der 30KOhm Widerstand gegen einen 100KOhm ersetzt wird.
Hier ist noch der Code. Gleich oben im LOOP sind die zwei Zeilen, die ich im Moment noch austausche, je nachdem, was ich für einen Messteiler teste.
Code: Alles auswählen
#include <LiquidCrystal_I2C.h> // LCD Display
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
const byte ANALOG_PIN = A0; // Hier wird der Name vom Messeingang festgelegt
float max31 = 0; // Der Speicher für den ausgelesenen Analogwert vom Messbuchse
float max31alt = 0;
float max32 = 0; // Der Speicher für den ausgelesenen Max-Analogwert vom ADC
float min31 = 0; // Der Speicher für den ausgelesenen Analogwert vom Messbuchse
float min31alt = 1023;
float min32 = 0; // Der Speicher für den ausgelesenen Max-Analogwert vom ADC
float durchschnitt = 0;
unsigned long startzeit = 0;
unsigned long endzeit = 0;
unsigned long Sekundenablauf01 = 0; // Messung erneuern nach eine Sekunde
const unsigned long Pausezeit01 = 1000;
//====================================================================================
void setup(void) {
analogReference(EXTERNAL); // Externe Referenzspannung am AREF 4,096Volt
Serial.begin(9600);
pinMode(ANALOG_PIN, INPUT); // Input vom Messteiler
lcd.begin(20, 4);
lcd.backlight();
lcd.clear();
// Display Maxwert
lcd.setCursor (0, 0);
lcd.print (F("Maximalwert"));
lcd.setCursor (18, 0);
lcd.print (F("V"));
// Display Minwert
lcd.setCursor (0, 1);
lcd.print (F("Minimalwert"));
lcd.setCursor (18, 1);
lcd.print (F("V"));
// Display Durchschnitts Wert
lcd.setCursor (0, 2);
lcd.print (F("Normalwert"));
lcd.setCursor (18, 2);
lcd.print (F("V"));
}
//===================================================================================
void loop(void) {
//--------------------------Startzeit für den Laufzeittest-----------------------------------------------
startzeit = micros();
//-----------------------Nach einer Sekunde neue Messung starten-----------------------------------------
if (millis() - Sekundenablauf01 >= Pausezeit01) {
//max32 = ((max31alt * 44) / 1000); // 0-1023 x 0,044 für 45 Volt
max32 = ((max31alt * 16) / 1000); // 0-1023 x 0,016 für 16 Volt
lcd.setCursor (13, 0);
lcd.print (F(" "));
lcd.setCursor (13, 0);
lcd.print (max32);
max31alt = 0;
//min32 = ((min31alt * 44) / 1000); // 0-1023 x 0,044 für 45 Volt
min32 = ((min31alt * 16) / 1000); // 0-1023 x 0,016 für 16 Volt
lcd.setCursor (13, 1);
lcd.print (F(" "));
lcd.setCursor (13, 1);
lcd.print (min32);
min31alt = 1023;
lcd.setCursor (13, 2);
lcd.print (F(" "));
lcd.setCursor (13, 2);
durchschnitt = (max32 - min32) / 2;
if (max32 == min32) {
durchschnitt = 0;
}
lcd.print (durchschnitt);
Sekundenablauf01 = millis();
//Serial.println(F("Datenausgabe aufs Display"));
}
// -----------------------------Max- und Minwert messen und Maxwert sichern----------------------
max31 = analogRead (ANALOG_PIN); // Analogen Eingang A0 auslesen
min31 = max31;
if (max31 >= max31alt) {
max31alt = max31;
}
// -----------------------------Minimalwert sichern----------------------------------------------
if (min31 <= min31alt) {
min31alt = min31;
}
// -----------------------------------Laufzeittest----------------------------------------------
endzeit = micros();
//Serial.println(endzeit - startzeit);
}
Ich stelle mir übrigens vor, alles noch ein wenig umzubauen. Ich möchte den 16 Volt Eingang lassen wie er ist, aber den 45 Volt Eingang auf den A1 Pin verlegen. Der bekommt dann eben einen eigenen Spannungsteiler (10K & 100K) und eine eigene Schutzdiode. Das wäre schon mal der geänderte Plan.

- Arduino UNO Messgerät 16 + 45 Volt.JPG (138.45 KiB) 4485 mal betrachtet
Dann kann ich in der Software einfach nur schauen, ob auf dem A0 oder dem A1 Eingang Spannung anliegt, und die Umrechnung automatisch anpassen. Also immer wenn Spannung auf A0 anliegt, die Umrechnung "min32 = ((min31alt * 16) / 1000);" verwenden und wenn die Spannung auf A1 anliegt, die Umrechnung "min32 = ((min31alt * 44) / 1000); verwenden. Und in der vierten Zeile vom Display zeige ich an, welche Max Spannung gerade aktiviert ist. Also bei Spannung an A0 = Max 16 Volt, und bei Spannung an A1 = Max 45 Volt.
Aber erst mal brauche ich eine Lösung für die Abweichung im höheren Messbereich.
Wenn ich dort die Umrechnung auf "min32 = ((min31alt * 446) / 10000);" ändere, bin ich im unteren Bereich super genau, aber nach oben hin wirds immer ungenauer.
Eigentlich ist aber die 44 in der Umrechnung schon richtig.
4,096 Volt x 11 = 45,0560 / 1024 =
0,0440
Franz