- LiFePO4 Speicher Test         

Kommentare

  1. Avatar von per48or
    vielen Dank an Meyenfelder für die Idee und die Infos dazu!
    Ich habe das nun an meiner Huawei-Anlage (SUN2000-4.6KTL-L1) auch umgesetzt.
    Zusätzlich hab ich noch einen Batteriespeicher (LG RESU 10H) der leider keine Ladezustandsanzeige besitzt, der hängt am gleichen Bus (Adr15).
    Leider gibts vom LG Resu dazu keine Doku, daher hab ich das Protokoll mitgeschrieben und analysiert, die beiden für mich wichtigen Werte (Ladezustand und Ladeleistung) hab ich gefunden, siehe Code.
    Im Programm warte ich bis beide Geräte vom Master abgefragt wurden (passiert ca 1x/sek), werte die entsprechenden Register aus und stelle dann alle Werte an einem Nextion-Display dar.

    Ich verwende einen Arduino Pro Mini mit einer 2€ RS485-Adapterplatine.
    Die RS485-Platine darf nur empfangen, also sind die Pins !RE und DE beide auf GND.
    Der RO-Pin geht auf Arduino RX.
    Den Arduino-TX-Pin verwende ich zum Senden der Daten an das Nextion-Display.

    hier mein Arduino-Code, vielleicht hilft das dem einen oder anderen als Basis:
    (Falls jemand das Nextion-File auch haben will, gerne per PN)

    Code:
    const int BUFFER_SIZE = 160;
    char buf[BUFFER_SIZE];
    float Wirkleistung;
    int Ladeleistung_raw; //Teiler1000
    int Ladezustand_raw;  //Teiler2
    float Ladeleistung;
    float Ladezustand;
    unsigned long lastread_zaehler;
    unsigned long lastread_akku;
    unsigned long lesetimeout;
    byte recbuf;
    boolean gelesen_zaehler=false;
    boolean gelesen_akku=false;
    
    void setup() {
      Serial.begin(9600);
    }
    
    void loop() {
    
    bytelesen();
    
      if (recbuf == 0x0B) {                       //Adr 11=Stromzähler DTSU666-H
        bytelesen();
        if (recbuf == 0x03) {                     //03=Kommando Register lesen
          bytelesen();
          if (recbuf == 0xA0) {                   //0xA0=160 Bytes Daten
            Serial.readBytes(buf, 160);
            ((byte*)&Wirkleistung)[3]=buf[48];    //ab 25. Register Wirkleistung % (float)
            ((byte*)&Wirkleistung)[2]=buf[49];
            ((byte*)&Wirkleistung)[1]=buf[50];
            ((byte*)&Wirkleistung)[0]=buf[51];
            Wirkleistung=Wirkleistung/1000.0;      //in kW
            lastread_zaehler=millis();
            gelesen_zaehler=true;
          }
        }
      }
    
      if (recbuf== 0x0F) {                           //Adr 15=LG Resu
        bytelesen();
        if (recbuf == 0x03) {                        //03=Kommando Register lesen
          bytelesen();
          if (recbuf == 0x38) {                      //0x38=56 Bytes Daten
            Serial.readBytes(buf, 56);
            ((byte*)&Ladeleistung_raw)[1]=buf[4];    //3. Register Ladeleistung_raw W (kw Teiler1000)
            ((byte*)&Ladeleistung_raw)[0]=buf[5];
            ((byte*)&Ladezustand_raw)[1]=buf[40];    //21. Register Ladezustand_raw % (Teiler2)
            ((byte*)&Ladezustand_raw)[0]=buf[41];
            Ladeleistung=Ladeleistung_raw/1000.0;
            Ladezustand=Ladezustand_raw/2.0;
            lastread_akku=millis();
            gelesen_akku=true;
          }
        }
      }
    
    
      if(gelesen_zaehler&&gelesen_akku){
        digitalWrite(13,HIGH);
        nextion();
        while(Serial.available()){          //Puffer löschen bevor neuer Leseversuch
         recbuf=Serial.read();
        }
        //Serial.end();
        //Serial.begin(9600);
        gelesen_zaehler=false;
        gelesen_akku=false;
        digitalWrite(13,LOW);
      }
    
      if(millis()>lastread_zaehler+10000){
        Wirkleistung=0.0;
        nextion();
        lastread_zaehler=millis();
      }
      
      if(millis()>lastread_akku+10000){
        Ladeleistung=0.0;
        Ladezustand=0.0;
        nextion();
        lastread_akku=millis();
      }
    
    
    }
    
    void bytelesen(){             //warten auf nächstes Byte und lesen, max 1s warten (nicht blockierend)
      lesetimeout=millis();
      while(!Serial.available() && (millis()<lesetimeout+1000)){}
      recbuf=Serial.read();
    }
    
    void nextion(){               //alle Werte aufs Display schreiben
    
    Serial.print("t2.txt=");
    Serial.write(0x22);
    Serial.print(Ladezustand,1);
    Serial.print("%");
    Serial.write(0x22);
    Serial.write(0xFF);
    Serial.write(0xFF);
    Serial.write(0xFF);
    
    Serial.print("j0.val=");
    Serial.print(Ladezustand,0);
    Serial.write(0xFF);
    Serial.write(0xFF);
    Serial.write(0xFF);
    
    Serial.print("j0.pco=");
    if(Ladezustand>60){
      Serial.print("2016");     //gn
    } else if (Ladezustand>30){
      Serial.print("64512");    //or
    } else {
      Serial.print("63488");    //rt
    }
    Serial.write(0xFF);
    Serial.write(0xFF);
    Serial.write(0xFF);
    
    Serial.print("t1.txt=");
    Serial.write(0x22);
    Serial.print(Ladeleistung,2);
    Serial.print("kW");
    Serial.write(0x22);
    Serial.write(0xFF);
    Serial.write(0xFF);
    Serial.write(0xFF);
    
    Serial.print("t0.txt=");
    Serial.write(0x22);
    Serial.print(Wirkleistung,2);
    Serial.print("kW");
    Serial.write(0x22);
    Serial.write(0xFF);
    Serial.write(0xFF);
    Serial.write(0xFF);
    
    
    Serial.print("g0.dir=");
    if(Ladeleistung>=0){
      Serial.print("1");     //nach links
    } else {
      Serial.print("0");     //nach rechts
    }
    Serial.write(0xFF);
    Serial.write(0xFF);
    Serial.write(0xFF);
    
    Serial.print("g2.dir=");
    if(Ladeleistung>=0){
      Serial.print("2");     //nach unten
    } else {
      Serial.print("3");     //nach oben
    }
    Serial.write(0xFF);
    Serial.write(0xFF);
    Serial.write(0xFF);
    
    Serial.print("g1.dir=");
    if(Wirkleistung<0){
      Serial.print("0");     //nach rechts
    } else {
      Serial.print("1");     //nach links
    }
    Serial.write(0xFF);
    Serial.write(0xFF);
    Serial.write(0xFF);
    
    }

LiFePO4 Speicher Test