Forum: Mikrocontroller und Digitale Elektronik Hilfe: Problem mit Arduino Mega - mehrere Spannungen messen


von Dirk T. (helipage)


Lesenswert?

Hallo zusammen...

Möchte mit einem Arduino Mega 2560 und TFT-Touch Display eine 
Bord-Control (soll Batteriespannungen messen, Inhalt von Wassertanks und 
Temperaturen anzeigen) für mein Wohnmobil realisieren.

Grundgerüst im Code steht auch, nun geht es an die Unterfunktionen.
Möchte gern über Spannungsteiler 4 verschiedene Spannungen messen.
Diese liegen an den AnalogIN Pins A0-A3 an.

Wenn ich nun mit analogRead (PIN) den Wert z.B. an A2 einlese und 
speichere funktioniert dies, Wert wird auch angezeigt.
Nun hab ich das um einen 2. Eingang (A3) erweitert.

Wenn ich mir nun beide Werte anzeigen lasse, sind beide gleich.
Lege ich nur an A2 eine Spannung an, so wird dieser Wert sowohl in der 
Anzeige für A2 als auch in der Anzeige für A3 angezeigt.
Umgekehrt (Spannung liegt nur an A3, oder A0 oder A1 an) gleiches Bild.

Hier mal der Code für die Abfrage von 2 Spannungen (an A2 und A3).
Hoffe, ihr könnt mir sagen, wo der Fehler liegt...
(Messung von A2 ist zu Testzwecken hier auskommentiert)

Danke und Grüße
Dirk


void Spannung()
  {
    // Fahrzeug-Batterie (Pin A2)
//    sensorVoltFahr = (analogRead(PinBatFahr)); // Messen der Spannung 
mit Korrekturwert
//    MessFahr=(0.9*MessFahr)+(0.1*sensorVoltFahr);     //Tiefpassfilter 
gegen das Springen der Spannungsanzeige
//    BatFahr = ((MessFahr / 1023.0) * 23.8);            // Berechnung 
der variablen Batteriespannung+ Korrekturwert

    // Aufbau-Batterie (Pin A3)
    sensorVoltAufbau = (analogRead(PinBatAufbau)); // Messen der 
Spannung mit Korrekturwert
    MessAufbau=(0.9*MessAufbau)+(0.1*sensorVoltAufbau); 
//Tiefpassfilter gegen das Springen der Spannungsanzeige
    BatAufbau = ((MessAufbau / 1023.0) * 23.8);            // Berechnung 
der variablen Batteriespannung+ Korrekturwert
  }

von Ralf D. (doeblitz)


Lesenswert?

War da nicht irgendwie so was in der Art, dass nach der Umschaltung des 
Kanals der erste Wert Müll ist? Also erst einen Dummy-Read auf dem neuen 
Kanal machen, danach dann verwendbare Werte bekommen.

Ich war jetzt aber zu faul, das hier mal selbst mit einem Mega2650 
auszuprobieren (Hüstel).

von Karl M. (Gast)


Lesenswert?

Hallo,

hast du auch die Impedanz der Spannungsquelle, so wie im Datenblatt 
beschrieben, beachtet?
Dann wird dein Code noch Fehler haben und nicht genügend Zeit zwischen 
den Wechsel der ADC Eingänge abwarten.

von R. M. (Gast)


Lesenswert?

Ralf D. schrieb:
> War da nicht irgendwie so was in der Art, dass nach der Umschaltung des
> Kanals der erste Wert Müll ist? Also erst einen Dummy-Read auf dem neuen
> Kanal machen, danach dann verwendbare Werte bekommen.

Das ist so, wenn man die Referenzspannung wechselt. Umschaltung zwischen 
den Eingängen ist jederzeit möglich, ohne Messwerte verwerfen zu müssen.

von Stefan F. (Gast)


Lesenswert?

Aus welchen Widerständen bestehen deine Spannungsteiler und in welchen 
Intervallen (wie oft) musst du mindestens messen?

von Dirk T. (helipage)


Lesenswert?

Wow...
So schnell Antworten, und das an einem Sonntag Abend :-)

Also: Spannungsteiler besteht aus 100K und 27K Widerstand (also 1:3), 
das sollte ja für 12V ausreichend sein.

Referenzspannung ist (erstmal) auf Default gesetzt, das es nicht auf 
100%ige Genauigkeit ankommt.

Die beiden Spannungen werden gemessen wie im Code, dann Rücksprung in 
den Code für die Anzeige.
Hier werden erst die Unterprogramme für Lüfterüberwachung und Buzzer 
ausgeführt und dann die Messung der Spannungen:


   /********************************************************/
    /*                                                      */
    /*           Anzeige der Akkuseite                      */
    /*                                                      */
    /********************************************************/




    void Akku()
    {
     myGLCD.clrScr();                                 // Löschen des 
Bildschirminhals
     myFiles.loadBitmap(0, 176, 64, 64,"home.raw");   //Button zeichnen, 
hier Homebutton: zurück zum Hauptmenue
     myGLCD.setColor(255, 255, 255);
     myGLCD.setFont(arial_normal);
     myGLCD.print("12V Versorgung",80, 200);
     myFiles.loadBitmap(200, 40, 81, 128,"battery.raw");

    while (true)
    {
    FanControl();               //Lüfter werden in dieser Schleife 
gesteuert
    Buzzer();                   //Wasserstandüberwachung
    Spannung();                 // Messung der Spannung




    /*                 Anzeigen der Spannung  Fahrzeug-Batterie 
*/
    /* Einstellung des Abstands für die Batterie im Display 
*/

    int DisplayZehnerStelleVolt;
    if (BatFahr < 10)
    DisplayZehnerStelleVolt = 36;
    if (BatFahr < 10)
    myGLCD.print(" ", 20,35);        //Leerzeichen drucken damit 
Zehnerstelle nicht auf Display stehen bleibt
    else
    DisplayZehnerStelleVolt = 20;

    myGLCD.setFont(Sinclair_S);
    myGLCD.setColor(0, 128, 255);
    myGLCD.print("Bord-Batterie", 20,15);
    myGLCD.setFont(DotMatrix_M);
    if (BatFahr >= 12.95){ myGLCD.setColor(VGA_LIME);}
    if ((BatFahr < 12.94) && (BatFahr >=11.51)){ 
myGLCD.setColor(VGA_YELLOW);}
    if (BatFahr < 11.50){ myGLCD.setColor(VGA_RED);}
    myGLCD.printNumF(BatFahr, 2, DisplayZehnerStelleVolt, 35);
    myGLCD.print("V", 104, 35);
    myGLCD.setColor(VGA_SILVER);
    myGLCD.drawRect(15, 7, 30, 10);
    myGLCD.drawRect(110, 7, 125, 10);
    myGLCD.drawRect(10,10,130,60);


    /*                 Anzeigen der Spannung  Aufbau-Batterie 
*/
    /* Einstellung des Abstands für die Batterie im Display 
*/

    int DisplayZehnerStelleVolt2;
    if (BatAufbau < 10)
    DisplayZehnerStelleVolt2 = 36;
    if (BatAufbau < 10)
    myGLCD.print(" ", 20,35);        //Leerzeichen drucken damit 
Zehnerstelle nicht auf Display stehen bleibt
    else
    DisplayZehnerStelleVolt2 = 20;

    myGLCD.setFont(Sinclair_S);
    myGLCD.setColor(0, 128, 255);
    myGLCD.print("Aufbau-Batterie", 12,95);
    myGLCD.setFont(DotMatrix_M);
    if (BatAufbau >= 12.95){ myGLCD.setColor(VGA_LIME);}
    if ((BatAufbau < 12.94) && (BatAufbau >=11.51)){ 
myGLCD.setColor(VGA_YELLOW);}
    if (BatAufbau < 11.50){ myGLCD.setColor(VGA_RED);}
    myGLCD.printNumF(BatAufbau, 2, DisplayZehnerStelleVolt2, 115);
    myGLCD.print("V", 104, 115);
    myGLCD.setColor(VGA_SILVER);
    myGLCD.drawRect(15, 87, 30, 90);
    myGLCD.drawRect(110, 87, 125, 90);
    myGLCD.drawRect(10,90,130,140);


     if (myTouch.dataAvailable())
    {
      myTouch.read();
      x=myTouch.getX();
      y=myTouch.getY();

      if (((y>=177) && (y<=239))  &&  ((x>=1) && (x<=63)))  // Abfrage 
Touchfläche Startbildschirm mit Uhr

        {
        myGLCD.setColor (0, 255, 0);
        myGLCD.fillRoundRect(1, 176, 64, 239);
        myGLCD.clrScr();               // Löschen des Bildschirminhals
        break;
        Hauptmenue();
        }

    }

      }

  }

von Stefan F. (Gast)


Lesenswert?

Dein Spannungsteiler ist zu hochohmig, schau mal diesbezüglich ins 
Datenblatt des µC. Der S&H Kondensator im Innern des ADC wird nicht 
schnell genug umgeladen, daher bekommst du völlig falsche 
Messergebnisse.

Was hast du Dir dabei gedacht, deinen Quelltext für die Displayausgaben 
zu zeigen, aber die für den ADC relevanten Teile auszulassen? Sollen wir 
das selbst zusammen puzzeln?

Ich kann am gezeigten Code auch nicht erkennen, in welchen Intervallen 
du den ADC ausliest. Diese Frage ist noch offen.

Jedenfalls vermute ich, dass du den ADC nicht tausende mal pro Sekunde 
brauchst. Dann kannst du deine Spannungsteiler mit 100nF Kondensatoren 
(vom ADC Eingang nach GND) stabilisieren, das müsste genügen, um den S&H 
Kondensator schnell genug umzuladen. Sorge du nur dafür, dass zwischen 
den Wiederholungen genug Pause ist, damit die neuen Kondensatoren 
nachgeladen werden können.

von Dirk T. (helipage)


Lesenswert?

Moin Stefanus...

Sorry, hab von Arduino Programmierung noch recht wenig Ahnung.
Hab das Grundgerüst für dieses Projekt von jemandem bekommen, der es in 
seinem Wohnwagen erfolgreich laufen hatte.
Wollte es nun nach meinen Wünschen anpassen.

Hab im Quelltext nichts weiter zum ADC gefunden.

Eine Abfrage der Spannungswerte z.B. 1x pro Sekunde würde vollkommen 
reichen.


Grüße
Dirk

von Stefan F. (Gast)


Lesenswert?

Wie geht es jetzt weiter?

von Dirk T. (helipage)


Lesenswert?

Moin...

Werde jetzt erstmal versuchen, Deine Vorschläge mit den Kondensatoren 
und dem geänderten Spannungsteiler umzusetzen.

Vielleicht hilft das ja schon weiter.

Grüße
Dirk

von Stefan F. (Gast)


Lesenswert?

Entweder Kondensatoren hinzufügen oder die Spannungsteiler niederohmiger 
machen. Beides zusammen wäre übertrieben.

Mache die Spannungsteiler so, dass der kleinere Widerstand weniger als 
10k Ohm ab. Dann bist du ihm Rahmen der Spezifikation.

von Dirk T. (helipage)


Lesenswert?

Hallo Stefanus

Danke erstmal für Deine Hilfe !


Grüße
Dirk

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.