- 3D-Druck Einstieg und Tipps         
Seite 9 von 9 ErsteErste ... 789
Ergebnis 81 bis 85 von 85

Thema: Projekt vorgestellt: Strommessung im Haushalt bis 30A mit Arduino

  1. #81
    Benutzer Stammmitglied
    Registriert seit
    19.07.2011
    Beiträge
    66
    Anzeige

    LiFePo4 Akku selber bauen - Video
    Entschuldigung für die Verwirrung. Der Stromwandler ist der gleiche geblieben. Ich habe lediglich den 6 Volt Trafo für die Spannungsmessung gegen einen 12 Volt Trafo mit viel mehr Leistung getauscht. Das hat ergeben dass der Sinus für die Spannungsmessung jetzt sinusförmig angezeigt wird. Mit dem 6 Volt Trafo hatte ich in dem Sinus leichte Ecken drin. Die ersten beiden Diagramme in der Excel Tabelle sind mit dem alten 6 Volt Trafo der einzige Unterschied ist, dass ich bei der ersten Messung keinen Kondensator drin habe und bei der zweiten Messung ein 10 Mikrofarad Kondensator. Bei dem dritten Diagramm habe ich den 12 Volt Trafo für die Spannungsmessung eingebaut + den Kondensator an dem Stromwandler und als Last habe ich eine Leuchtstofflampe angeschlossen.

  2. #82
    Erfahrener Benutzer Fleißiges Mitglied Avatar von avr_racer
    Registriert seit
    01.04.2014
    Ort
    MecklenburgVorpommern
    Beiträge
    174
    Gut also ist der Sachstand wieder gleich und mit den Änderungen hat sich also nicht wirklich viel getan, dann warten wir mal bis die neu Messspule da ist und gucken dann weiter.

  3. #83
    Benutzer Stammmitglied
    Registriert seit
    19.07.2011
    Beiträge
    66
    Fertig?
    Also ich habe lange weitergetestet und das Ergebnis ist, dass ich die Verschiebung durch den Trafo über die Software rausrechne.
    Der Messwert ist ganz passabel, wobei ich festgestellt habe, dass ich kein geeichtes Messgerät habe, um einen 100%igen Kontrollwert zu haben.
    Eine Glühlampe ist einfach, aber eine Waschmaschine mit "Frequenzumrichter" ist für mich nicht mehr sicher messbar. Auch hierfür extra gekaufte digitale Hutschienenzähler haben untereinander Abweichungen von mehreren % angezeigt.
    Hier nun das endgültige Programm:
    Datei: LeistMess_V3.0.ino

    Code:
    /*
       Zur Leistungsmessung in einer Elektroverteilung.
       Es werden mehrere Leistungen gemessen und über I2C zur Weiterverarbeitung weitergegeben.
       Herzstück ist ein Arduino Nano. Über SPI-Bus sind pro Messung ein MCP3301 A/D-Wandler angeschlossen,
       welcher wiederum an eine Stromzange angeschlossen ist. Die Leistungsmessung ist zur Zeit nur für Wechselspannung.
       Die Spannung wird über einen Trafo einphasig gemessen und mit den gemessenen Strömen multipliziert.
       Weitere Infos zur Messung siehe weiter unten.
    */
    
    // ProgrammName: LeistMess
    // Kurzbeschreibung: Strommessung, Effektivwertbildung, Datenaufbereitung und Übertragung
    // Datum: 04.03.2017 / Version: 1.0 - mit serieller Ausgabe
    // Datum: 10.07.2017 / Version: 1.1 - mit Ausgabe über I2C
    // Datum: 03.04.2018 / Version: 1.2 - I2C Ausgabe angepasst
    // Datum: 20.04.2018 / Version: 1.3 => Umstellung auf Leistungsmessung
    // Datum: 29.08.2018 / Version: 2.0 - Leistungsmessung eingebaut; Kalibrierungsmenü angepasst
    // Datum: 30.08.2018 / Version: 2.1 - 230V Spannung über I2C hinzugefügt; I2C-Adresse über Konstante
    // Diverse Änderungen und Tests
    // Datum: 07.03.2019 / Version: 3.0 - an Nano angepasst
    
    // Autor: Jürgen Stähr
    
    //Programm Version:
    const String Version = "3.0";
    
    //D12 -> Pin 50
    //D13 -> Pin 52230
    
    // Konfiguration
    //******* ACHTUNG ********** Hier an die vorhandene Hardware anpassen ******** ACHTUNG ***************
    const int csSpg = 8;          // Pin Nummer des CS für die Spannungsmessung hier eintragen
    const int PinKal = 17;           // PIN Nummer für die Kalibrierung (Für Kalibrierung auf Masse ziehen)
    const int ADCAnz = 2;           // Anzahl aller angeschlossenen ADC (Spannung- und Strommessung)
    const int CRundAnz = 4;         // Anzahl der Messungen je Sekunde
    const int I2C_Adr = 4;          // I2C Adresse für die Datenausgabe als Slave
    // Pin Nummern der cs Eingänge der ADC. Erlaubt sind 2 - 10 (digital Pins)
    //                                                  14 - 19 (analogPins A0 - A5)
    //const int cs[] = {10, 10,10,10,10,10,10,10,10,10};  // das geht auch, macht aber keinen Sinn
    const int cs[] = {9, 10}; // Muss mit ADCAnz übereinstimmen oder größer sein
    const int Shunt[] = {100, 56}; // Entsprechend dem cs[] Array die Widerstände eintrage//                   16A  16A   9A  16A  28A  9A  28A  9A  16A
    
    
    
    /*
         TESTPLATINE 2-Kanal:
         Kanal 7 = 100 Ohm
         Kanal 8 =  56 Ohm
    
         Kanal:  Bezeichnung: Phase "L1"
       (0) L1 D2   Spannungsmessung - 150 Ohm
       (1) L1 D3   Herd 16A - L1 - 100 Ohm
       (2) L1 D4
       (3) L1 D5
       (4) L1 D6
       (5) L1 D7   DG Steckdosen&Bel. 28A - 56 Ohm
       (6) L1 D8   G  Steckdosen&Bel. 28A - 56 Ohm
       (7) L1 D9   Steckdosen Keller 28A - 56 Ohm
       (8) L1 D10  Beleuchtung Keller 9A - 180 Ohm
       (9) L1 D14  Waschmaschine 16A - 100 Ohm
    
        Kanal:  Bezeichnung: Phase "L2"
       (0) L2 D2   Spannungsmessung - 150 Ohm
       (1) L2 D3   Herd 16A - L2 - 100 Ohm
       (2) L2 D4   Geschirrspüler 16A - 100 Ohm
       (3) L2 D5   Beleuchtung EG 9A - 180 Ohm
       (4) L2 D6   16A - 100 Ohm
       (5) L2 D7   Steckdosen EG 28A - 56 Ohm
       (6) L2 D8   28A - 56 Ohm
       (7) L2 D9
       (8) L2 D10
       (9) L2 D14
    
       Kanal:  Bezeichnung: Phase "L3"
       (0) L3 D2   Spannungsmessung - 150 Ohm
       (1) L3 D3   Backofen 16A - L3 - 100 Ohm
       (2) L3 D4
       (3) L3 D5   Kühlschrank 9A - 180 Ohm
       (4) L3 D6
       (5) L3 D7   OG Steckdosen&Bel. 28A - 56 Ohm
       (6) L3 D8
       (7) L3 D9
       (8) L3 D10
       (9) L3 D14
    */
    const unsigned long BaudRate = 115200;  // hier die Baudrate des seriellen Interfaces einstellen
    //********************************************************************
    // Beschreibung:
    /*--------------------------------------------------------------------------
       Das Programm läuft auf einem Arduiono (Nano, Mini,...) und soll den Wechselstrom von mehreren Installationsleitungen messen.
    
       Max. können 10 Wandler angeschlossen werden. Bei jedem Wandler wird 4 mal pro Sekunde je eine Periode gemessen und aus den
       Messergebnissen der RMS gebildet. Der Arduino schafft 586 Messungen in 20 ms bei Verwendung von unsigned long zum Speichern
       der Messergebnisse. Bei Verwendung von float können nur 380 - 400 Messungen durchgeführt werden.
       Die Integer Berechnung begrenzt den max. gemessenen Strom auf 2707 Wandlerzählern, entspricht bei 50 Ohm 33A  ->  100 Ohm 16,1A.
    
       Die Zusammengefassten Ergebnisse werden einmal pro Sekunde über die serielle Schnittstelle übertragen.
    
       Die Messwandler liefern 1mA pro 1A Messstrom, max. jedoch 2,5V. ( wenn das der Effektivwert ist, liegt der Spitzenwert schon zu hoch für den ADC!!!!)
       Ein 13 Bit ADC MCP 3301 digitalisiert die über einen Messshunt abfallende Spannung.
       Die Größe des Mess-Shunt ist je ADC wählbar und muss im Array Shunt[] eingetragen werden.
       Der ADC erhält eine Referenzspannung von 2,5V. Diese geteilt durch die halbe Auflösung=4096 ergibt den
       Spannungswert eines ADC-Zählers= 0,61035 mV. Die Referenzspannungsquelle muss damit hinreichend genau sein.
    
       Der ADC wird über SPI angesprochen. Er kann mit max 1,7 MHz getaktet werden. Der AVR läuft mit 16 MHz und kann den SPI Takt
       nur durch 2,4,8,16,.. teilen, so dass der ADC mit 1 MHz getaktet wird. Damit dauert die Übertragung eines
       Messwertes 16 uS. Weiter 18 uS werden für die Verarbeitung benötigt
    
       TEST MESSWERTE(Messwiderstand -> Messstrom):
       --------------------------------------------
       OHM - Strom MIN - Strom MAX
        56 Ohm - 11 mA - 28 A
       100 Ohm -  6 mA - 16 A
       180 Ohm -  4 mA -  9 A
    
      --------------------------------------------------------------------------
      Version 1.1 mit I2C
      Der Arduino verhält sich als I2C Slave. Sobald eine Anfrage vom Master empfangen wird,
      werden alle 10 Messwerte (in High- und Lowbyte aufgeteilt) per I2C gesendet. Wärend dieser Zeit
      können keine I2C Anfragen empfangen werden.
    
      Version 1.3 ==> Leistungsmessung
      Das Programm soll nun die Leistung der Verbraucher erfassen. Dazu wird ein frei wählbarer Wandler
      zur Messung der Spannung benutzt. Es kann auch ein elfter Wandler angeschlossen werden. der Controller
      kann dann 10 Verbraucher überwachen.
      Messprinzip:
      In der Funktion Messperiode wird der Strom des aktuellen Wandlers mit der gemessenen Spannung multipliziert und in einer
      long int var aufaddiert. Nach 20ms wird der Mittelwert durch Teilen mit der Anzahl der Messungen ermittelt.
      Ausgabe:
      Erst hier wird der Wert eines Stromzählers vom ADC und des Spannungszählers eingearbeitet:
      - Mittelwert aus den Runden
          StromWert eiens Zählers in Abhängigkeit vom MessShunt
          Wert eines Spannungszählers (400V Spitzenspannung/4096 ADC Zähler ungefähr 0,1V)
          Korrekturwert Spannung
      Hier wird von Integer auf Float umgeschaltet.
    
      Da die Spannung nicht so genau wie der Strom angliefert wird, kann die Spannungsmessung kalibriert werden.
      Hierzu muss z.B. der Pin A3 beim Einschalten auf Masse gezogen werden, das Programm geht dann in den Kalibriermodus.
      Es misst die Spannung und gibt sie über die Serielle Schnittstelle aus und wartet anschließend auf die Eingabe
      einer Spannungsmessung. Der Korrekturfaktor wird daraus errechnet und im EEPROM abgespeichert.
      (die max Eingangsspannung für den MCP3301 beträgt +/-2,5V)
    
    */
    
    
    // für Datenausgabe bei Fehlersuche(wenn auskommentiert = nicht aktiv)
    //#define debug //Status über RS232 ausgeben
    #define debug_Strom_Ausgabe //Strom über RS232 ausgeben
    
    const unsigned long CPeriode = 20000; // Microsekunden einer Halbwelle
    const unsigned long CRunde = 1000 / CRundAnz; // ms einer Messrunde über alle ADC
    const int EEAdr = 0;                          // Adresse im EEProm für den Spg. Korrekturwert
    
    // Array zur Aufnanme aller Messergebnisse einer Sekunde
    long Erg[ADCAnz * CRundAnz];
    boolean Flag_Ausgabe = false;  // Flag für die Ausgabe
    unsigned long SchlafRunden = 0; // zählt im Debugmodus die Looprunden
    float Korrektur;                // nimmt den Spannungskorrekturwert aus dem EEPROM auf
    int Wert_h[ADCAnz];   //Variable für I2C High
    int Wert_l[ADCAnz];   //Variable für I2C Low
    float MessSpg; //aktuelle 230V Spannung ausgeben
    int MessSpg2; //aktuelle 230V Spannung ABER Komma verschoben!!!
    
    
    //**************************************************************************************
    #include <SPI.h>                    // SPI Bibliothek
    #include <Streaming.h>              // Bibliothek zur besseren Ausgabeformatierung ==> Streaming.h ins Arduino Bibliotheksverzeichni kopieren
    #include <Wire.h>                   // Bibliothek für I2C
    #include <EEPROM.h>                 // EEPROM Zugriff
    
    //**************************************************************************************
    // Funktionsprototypen
    long MessPeriode(int csADC);
    
    void Ausgabe();
    void requestEvent();
    void Messung();
    //**************************************************************************************
    void setup() {
    
      Serial.begin(BaudRate);  // Serielle Schnittstelle mit 115200 Baud starten
    
      SPI.begin();            // SPI Interface starten
      for (int i = 0; i < ADCAnz; i++) {    // cs Pins initialisieren
        pinMode(cs[i], OUTPUT);
        digitalWrite(cs[i], HIGH);
      }
      // Pin für die Spannungsmessung init.
      pinMode(csSpg, OUTPUT);
      digitalWrite(csSpg, HIGH);
      // Pin für die Kalibrierung
      pinMode(PinKal, INPUT_PULLUP);
    
      SPI.beginTransaction(SPISettings(1700000, MSBFIRST, SPI_MODE0)); // SPI Parameter
    
      Wire.begin(I2C_Adr);                // I2C mit Adresse #... starten
      Wire.onRequest(requestEvent); // register event für I2C
    
    
      // Versionsausgabe:
      //____________________________________________________________________________________________________
      Serial.println("= = = = = = = = = = = = = = = = = = =");
      Serial.print("  NEUSTART: StromMess_I2C_V_v"); Serial.println(Version); //Damit später zu sehen ist, welche Datei auf dem Arduino ist
      Serial.print("  I2C Adresse L2: "); Serial.println (I2C_Adr);
      Serial.println("= = = = = = = = = = = = = = = = = = =");
      //____________________________________________________________________________________________________
    
    
    
      //normal starten oder Kalibrierung starten:
      if (digitalRead(PinKal) == LOW) {
        //if (digitalRead(PinKal) == HIGH) { //immer Kalibrierung ausrufen zum testen
        Serial << "Kalibrierung" << endl;
        Kalibrierung();
      }
      EEPROM.get(EEAdr, Korrektur);
    }
    
    
    //**************************************************************************************
    void loop() {
    
      if (digitalRead(PinKal) == HIGH) Flag_Ausgabe = true;
      //Serial.print ("Ausgabe - Flag_Ausgabe: ");
      //Serial.println (Flag_Ausgabe);
    
      if (Flag_Ausgabe == true) { // Falls I2C Master Daten haben will
        delay(10);
    
        //Spannung messen und auf ertem Kanal ausgeben
        int Spg = SpgMessung();
        MessSpg = Spg;
        MessSpg *= Korrektur;   // Korrekturfaktor aus dem EEProm befücksichtigen
        MessSpg2 = MessSpg; //Wert mit verschobenem Komma für I2C Ausgabe
        MessSpg *= 0.1;
    
        Messung();        // Neue Messung anstoßen
        Flag_Ausgabe = false;  // Flag zurücksetzen
      }
    #ifdef debug
      SchlafRunden += 1;    // Im Debugmodus die Anzahl der LoopRunden zählen
    #endif
    
    }
    
    //**************************************************************************************
    void requestEvent() {           // Diese Schleife wird bei I2C Empfang durchlaufen
    #ifdef debug
      Serial.println ("requestEvent - Anforderung von I2C Master");
    #endif
    
      for (int i = 0; i < ADCAnz; i++) {
        // I2C Ausgeben -> Daten müssen sofort ausgegeben werden, da sonst Schwierigkeiten mit I2C Master
        Wire.write(Wert_l[i]);
        Wire.write(Wert_h[i]);
    
    #ifdef debug
        Serial << Wert_l[i] << " : " << Wert_h[i] << endl;
    #endif
      }  // Ende Schleife über alle ADC
    
      Flag_Ausgabe = true;              // und es wird nichts weiter gemacht, als ein Flag zu setzen, das in Loop ausgewertet wird
    }
    
    
    //**************************************************************************************
    void Messung() {
    
      // Diese Schleife wird jede Sek. einmal durchlaufen
      // I2C abschalten
      TWCR = _BV(~TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(~TWINT);
    
      for (int i = 0; i < ADCAnz * CRundAnz; i++) Erg[i] = 0; // Ergebniise des vorherigen Laufes löschen
      // Schleife je Runde. In jeder Runde werden alle ADC für je 20ms abgefragt
      for (int runde = 0; runde < CRundAnz; runde++) {
        //Serial << "StartRunde:" << runde << endl;
        for (int ADCNr = 0; ADCNr < ADCAnz; ADCNr++) {
          int Index = runde * ADCAnz + ADCNr; // Zeigt auf das Ergebnisarray, Reihenfolge: Ergs der ersten Runde, Ergs der 2. Runde, usw.
          Erg[Index] = MessPeriode(cs[ADCNr]); // Messung für einen ADC durchführen und speichern;
          //Serial << "ADCNr:" << ADCNr << "Runde:" << runde << endl;
        }  // Ende, alle ADC einmal durchmessen
        if (runde == CRundAnz - 1) Ausgabe(); // wenn es die letzte Runde war ==> Daten ausgeben
      } // Ende Schleife über alle Mess-Runden
    
      // I2C einschalten
      TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
      return;
    } //Ende Messung
    
    
    /* Function MessPeriode
        Führt mit einem ADC die Messungen über eine Periode durch.
        Der cs-PIN des ADC wird übergeben
        führt dann die Spannungsmessung aus
        summiert Strom * Spg Werte auf
        nach Ablauf wird durch die Anzahl der Messungen geteilt (Mittelwert) ==> Rückgabewert
        Strom und Spannung müssen vorzeichenrichtig verarbeitet werden, deshalb nur long Variablen*/
    
    long MessPeriode(int csADC) {
      unsigned long ZeitPeriode = micros();
      int MessAnz = 0; // Anzahl der Messungen
      const int diff = 2; //Hier den Wert für die Differenz / Verschiebung eingeben - muss ausprobiert werden. 
      /*Einen ohmschen Verbraucher wie eine Glühlampe anschließen und den Wert im Testmodus so einstellen, 
       * dass die Werte von Strom und Spannung gleichzeitig im positiven/negativen Bereich sind.
       */
       
      // Initialisierung der Zähler
      // Der Strom wird jeweils einen Platz weiter ins Array als die Spannung geschrieben. Dadurch dauert es diff=8 mal bis zum ersten Mal
      // Platz null belegt wird. erst dann beginnt die Messung und damit auch die Zeitzählung
      int zaehler_i = 0; //Zeiger für Stromarray  ==> Im ersten Durchlauf wird Platz 1 im Array beschrieben
      int zaehler_u = diff; //Zeiger für Spannungsarray ==>  Im ersten Durchlauf wird Platz 0 im Array beschrieben
      int ADCStrom[diff + 1]; // nimmt den Strom-Messwert vom ADC auf
      int ADCSpg[diff + 1];  // desgl. für die Spannung
      boolean start = false; // false, bis diff=8 Durchgänge gelaufen sind.
    
      float Erg = 0; // nimmt die Summen einer Periode auf
    
      //..................................................
    
    
      do {
    
        //Zähler für Strom:
        if (zaehler_i < diff) {
          zaehler_i++;
        }
        else {
          zaehler_i = 0;
          // prüfen, ob wir am Anfang der Messung stehen
          if (!start) {
            // Das Array ist das erste Mal gefüllt, jetzt kann es losgehen
            ZeitPeriode = micros();  // Messzeit jetzt neu starten
            Erg = 0;                // Ergebnis noch mal nullen
            start = true;             // und Feuer frei
          }
        }
        //Zähler für Spannung:
        if (zaehler_u < diff) {
          zaehler_u++;
        }
        else {
          zaehler_u = 0;
        }
        // Strom und Spannung versetzt ins Array schreiben
        // Strommessung: mit zaehler_i
        digitalWrite(csADC, LOW);
        ADCStrom[zaehler_i] = SPI.transfer16(0);
        digitalWrite(csADC, HIGH);
        // der ADC liefert ein 13 Bit Ergebniss, das muss an 16 Bit int angepasst werden
        if (bitRead(ADCStrom[zaehler_i], 12)) {
          ADCStrom[zaehler_i] |= 0xF000;         // das int Signbit und das obere HalbByte auf 1 setzen (2er Complement)
        } else ADCStrom[zaehler_i] &= 0x0FFF;      // die 3 undefinierten und das Signbit auf null
    
        // Spannungsmessung: mit zaehler_u
        digitalWrite(csSpg, LOW);
        ADCSpg[zaehler_u] = SPI.transfer16(0);
        digitalWrite(csSpg, HIGH);
        // der ADC liefert ein 13 Bit Ergebniss, das muss an 16 Bit int angepasst werden
        if (bitRead(ADCSpg[zaehler_u], 12)) {
          ADCSpg[zaehler_u] |= 0xF000;  // das int Signbit und das obere HalbByte auf 1 setzen (2er Complement)
        } else ADCSpg[zaehler_u] &= 0x0FFF;      // die 3 undefinierten und das Signbit auf null
    
    
        //BERECHNUNG: mit den verschobenen Werten
        // Die Verschiebung ist bereits im Array enthalten. Der aktuellen Zähler ist zaehler_i,
        // er wird mit den bereits früher aufgezeichneten Spannungswerten mulzipliziert.
        Erg += (float)ADCStrom[zaehler_i] * (float)ADCSpg[zaehler_i];  // Strom * Spannung aufaddieren
    
        MessAnz++;                                               // Anzahl der Messungen erhöhen
      } while (micros() - ZeitPeriode < CPeriode);               // Ende MessSchleife über eine Periode
      //..................................................
    
      Erg /= MessAnz;                // Das Ergebnis aller Messungen durch die Anzahl teilen (Mittelwert)
    #ifdef debug
      Serial << "Anzahl der Messungen je Periode:" << MessAnz << " Messung: " << Erg <<  endl;;
    #endif
      return (long)Erg;        // Rückgabe ist der Mittelwert
    }
    
    /* Function Ausgabe
       gibt jede Sekunde die Messergebnisse über die Serielle Schnittstelle aus*/
    //**************************************************************************************
    void Ausgabe() {
    #ifdef debug
      Serial.println ("Ausgabe: ");
    #endif
      const long Uadc = 610350; // Wert eines Zählers
      float IuA;                 // Strom je Zähler eines ADC
      float SekWert;   // nimmt die Ergebnisse einer Runde eines ADC auf
      int Leistung;
    
      for (int ADCNr = 0; ADCNr < ADCAnz; ADCNr++) { // Schleife über alle ADC
        SekWert = 0;
        for (int Runde = 0; Runde < CRundAnz; Runde++) { // Schleife über alle Runden je ADC
          SekWert += Erg[Runde * ADCAnz + ADCNr]; // Messergebnisse eines ADC aufaddieren
        } // Ende Schleife über Runden eines ADC
        SekWert /= CRundAnz;    // Mittelwert bilden
        // Stromkorrektur einarbeiten
        IuA = Uadc / Shunt[ADCNr]; // Strom je Zähler in uA berechnen
        SekWert *= IuA;         // mit Strom-Zählerwert multiplizieren z.B. für 50 Ohm(12207 uA)
        SekWert /= 1000;        // auf mA runter rechnen
        SekWert /= 1000;        // auf A runter rechnen
        SekWert /= 10;          // ein ADC-Zähler ist ca. 100mV Wert => Umrechnung auf Volt
        SekWert *= Korrektur;   // Korrekturfaktor aus dem EEProm berücksichtigen
    
    
        if (SekWert >= 0) {     // Wert nur übernehmen, wenn >= 0, sonst 0 eintragen -> also keine negativen Werte
          Leistung = SekWert;
    
        }
        else {
          Leistung = 0;
        }
    
        // Ausgeben
        Wert_l[ADCNr + 1] = (lowByte(Leistung));   //aktuellen Wert an I2C Variable übergeben
        Wert_h[ADCNr + 1] = (highByte(Leistung));  //+1 damit Byte0 für die Spannung frei bleibt
    
    #ifdef debug_Strom_Ausgabe
        //Serial << "Leist." << ADCNr + 1 << ": " << SekWert << " W; " ; //Ausgabe mit 2 Nachkommastellen
        Serial << "Leist." << ADCNr + 1 << ": " << Leistung << " W; " ; //Ausgabe ohne Nachkommastellen
    #endif
      }  // Ende Schleife über alle ADC
    
      //Spannung über I2C auf dem ersten Byte übergeben
      Wert_l[0] = (lowByte(MessSpg2));   //aktuellen Wert an I2C Variable übergeben
      Wert_h[0] = (highByte(MessSpg2));  //aktuellen Wert an I2C Variable übergeben
      Serial.print ("Spg.: ");
      Serial.print (MessSpg2);
    
    #ifdef debug_Strom_Ausgabe
      Serial << endl;
    #endif
      return;
    } // Ende Function Ausgabe
    - - - Aktualisiert - - -

    und der zweite Teil für die Kalibrierung:
    Datei: Kalibrie.ino

    Code:
    /*
       Kalibrierung
       Hier wird die Spannungsmessung kalibriert. Durch einmaliges Eingeben der gemessenen Spannung errechnet das Programm
       einen Korrekturfaktor und speichert ihn im EEPROM ab. Der Faktor wird künftig bei der Berechnung verwendet
    */
    
    void Kalibrierung() {
      while (true) {
    
    
        float SpgVergl = 0; //ist die Spannung, welche als Vergleich vom Benutzer eingegeben wurde
        int Spg = SpgMessung();
        float MessSpg = Spg * 0.1;
    
    
        Serial << ">>>>>>>>>>> Kalibrierung <<<<<<<<<<" << endl;
        Serial << "Die gemessene Spannung (ohne Korrektur!) beträgt: " << _FLOAT(MessSpg, 1) << "V" << endl;
        Serial << "Bitte das Ergebnis der Vergleichsmessung eingeben: ";
        Serial.setTimeout(1000000);
        while (SpgVergl == 0) {
          String Eingabe = Serial.readStringUntil('\n');
          SpgVergl = Eingabe.toFloat();
        }
        Serial << endl << "Eingegeben wurde: " << SpgVergl << endl;
        Serial << " " << endl;
    
    
        float Korrektur = SpgVergl / MessSpg;
        Serial << "Korrekturfaktor ausrechnen: SpgVergl / MessSpg" << endl;
        Serial << "Korrekturfaktor ausrechnen:  " << SpgVergl << "V / " << MessSpg << "V" << endl;
        Serial << "Korrekturfaktor ist: " << _FLOAT(Korrektur, 5) << endl;
        Serial << " " << endl;
    
    
        Serial << "Daraus errechneter Messwert: "  << endl;
        Serial << "MessSpg * Korrektur = Messwert"  << endl;
        Serial << MessSpg << "V * " << Korrektur << " = " << MessSpg*Korrektur << "V" << endl;
        Serial << " " << endl;
    
    
        EEPROM.put(EEAdr, Korrektur); //Faktor in EEPROM speichern
        EEPROM.get(EEAdr, Korrektur); //Faktor zum Testen nochmal aus EEPROM auslesen
        Serial << "geänderter Korrekturfaktor: " << _FLOAT(Korrektur, 5) << endl;
        Serial << "wurde im EEPROM Abgespeichert!" << endl << endl;
    
      }
      return;
    }
    int SpgMessung() {
      unsigned long ZeitPeriode = micros();
      int MessAnz = 0; // Anzahl der Messungen
      int ADCdata;  // nimmt den Messwert vom ADC auf
      unsigned long Erg = 0; // nimmt die quadrierten Summen einer Periode auf
      do {
        digitalWrite(csSpg, LOW);
        ADCdata = SPI.transfer16(0);
        digitalWrite(csSpg, HIGH);
        // der ADC liefert ein 13 Bit Ergebniss, das muss an 16 Bit int angepasst werden
        if (bitRead(ADCdata, 12)) {
          ADCdata |= 0xF000;         // das int Signbit und das obere HalbByte auf 1 setzen (2er Complement)
        } else ADCdata &= 0x0FFF;      // die 3 undefinierten und das Signbit auf null
    
        Erg += (unsigned long)ADCdata * (unsigned long)ADCdata;  // Quadrieren
        MessAnz++;    // Anzahl der Messungen erhöhen
      } while (micros() - ZeitPeriode < CPeriode);               // Ende MessSchleife über eine Periode
      Erg /= MessAnz;                // Das Ergebnis aller Messungen durch die Anzahl teilen (quadratischer Mittelwert)
    
    #ifdef debug
      Serial << "Anz:" << MessAnz;
      Serial << "M:" << ADCdata << " E:" << (int(sqrt(Erg))) << "; ";
    #endif
      return int(sqrt(Erg));        // Rückgabe ist die Wurzel aus dem Mittelwert der Quadrate
    }

  4. #84
    Neuer Benutzer
    Registriert seit
    21.07.2004
    Alter
    67
    Beiträge
    1
    Glückwunsch!
    werde es mal testen

  5. #85
    Hallo
    habe mal diesen thread wieder nach oben geholt.
    Und ich habe ihn eigentlich komplett gelesen, natürlich nicht alles sofort verstanden.

    Im Schaltplan im link unter dem ersten Beitrag finde ich nicht den Trafo zur Spannungsmessung, wo finde ich da mehr?

    Ziel ist es die Stromaufnahme und kW/h von Geräten an einer 16A & 32A CEE Steckdose zu messen

    weiter oben wird ja ein 15A 15:1 Stromwandler noch mit vorgeschlagen
    für mich würde ich dann die Schaltung 3x aufbauen mit 15,30,50A Wandlern an L1, 2 und 3

    wird ganz schön kniffelig, hat das jemand schon mal so gemacht?

    Grüße
    jodurino

Seite 9 von 9 ErsteErste ... 789

Ähnliche Themen

  1. Suche Serviceleistung Arduino Programierer für mein Projekt gegen Bezahlung gesucht
    Von kkellner im Forum Jobs/Hilfen/Stellen - Gesuche und Angebote
    Antworten: 1
    Letzter Beitrag: 16.07.2015, 15:37
  2. Arduino 230V Relais Strommessung
    Von Fransch im Forum Elektronik
    Antworten: 4
    Letzter Beitrag: 14.07.2015, 21:39
  3. Arduino Projekt Fotofalle
    Von TKK-Arduino im Forum Arduino -Plattform
    Antworten: 20
    Letzter Beitrag: 18.02.2015, 18:35
  4. Antworten: 5
    Letzter Beitrag: 02.08.2013, 21:38
  5. Arduino-Projekt verkleinern
    Von IPlayWithLasers im Forum Arduino -Plattform
    Antworten: 4
    Letzter Beitrag: 28.01.2012, 10:55

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen