MPPT Solarlader

Benutzeravatar
Admin
Administrator
Beiträge: 1199
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: MPPT Solarlader

Beitrag von Admin »

Einen schönen guten Tag Bernhard.
Jetzt habe ich endlich den Uno zum Test am MPPT Laderegler angeschlossen und es läuft grundsätzlich. Aber offenbar ist die BaudRate 115200 zu schnell. Do ich es nicht eilig habe würde ich gerne auf die 9600 runter gehen. Nur habe ich noch nicht gefunden, wie das gehen soll. Ich finde den Menüpunkt nicht im Menue des Ladereglers. Hast du den schon gefunden?

Servus
Franz :(V):
Benutzeravatar
Admin
Administrator
Beiträge: 1199
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: MPPT Solarlader

Beitrag von Admin »

Alles zurück. Das Problem war nicht die Daten-Übernahme vom MPPT Regler, sondern die Ausgabe aufs Display. Da hat wohl das holen der Daten die Ausgabe am Display gestört. Da ich aber keine Daten am Display brauche, habe ich erst mal alles eingekürzt auf die Serial Ausgabe. Dann klappt alles super. Danke schon mal dafür, die Daten vom MPPT holen klappt suuuuuper. :(oo):

Servus
Franz
Bernhard - Fony
Beiträge: 73
Registriert: Mo 12. Jun 2023, 17:49
Kontaktdaten:

Re: MPPT Solarlader

Beitrag von Bernhard - Fony »

;) Im erstem Moment hast Du mich Erschrocken.
Schön das alles Klappt, die Baudratte kann man laut noiasca mit dem PC Programm ändern, habe aber nicht geschaut.
Wahrscheinlich ende der oder nächste Woche klemme mal Laptop dran. Als Rentner habe keine Zeit immer kommt was dazwischen ;)
Jetzt wollen die Frauen aus dem Vorstand im Büro neue Lampen haben, also Zusatzarbeit :O:
Benutzeravatar
Admin
Administrator
Beiträge: 1199
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: MPPT Solarlader

Beitrag von Admin »

Dann mach mal. Mein Vorstand hat auch immer wieder was zu tun für mich. :(V):
Benutzeravatar
Admin
Administrator
Beiträge: 1199
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: MPPT Solarlader

Beitrag von Admin »

Jetzt habe ich hier mal das Programm kombiniert. Die Solarheizung und die MPPT Daten abfragen.
Aber da wird das Programm nicht mehr komiliert.

"Fehler beim kompilieren für das Board Arduino Uno".
.

Code: Alles auswählen

// Arduino Pool_Solarheizung_Pumpensteuerung
// Mit MPPT Kommunikation
//##########################################
#include <OneWire.h>
#include <DallasTemperature.h>
#include "Wire.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
//-----Motortreiber----
const byte RPWM = 10;
const byte LPWM = 11;
//-------Potis---------
const byte Poti1 = A0;
const byte Poti2 = A1;
//-------Taster--------
byte Tasterstatur = 0;
const byte Taster = 6; // Display einschalten !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//-------Merker--------
byte Pumpe = 0;
int P1 = 0;
int P2 = 0;
int Drehzahl = 0;
int Solldrehzahl = 0;
int Sollalt = 10;
byte Anfahren = 0;
int Drehzahlmin = 150;
int Drehzahlmax = 255;
unsigned long millisekunden = 0;
//#################################################################################
//---------------------------------------MPPT Kommunikation------------------------
/*************************************
   Für Uno wird SoftwareSerial benutzt
**************************************/
#include <SoftwareSerial.h>
SoftwareSerial tracerSerial(4, 5); // RO, DI  Pins drehen wenn nicht funktioniert

/**********************************************
    Ich verwende  einen MAX485-kompatiblen RS485-Transceiver.
  Rx/Tx ist mit der seriellen Schnittstelle der Hardware an "Serial" verbunden.
  Die Pins "Data Enable" und "Rec3eiver Enable" sind wie folgt beschaltet:
 ********************************************************/
#include <ModbusMaster.h>

#define MAX485_DE      3 // DE und RE dürfen am einen Pin hängen 
#define MAX485_RE_NEG  3

// instantiate ModbusMaster object
ModbusMaster node;

int prozent = 0;
float akkuVolt = 0;
float akkuAmpere = 0;
float pvwat = 0;
float pva = 0;
float pvv = 0;

void preTransmission()
{
  digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
}

void postTransmission()
{
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
}
unsigned long previousMillis = 0;
const long intervall = 2000;// Daten werden alle 2Sek ausgelesen
//-----------------------MPPT Kommunikation Ende------------------------------
//############################################################################
//-------------------------------Zeiten---------------------------------------
unsigned long Sekundenablauf01 = 0;      // Messung Potis und Ausgabe Display
const unsigned long Pausezeit01 = 1000;
unsigned long Sekundenablauf02 = 0;      // Display nach Zeit ausschalten
const unsigned long Pausezeit02 = 60000 * 15;
unsigned long Sekundenablauf03 = 0;      //Serial Werte Ausgabezeit
const unsigned long Pausezeit03 = 60000 * 5;
unsigned long Sekundenablauf04 = 0;      // Werte für Pumpe und Pumpe ansteuern
const unsigned long Pausezeit04 = 30000; //Alle 30 Sekunden Daten für Pumpe
const unsigned char One_Wire_Bus = 2;    // Sensoren auf Pin 2
OneWire oneWire(One_Wire_Bus);
DallasTemperature sensoren (&oneWire);
int Anzahl_Sensoren = 0;
int is = 0; // Zähler für die Sensoren
int ia = 0; // Zähler für die Adressstellen 0-7
int Sensor = 0;
float temppool = 0;
float tempsolar = 0;
float tempdif = 0;
DeviceAddress tempDeviceAddress; // Für die Adressausgabe
int numberOfDevices; // Für die Adressausgabe
//##########################################################################
//################################  Setup ##################################
//##########################################################################
void setup() {
  Wire.begin();
  sensoren.begin();
  Serial.begin(9600);
  lcd.begin();
  lcd.backlight();
  lcd.setCursor (0, 0);
  lcd.print (F("Solarheizung - Pool"));
  lcd.setCursor (0, 1);
  lcd.print (F("Soll"));
  lcd.setCursor (10, 1);
  lcd.print (F("Ist"));
  lcd.setCursor (0, 2);
  lcd.print (F("Soll"));
  lcd.setCursor (10, 2);
  lcd.print (F("Ist"));
  lcd.setCursor (0, 3);
  lcd.print (F("Soll      Ist"));
  //#######################################################################
  tracerSerial.begin(115200); // Modbus Kommunikation mit 115200 Baud
  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  digitalWrite(MAX485_RE_NEG, 0);// Init in receive mode
  digitalWrite(MAX485_DE, 0);


  // Tracer xxxxAN Modbus slave ID 1
  node.begin(1, tracerSerial);  // Begin der Verbindung mit Tracer
  // Rückrufe ermöglichen es uns, den RS485-Transceiver korrekt zu konfigurieren
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);

  //#######################################################################
  // Anzahl der Sesoren ermitteln-------------------------------------
  Anzahl_Sensoren = sensoren.getDeviceCount();
  // Ermitteln der Sensor-Adressen------------------------------------
  for (is = 0; is < Anzahl_Sensoren; is++)
  {
    if (sensoren.getAddress(tempDeviceAddress, is))
    {
      Serial.println ();
      printAddress(tempDeviceAddress);
    }
  }
  //-----------Aus-/Eingänge einrichten-------------------------------------
  pinMode(RPWM, OUTPUT);              // PWM Pumpensteuerung
  pinMode(LPWM, OUTPUT);              // PWM Pumpensteuerung
  pinMode(Poti1, INPUT);
  pinMode(Poti2, INPUT);
  pinMode(Taster, INPUT_PULLUP);
}
// Ausgabe der Sensor-Adressen
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t ia = 0; ia < 8; ia++)
  {
    if (deviceAddress[ia] < 16)
    {
      Serial.print("0"); //ist die Hex Adresse kleiner 16 dann erste Stelle eine "0"
    }
    Serial.print(deviceAddress[ia], HEX);
  }
  Serial.println();
}
//###########################################################################
//################################## LOOP ###################################
//###########################################################################
void loop()
{
  millisekunden = millis();
  //--------------------------Display Lichtkontrolle -------------------------
  Tasterstatur = digitalRead(Taster);
  if (Tasterstatur == LOW)
  {
    lcd.backlight();
    Sekundenablauf02 = millisekunden;
  }
  if (millisekunden - Sekundenablauf02 >= Pausezeit02) // Dislay Zeit abgelaufen?
  {
    lcd.noBacklight();
  }
  //--------------------------Display Licht kontrolle Ende-------------------
  //#########################################################################
  //-------------------------Daten auswerten und aufs Display----------------
  if (millisekunden - Sekundenablauf01 >= Pausezeit01) // Eine Sekunde abgelaufen?
  {
    P1 = analogRead (Poti1);
    P1 = map(P1, 0, 1023, 0, 40); // -------Solltemperatur Einstellung-------
    P2 = analogRead (Poti2);
    P2 = map(P2, 0, 1023, 0, 10); // -------Solldiffderenz Einstellung-------
    lcd.setCursor (5, 1);
    lcd.print (P1);
    lcd.print ("  ");
    lcd.setCursor (5, 2);
    lcd.print (P2);
    lcd.print ("  ");
    lcd.setCursor (5, 3);
    lcd.print (Solldrehzahl);
    lcd.print (F("  "));
    lcd.setCursor (14, 3);
    lcd.print (Drehzahl);
    lcd.print (F("  "));
    Sekundenablauf01 = millisekunden;
    // -------------------------Temperatur Sensoren Auswerten---------------------------
    //Temperaturen Aulesen
    sensoren.requestTemperatures();

    // Hier werden die Temp-Sensoren ausgelesen und aufs Display gebracht
    if (Sensor < 2)
    {
      Sensor ++;
      float temperatur = sensoren.getTempCByIndex(Sensor - 1);
      if (Sensor == 1)
      {
        tempsolar = temperatur + 1; // -----------Temperatur Messung 1------------------
      }
      if (Sensor == 2)
      {
        temppool = temperatur - 1; // -----------Temperatur Messung 2------------------
        //--------------------------------------Temperatur aufs Display----------------
        lcd.setCursor (14, 1);
        lcd.print (temppool);
        lcd.print (F(" "));
        tempdif = (tempsolar * 10) - (temppool * 10); //---Themperatur Differenz----
        if (tempdif < 0)
        {
          tempdif = 5;
        }
        lcd.setCursor (14, 2);
        lcd.print (tempdif / 10);
        lcd.print (F(" "));
      }
    }
    // ---Alle Sensoren ausgelesen? Dann für nächste Messungen auf Null Stellen---
    if (Sensor == Anzahl_Sensoren)
    {
      Sensor = 0;
    }
  }
  //-------------------------Daten auslesen und Aufs Diplay Ende------------------
  //##############################################################################
  // ------Daten für Pumpensteuerung auswerten und an Pumpe übergeben-------------

  if (millisekunden - Sekundenablauf04 >= Pausezeit04) // 30 Sekunden abgelaufen?
  {
    // -------Prüfen ob Solartemperatur zum Anlauf der Pumpe sinnvoll ist---------
    if ((tempsolar > 28) && (tempsolar < 33) && (tempdif < 10))
    {
      tempdif = 10;
    }
    if ((tempsolar < 26) && (tempdif < 10))
    {
      tempdif = 0;
    }
    //-------------Solldrehzahl aus Temperaturdifferenz ermitteln--------------
    Solldrehzahl = map(tempdif, 10, 40, 150, 255);
    if (Solldrehzahl > Drehzahlmax)
    {
      Solldrehzahl = Drehzahlmax;
    }
    else
    {
      if (Solldrehzahl < Drehzahlmin)
      {
        Solldrehzahl = Drehzahlmin;
      }
    }
    // Ist gemessene tempdif gleich/größer Solldifferenz, dann Max Drehzahl
    if (tempdif >= (P2 * 10))
    {
      Solldrehzahl = Drehzahlmax;
    }
    //------------------Pumpen Ansteuerung------------------------------------
    // Gibt es keine brauchbare TemperaturDifferenz mehr, dann Pumpe auf PWM 0
    if (Anfahren == 0)
    {
      if (tempdif < 10) //---Temp.Differenz kleiner 1 Grad, dann Pumpe aus----
      {
        Solldrehzahl = 0;
      }
      // Ist aber die Wunsch-Temperatur +2 erreicht, dann keine Solar Unterstützung mehr
      if (temppool > (P1 + 2))
      {
        Solldrehzahl = 0;
      }
      // Ist Solldrehzahl erreicht ? Dann Drehzahl auf die Solldrehzahl einstellen
      if (Solldrehzahl < Sollalt)
      {
        Drehzahl = Solldrehzahl;
        Sollalt = Solldrehzahl;
      }
    }
    // Ist Solldrehzahl nicht erreicht dann Drehzahl um 10 erhöhen
    if ((Solldrehzahl > Sollalt) && (tempdif > 13))
    {
      if (Drehzahl < 120)
      {
        Drehzahl = 130;
      }
      Drehzahl = Drehzahl + 10;
      // Wenn über Max, dann die Drehzahl auf Maxdrehzahl anpassen
      if (Drehzahl > Drehzahlmax)
      {
        Drehzahl = Drehzahlmax;
      }
      Sollalt = Drehzahl;
      Anfahren = 1;
    }
    else
    {
      Anfahren = 0;
    }
    analogWrite(RPWM, Drehzahl);
    analogWrite(LPWM, 0);
    Sekundenablauf04 = millisekunden;
  }
  //------------------------Pumpensteuerung Ende-------------------------------
  //###########################################################################
  // ------------------------Serial Print Ausgabe------------------------------
  if (millisekunden - Sekundenablauf03 >= Pausezeit03) // Serial Ausgabezeit abgelaufen?
  {
    Serial.println("--------------------");
    Serial.print("Drehzahl Pumpe = ");
    Serial.print(Drehzahl);
    Serial.print(" - ");
    Serial.println(Solldrehzahl);
    Serial.print("Temp Pool = ");
    Serial.println(temppool);
    Serial.print("Temp Solar = ");
    Serial.println(tempsolar);
    Serial.print("Temp Differenz = ");
    Serial.println(tempsolar - temppool);
    Sekundenablauf03 = millisekunden;
  }
  //-------------------------Seriale Ausgabe Ende-----------------------------
  //############################################################################
  //---------------------------MPPT Kommunikation-------------------------------
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= intervall)
  {
    previousMillis = currentMillis; // Zeitpunkt der letzten Schaltung wird festgehalten
    // Read 16 registers beginn mit Adresse  0x3100)
    uint8_t result;
    result = node.readInputRegisters(0x3100, 16);
    if (result == node.ku8MBSuccess)
    { //PV Daten
      pvv = node.getResponseBuffer(0x00) / 100.0f; //Tracer PV Volt
      Serial.print("Panel ");
      Serial.print(pvv);
      Serial.print("V  ");
      pva = node.getResponseBuffer(0x01) / 100.0f;//PV Ampere
      Serial.print(pva);
      Serial.print ("A  ");
      //PV Leistung
      pvwat = ((node.getResponseBuffer(0x06) +  node.getResponseBuffer(0x07) ) / 100.0f); //PV Watt
      Serial.print(pvwat);
      Serial.println("W");

      /*****  Akkustand Anzeigen  *****/
      akkuVolt = node.getResponseBuffer(0x04) / 100.0f; //Tracer Akku Volt
      Serial.print("Akku  ");
      Serial.print(akkuVolt);
      Serial.print ("V  ");

      akkuAmpere = node.getResponseBuffer(0x05) / 100.0f;//Akku Ladedaten in Ampere
      Serial.print(akkuAmpere);
      Serial.print("A  ");
      Serial.print(prozent);
      Serial.println ("%");
      Serial.println ("---------------------------------");
    }
    result = node.readInputRegisters(0x311A , 1);//Akkukapazität in Prozent
    if (result == node.ku8MBSuccess) {
      prozent = node.getResponseBuffer(0x00);
    }
  }
  //---------------------------MPPT Kommunikation Ende------------------------
  //###########################################################################
}

Hier ist dein Programm, dass ich zusammengekürzt habe, das aber so wie es ist wunderbar funktioniert:

Code: Alles auswählen

//#include <Wire.h>
/*************************************
   Für Uno wird SoftwareSerial benutzt
**************************************/
#include <SoftwareSerial.h>
SoftwareSerial tracerSerial(4, 5); // RO, DI  Pins drehen wenn nicht funktioniert

/**********************************************
    Ich verwende  einen MAX485-kompatiblen RS485-Transceiver.
  Rx/Tx ist mit der seriellen Schnittstelle der Hardware an "Serial" verbunden.
  Die Pins "Data Enable" und "Rec3eiver Enable" sind wie folgt beschaltet:
 ********************************************************/
#include <ModbusMaster.h>

#define MAX485_DE      3 // DE und RE dürfen am einen Pin hängen 
#define MAX485_RE_NEG  3

// instantiate ModbusMaster object
ModbusMaster node;

int prozent = 0;
float akkuVolt = 0;
float akkuAmpere = 0;
float pvwat = 0;
float pva = 0;
float pvv = 0;

void preTransmission()
{
  digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
}

void postTransmission()
{
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
}
unsigned long previousMillis = 0;
const long intervall = 2000;// Daten werden alle 2Sek ausgelesen

void setup() {
  Serial.begin(9600);
  tracerSerial.begin(115200); // Modbus Kommunikation mit 115200 Baud



  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  digitalWrite(MAX485_RE_NEG, 0);// Init in receive mode
  digitalWrite(MAX485_DE, 0);


  // Tracer xxxxAN Modbus slave ID 1
  node.begin(1, tracerSerial);  // Begin der Verbindung mit Tracer
  // Rückrufe ermöglichen es uns, den RS485-Transceiver korrekt zu konfigurieren
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}
void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= intervall)
  {
    previousMillis = currentMillis; // Zeitpunkt der letzten Schaltung wird festgehalten
    // Read 16 registers beginn mit Adresse  0x3100)
    uint8_t result;
    result = node.readInputRegisters(0x3100, 16);
    if (result == node.ku8MBSuccess)
    { //PV Daten
      pvv = node.getResponseBuffer(0x00) / 100.0f; //Tracer PV Volt
      Serial.print("Panel ");
      Serial.print(pvv);
      Serial.print("V  ");
      pva = node.getResponseBuffer(0x01) / 100.0f;//PV Ampere
      Serial.print(pva);
      Serial.print ("A  ");
      //PV Leistung
      pvwat = ((node.getResponseBuffer(0x06) +  node.getResponseBuffer(0x07) ) / 100.0f); //PV Watt
      Serial.print(pvwat);
      Serial.println("W");

      /*****  Akkustand Anzeigen  *****/
      akkuVolt = node.getResponseBuffer(0x04) / 100.0f; //Tracer Akku Volt
      Serial.print("Akku  ");
      Serial.print(akkuVolt);
      Serial.print ("V  ");

      akkuAmpere = node.getResponseBuffer(0x05) / 100.0f;//Akku Ladedaten in Ampere
      Serial.print(akkuAmpere);
      Serial.print("A  ");
      Serial.print(prozent);
      Serial.println ("%");
      Serial.println ("---------------------------------");
    }
    result = node.readInputRegisters(0x311A , 1);//Akkukapazität in Prozent
    if (result == node.ku8MBSuccess) {
      prozent = node.getResponseBuffer(0x00);
    }
  }
}
Benutzeravatar
Admin
Administrator
Beiträge: 1199
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: MPPT Solarlader

Beitrag von Admin »

Hier ist meine Solarheizung, mit der ich den Programm kombiniert habe. Das Programm für sich alleine funktioniert auch.

Code: Alles auswählen

// Arduino Pool_Solarheizung_Pumpensteuerung
#include <OneWire.h>
#include <DallasTemperature.h>
#include "Wire.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
//-----Motortreiber----
const byte RPWM = 10;
const byte LPWM = 11;
//-------Potis---------
const byte Poti1 = A0;
const byte Poti2 = A1;
//-------Taster--------
byte Tasterstatur = 0;
const byte Taster = 4;// Display einschalten
//-------Merker--------
byte Pumpe = 0;
int P1 = 0;
int P2 = 0;
int Drehzahl = 0;
int Solldrehzahl = 0;
int Sollalt = 10;
byte Anfahren = 0;
int Drehzahlmin = 150;
int Drehzahlmax = 255;
unsigned long millisekunden = 0;
//-------------------------------Zeiten---------------------------------------
unsigned long Sekundenablauf01 = 0;      // Messung Potis und Ausgabe Display
const unsigned long Pausezeit01 = 1000;
unsigned long Sekundenablauf02 = 0;      // Display nach Zeit ausschalten
const unsigned long Pausezeit02 = 60000 * 15;
unsigned long Sekundenablauf03 = 0;      //Serial Werte Ausgabezeit
const unsigned long Pausezeit03 = 60000 * 5;
unsigned long Sekundenablauf04 = 0;      // Werte für Pumpe und Pumpe ansteuern
const unsigned long Pausezeit04 = 30000; //Alle 30 Sekunden Daten für Pumpe
const unsigned char One_Wire_Bus = 2;    // Sensoren auf Pin 2
OneWire oneWire(One_Wire_Bus);
DallasTemperature sensoren (&oneWire);
int Anzahl_Sensoren = 0;
int is = 0; // Zähler für die Sensoren
int ia = 0; // Zähler für die Adressstellen 0-7
int Sensor = 0;
float temppool = 0;
float tempsolar = 0;
float tempdif = 0;
DeviceAddress tempDeviceAddress; // Für die Adressausgabe
int numberOfDevices; // Für die Adressausgabe
//##########################################################################
//################################  Setup ##################################
//##########################################################################
void setup() {
  Wire.begin();
  sensoren.begin();
  Serial.begin(9600);
  lcd.begin();
  lcd.backlight();
  lcd.setCursor (0, 0);
  lcd.print (F("Solarheizung - Pool"));
  lcd.setCursor (0, 1);
  lcd.print (F("Soll"));
  lcd.setCursor (10, 1);
  lcd.print (F("Ist"));
  lcd.setCursor (0, 2);
  lcd.print (F("Soll"));
  lcd.setCursor (10, 2);
  lcd.print (F("Ist"));
  lcd.setCursor (0, 3);
  lcd.print (F("Soll      Ist"));
  // Anzahl der Sesoren ermitteln-------------------------------------
  Anzahl_Sensoren = sensoren.getDeviceCount();
  // Ermitteln der Sensor-Adressen------------------------------------
  for (is = 0; is < Anzahl_Sensoren; is++)
  {
    if (sensoren.getAddress(tempDeviceAddress, is))
    {
      Serial.println ();
      printAddress(tempDeviceAddress);
    }
  }
  //-----------Aus-/Eingänge einrichten-------------------------------------
  pinMode(RPWM, OUTPUT);              // PWM Pumpensteuerung
  pinMode(LPWM, OUTPUT);              // PWM Pumpensteuerung
  pinMode(Poti1, INPUT);
  pinMode(Poti2, INPUT);
  pinMode(Taster, INPUT_PULLUP);
}
// Ausgabe der Sensor-Adressen
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t ia = 0; ia < 8; ia++)
  {
    if (deviceAddress[ia] < 16)
    {
      Serial.print("0"); //ist die Hex Adresse kleiner 16 dann erste Stelle eine "0"
    }
    Serial.print(deviceAddress[ia], HEX);
  }
  Serial.println();
}
//###########################################################################
//################################## LOOP ###################################
//###########################################################################
void loop()
{
  millisekunden = millis();
  //--------------------------Display Lichtkontrolle -------------------------
  Tasterstatur = digitalRead(Taster);
  if (Tasterstatur == LOW)
  {
    lcd.backlight();
    Sekundenablauf02 = millisekunden;
  }
  if (millisekunden - Sekundenablauf02 >= Pausezeit02) // Dislay Zeit abgelaufen?
  {
    lcd.noBacklight();
  }
  //--------------------------Display Licht kontrolle Ende-------------------
  //#########################################################################
  //-------------------------Daten auswerten und aufs Display----------------
  if (millisekunden - Sekundenablauf01 >= Pausezeit01) // Eine Sekunde abgelaufen?
  {
    P1 = analogRead (Poti1);
    P1 = map(P1, 0, 1023, 0, 40); // -------Solltemperatur Einstellung-------
    P2 = analogRead (Poti2);
    P2 = map(P2, 0, 1023, 0, 10); // -------Solldiffderenz Einstellung-------
    lcd.setCursor (5, 1);
    lcd.print (P1);
    lcd.print ("  ");
    lcd.setCursor (5, 2);
    lcd.print (P2);
    lcd.print ("  ");
    lcd.setCursor (5, 3);
    lcd.print (Solldrehzahl);
    lcd.print (F("  "));
    lcd.setCursor (14, 3);
    lcd.print (Drehzahl);
    lcd.print (F("  "));
    Sekundenablauf01 = millisekunden;
    // -------------------------Temperatur Sensoren Auswerten---------------------------
    //Temperaturen Aulesen
    sensoren.requestTemperatures();

    // Hier werden die Temp-Sensoren ausgelesen und aufs Display gebracht
    if (Sensor < 2)
    {
      Sensor ++;
      float temperatur = sensoren.getTempCByIndex(Sensor - 1);
      if (Sensor == 1)
      {
        tempsolar = temperatur + 1; // -----------Temperatur Messung 1------------------
      }
      if (Sensor == 2)
      {
        temppool = temperatur - 1; // -----------Temperatur Messung 2------------------
        //--------------------------------------Temperatur aufs Display----------------
        lcd.setCursor (14, 1);
        lcd.print (temppool);
        lcd.print (F(" "));
        tempdif = (tempsolar * 10) - (temppool * 10); //---Themperatur Differenz----
        if (tempdif < 0)
        {
          tempdif = 5;
        }
        lcd.setCursor (14, 2);
        lcd.print (tempdif / 10);
        lcd.print (F(" "));
      }
    }
    // ---Alle Sensoren ausgelesen? Dann für nächste Messungen auf Null Stellen---
    if (Sensor == Anzahl_Sensoren)
    {
      Sensor = 0;
    }
  }
  //-------------------------Daten auslesen und Aufs Diplay Ende------------------
  //##############################################################################
  // ------Daten für Pumpensteuerung auswerten und an Pumpe übergeben-------------

  if (millisekunden - Sekundenablauf04 >= Pausezeit04) // 30 Sekunden abgelaufen?
  {
    // -------Prüfen ob Solartemperatur zum Anlauf der Pumpe sinnvoll ist---------
    if ((tempsolar > 28) && (tempsolar < 33) && (tempdif < 10))
    {
      tempdif = 10;
    }
    if ((tempsolar < 26) && (tempdif < 10))
    {
      tempdif = 0;
    }
    //-------------Solldrehzahl aus Temperaturdifferenz ermitteln--------------
    Solldrehzahl = map(tempdif, 10, 40, 150, 255);
    if (Solldrehzahl > Drehzahlmax)
    {
      Solldrehzahl = Drehzahlmax;
    }
    else
    {
      if (Solldrehzahl < Drehzahlmin)
      {
        Solldrehzahl = Drehzahlmin;
      }
    }
    // Ist gemessene tempdif gleich/größer Solldifferenz, dann Max Drehzahl
    if (tempdif >= (P2 * 10))
    {
      Solldrehzahl = Drehzahlmax;
    }
    //------------------Pumpen Ansteuerung------------------------------------
    // Gibt es keine brauchbare TemperaturDifferenz mehr, dann Pumpe auf PWM 0
    if (Anfahren == 0)
    {
      if (tempdif < 10) //---Temp.Differenz kleiner 1 Grad, dann Pumpe aus----
      {
        Solldrehzahl = 0;
      }
      // Ist aber die Wunsch-Temperatur +2 erreicht, dann keine Solar Unterstützung mehr
      if (temppool > (P1 + 2))
      {
        Solldrehzahl = 0;
      }
      // Ist Solldrehzahl erreicht ? Dann Drehzahl auf die Solldrehzahl einstellen
      if (Solldrehzahl < Sollalt)
      {
        Drehzahl = Solldrehzahl;
        Sollalt = Solldrehzahl;
      }
    }
    // Ist Solldrehzahl nicht erreicht dann Drehzahl um 10 erhöhen
    if ((Solldrehzahl > Sollalt) && (tempdif > 13))
    {
      if (Drehzahl < 120)
      {
        Drehzahl = 130;
      }
      Drehzahl = Drehzahl + 10;
      // Wenn über Max, dann die Drehzahl auf Maxdrehzahl anpassen
      if (Drehzahl > Drehzahlmax)
      {
        Drehzahl = Drehzahlmax;
      }
      Sollalt = Drehzahl;
      Anfahren = 1;
    }
    else
    {
      Anfahren = 0;
    }
    analogWrite(RPWM, Drehzahl);
    analogWrite(LPWM, 0);
    Sekundenablauf04 = millisekunden;
  }
  //------------------------Pumpensteuerung Ende-------------------------------
  //###########################################################################
  // ------------------------Serial Print Ausgabe------------------------------
  if (millisekunden - Sekundenablauf03 >= Pausezeit03) // Serial Ausgabezeit abgelaufen?
  {
    Serial.println("--------------------");
    Serial.print("Drehzahl Pumpe = ");
    Serial.print(Drehzahl);
    Serial.print(" - ");
    Serial.println(Solldrehzahl);
    Serial.print("Temp Pool = ");
    Serial.println(temppool);
    Serial.print("Temp Solar = ");
    Serial.println(tempsolar);
    Serial.print("Temp Differenz = ");
    Serial.println(tempsolar - temppool);
    Sekundenablauf03 = millisekunden;
  }
  //-------------------------Seriale Ausgabe Ende-----------------------------
}
Du hast mal irgendwas geschrieben dass dein Programm in Kombination mit irgend einer Lib nicht funtioniert?
Bernhard - Fony
Beiträge: 73
Registriert: Mo 12. Jun 2023, 17:49
Kontaktdaten:

Re: MPPT Solarlader

Beitrag von Bernhard - Fony »

Muss mir das Morgen mall ansehen, wenn nur modbuss funktioniert sollte auch komplett funktioniere.
Dein Speicher wird alle, schätze mall, nimm doch F-Makro auch für Serial, Programmspeicher darf 100% voll sein, RAM so wenig wie möglich

Code: Alles auswählen

Serial.print(F("Drehzahl Pumpe = "));
Benutzeravatar
Admin
Administrator
Beiträge: 1199
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: MPPT Solarlader

Beitrag von Admin »

OK, also einen konkreten Grund weißt du im Moment nicht. Ich dachte, nicht dass ich suche und du weißt den Grund schon. Stimmt, ich habe gar nicht auf die Speicherbelegung geachtet. Mache ich gleich mal. Danke für den Tipp. Manchmal sieht man den Wald vorlauter Bäume nicht. :(o): :(o):
Bernhard - Fony
Beiträge: 73
Registriert: Mo 12. Jun 2023, 17:49
Kontaktdaten:

Re: MPPT Solarlader

Beitrag von Bernhard - Fony »

Also bevor ich auf ESP8266 umgestiegen bin, habe das ausgelesen mit mit einem Tandem aus zwei Nano, eine war zuständig für Tracer und RTC, der andere für Anzeige und Dtatalog auf SD.
Nach dem Umstieg auf ESP wollte die SD nicht, hat sich herausgestellt das die Allgemein macht Probleme mit ESP, nach kurze suche im Netz habe andere SD Lib gefunden.
Das war das Problem wo ran Du dich erinnerst ;)
Benutzeravatar
Admin
Administrator
Beiträge: 1199
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: MPPT Solarlader

Beitrag von Admin »

Ich habe jetzt die beiden Programme nochmal neu zu einem Programm zusammengebaut, diesmal gibts keine Meldung. Ich werde es heute oder Morgen im Poolhaus testen ob es miteinander arbeitet. Und wenn es das tut, dann baue ich die Schnittstelle zum MPPT Lader ein.

Frage mich nicht warum es jetzt geht, aber der Compieler hat keine Beschwerden mehr. Speicherplatz scheint mehr als genug zu verbleiben. :(oo): Die Serial.prints() kommen ja auch noch alle raus. Die Seral-print(); sind ja ALLE nur zur Kontrolle, bis das Programm rund läuft.

Hier ist das Programm nochmal, wie es jetzt zu funktionieren scheint:

Code: Alles auswählen

// Arduino Pool_Solarheizung_Pumpensteuerung
#include <OneWire.h>
#include <DallasTemperature.h>
#include "Wire.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
//###########################################################################
//-------------------------------------------------MPPT Regler---------------
/*************************************
   Für Uno wird SoftwareSerial benutzt
**************************************/
#include <SoftwareSerial.h>
SoftwareSerial tracerSerial(4, 5); // RO, DI  Pins drehen wenn nicht funktioniert

/**********************************************
    Ich verwende  einen MAX485-kompatiblen RS485-Transceiver.
  Rx/Tx ist mit der seriellen Schnittstelle der Hardware an "Serial" verbunden.
  Die Pins "Data Enable" und "Rec3eiver Enable" sind wie folgt beschaltet:
 ********************************************************/
#include <ModbusMaster.h>

#define MAX485_DE      3 // DE und RE dürfen am einen Pin hängen 
#define MAX485_RE_NEG  3

// instantiate ModbusMaster object
ModbusMaster node;

int prozent = 0;
float akkuVolt = 0;
float akkuAmpere = 0;
float pvwat = 0;
float pva = 0;
float pvv = 0;
unsigned long currentMillis = 0;

void preTransmission()
{
  digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
}

void postTransmission()
{
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
}
unsigned long previousMillis = 0;
const long intervall = 2000;// Daten werden alle 2Sek ausgelesen
//-------------------------------------------------MPPT Regler Ende----------
//###########################################################################
//-----Motortreiber----
const byte RPWM = 10;
const byte LPWM = 11;
//-------Potis---------
const byte Poti1 = A0;
const byte Poti2 = A1;
//-------Taster--------
byte Tasterstatur = 0;
const byte Taster = 6;// Display einschalten !! Geändert weil 4 belegt ist !!
//-------Merker--------
byte Pumpe = 0;
int P1 = 0;
int P2 = 0;
int Drehzahl = 0;
int Solldrehzahl = 0;
int Sollalt = 10;
byte Anfahren = 0;
int Drehzahlmin = 150;
int Drehzahlmax = 255;
unsigned long millisekunden = 0;
//-------------------------------Zeiten---------------------------------------
unsigned long Sekundenablauf01 = 0;      // Messung Potis und Ausgabe Display
const unsigned long Pausezeit01 = 1000;
unsigned long Sekundenablauf02 = 0;      // Display nach Zeit ausschalten
const unsigned long Pausezeit02 = 60000 * 15;
unsigned long Sekundenablauf03 = 0;      //Serial Werte Ausgabezeit
const unsigned long Pausezeit03 = 60000 * 5;
unsigned long Sekundenablauf04 = 0;      // Werte für Pumpe und Pumpe ansteuern
const unsigned long Pausezeit04 = 30000; //Alle 30 Sekunden Daten für Pumpe
const unsigned char One_Wire_Bus = 2;    // Sensoren auf Pin 2
OneWire oneWire(One_Wire_Bus);
DallasTemperature sensoren (&oneWire);
int Anzahl_Sensoren = 0;
int is = 0; // Zähler für die Sensoren
int ia = 0; // Zähler für die Adressstellen 0-7
int Sensor = 0;
float temppool = 0;
float tempsolar = 0;
float tempdif = 0;
DeviceAddress tempDeviceAddress; // Für die Adressausgabe
int numberOfDevices; // Für die Adressausgabe
//##########################################################################
//################################  Setup ##################################
//##########################################################################
void setup() {
  Wire.begin();
  sensoren.begin();
  Serial.begin(9600);
  lcd.begin();
  lcd.backlight();
  //##########################################################################
  //-----------------------------------MPPT Setup-----------------------------
  tracerSerial.begin(115200); // Modbus Kommunikation mit 115200 Baud
  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  digitalWrite(MAX485_RE_NEG, 0);// Init in receive mode
  digitalWrite(MAX485_DE, 0);
  // Tracer xxxxAN Modbus slave ID 1
  node.begin(1, tracerSerial);  // Begin der Verbindung mit Tracer
  // Rückrufe ermöglichen es uns, den RS485-Transceiver korrekt zu konfigurieren
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
  //-------------------------------MPPT Setup Ende--------------------------
  //##########################################################################
  lcd.setCursor (0, 0);
  lcd.print (F("Solarheizung - Pool"));
  lcd.setCursor (0, 1);
  lcd.print (F("Soll"));
  lcd.setCursor (10, 1);
  lcd.print (F("Ist"));
  lcd.setCursor (0, 2);
  lcd.print (F("Soll"));
  lcd.setCursor (10, 2);
  lcd.print (F("Ist"));
  lcd.setCursor (0, 3);
  lcd.print (F("Soll      Ist"));
  // Anzahl der Sesoren ermitteln-------------------------------------
  Anzahl_Sensoren = sensoren.getDeviceCount();
  // Ermitteln der Sensor-Adressen------------------------------------
  for (is = 0; is < Anzahl_Sensoren; is++)
  {
    if (sensoren.getAddress(tempDeviceAddress, is))
    {
      Serial.println ();
      printAddress(tempDeviceAddress);
    }
  }
  //-----------Aus-/Eingänge einrichten-------------------------------------
  pinMode(RPWM, OUTPUT);              // PWM Pumpensteuerung
  pinMode(LPWM, OUTPUT);              // PWM Pumpensteuerung
  pinMode(Poti1, INPUT);
  pinMode(Poti2, INPUT);
  pinMode(Taster, INPUT_PULLUP);
}
// Ausgabe der Sensor-Adressen
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t ia = 0; ia < 8; ia++)
  {
    if (deviceAddress[ia] < 16)
    {
      Serial.print("0"); //ist die Hex Adresse kleiner 16 dann erste Stelle eine "0"
    }
    Serial.print(deviceAddress[ia], HEX);
  }
  Serial.println();
}
//###########################################################################
//################################## LOOP ###################################
//###########################################################################
void loop()
{
  millisekunden = millis();
  //--------------------------Display Lichtkontrolle -------------------------
  Tasterstatur = digitalRead(Taster);
  if (Tasterstatur == LOW)
  {
    lcd.backlight();
    Sekundenablauf02 = millisekunden;
  }
  if (millisekunden - Sekundenablauf02 >= Pausezeit02) // Dislay Zeit abgelaufen?
  {
    lcd.noBacklight();
  }
  //--------------------------Display Licht kontrolle Ende-------------------
  //#########################################################################
  //-------------------------Daten auswerten und aufs Display----------------
  if (millisekunden - Sekundenablauf01 >= Pausezeit01) // Eine Sekunde abgelaufen?
  {
    P1 = analogRead (Poti1);
    P1 = map(P1, 0, 1023, 0, 40); // -------Solltemperatur Einstellung-------
    P2 = analogRead (Poti2);
    P2 = map(P2, 0, 1023, 0, 10); // -------Solldiffderenz Einstellung-------
    lcd.setCursor (5, 1);
    lcd.print (P1);
    lcd.print ("  ");
    lcd.setCursor (5, 2);
    lcd.print (P2);
    lcd.print ("  ");
    lcd.setCursor (5, 3);
    lcd.print (Solldrehzahl);
    lcd.print (F("  "));
    lcd.setCursor (14, 3);
    lcd.print (Drehzahl);
    lcd.print (F("  "));
    Sekundenablauf01 = millisekunden;
    // -------------------------Temperatur Sensoren Auswerten---------------------------
    //Temperaturen Aulesen
    sensoren.requestTemperatures();

    // Hier werden die Temp-Sensoren ausgelesen und aufs Display gebracht
    if (Sensor < 2)
    {
      Sensor ++;
      float temperatur = sensoren.getTempCByIndex(Sensor - 1);
      if (Sensor == 1)
      {
        tempsolar = temperatur + 1; // -----------Temperatur Messung 1------------------
      }
      if (Sensor == 2)
      {
        temppool = temperatur - 1; // -----------Temperatur Messung 2------------------
        //--------------------------------------Temperatur aufs Display----------------
        lcd.setCursor (14, 1);
        lcd.print (temppool);
        lcd.print (F(" "));
        tempdif = (tempsolar * 10) - (temppool * 10); //---Themperatur Differenz----
        if (tempdif < 0)
        {
          tempdif = 5;
        }
        lcd.setCursor (14, 2);
        lcd.print (tempdif / 10);
        lcd.print (F(" "));
      }
    }
    // ---Alle Sensoren ausgelesen? Dann für nächste Messungen auf Null Stellen---
    if (Sensor == Anzahl_Sensoren)
    {
      Sensor = 0;
    }
  }
  //-------------------------Daten auslesen und Aufs Diplay Ende------------------
  //##############################################################################
  // ------Daten für Pumpensteuerung auswerten und an Pumpe übergeben-------------

  if (millisekunden - Sekundenablauf04 >= Pausezeit04) // 30 Sekunden abgelaufen?
  {
    // -------Prüfen ob Solartemperatur zum Anlauf der Pumpe sinnvoll ist---------
    if ((tempsolar > 28) && (tempsolar < 33) && (tempdif < 10))
    {
      tempdif = 10;
    }
    if ((tempsolar < 26) && (tempdif < 10))
    {
      tempdif = 0;
    }
    //-------------Solldrehzahl aus Temperaturdifferenz ermitteln--------------
    Solldrehzahl = map(tempdif, 10, 40, 150, 255);
    if (Solldrehzahl > Drehzahlmax)
    {
      Solldrehzahl = Drehzahlmax;
    }
    else
    {
      if (Solldrehzahl < Drehzahlmin)
      {
        Solldrehzahl = Drehzahlmin;
      }
    }
    // Ist gemessene tempdif gleich/größer Solldifferenz, dann Max Drehzahl
    if (tempdif >= (P2 * 10))
    {
      Solldrehzahl = Drehzahlmax;
    }
    //------------------Pumpen Ansteuerung------------------------------------
    // Gibt es keine brauchbare TemperaturDifferenz mehr, dann Pumpe auf PWM 0
    if (Anfahren == 0)
    {
      if (tempdif < 10) //---Temp.Differenz kleiner 1 Grad, dann Pumpe aus----
      {
        Solldrehzahl = 0;
      }
      // Ist aber die Wunsch-Temperatur +2 erreicht, dann keine Solar Unterstützung mehr
      if (temppool > (P1 + 2))
      {
        Solldrehzahl = 0;
      }
      // Ist Solldrehzahl erreicht ? Dann Drehzahl auf die Solldrehzahl einstellen
      if (Solldrehzahl < Sollalt)
      {
        Drehzahl = Solldrehzahl;
        Sollalt = Solldrehzahl;
      }
    }
    // Ist Solldrehzahl nicht erreicht dann Drehzahl um 10 erhöhen
    if ((Solldrehzahl > Sollalt) && (tempdif > 13))
    {
      if (Drehzahl < 120)
      {
        Drehzahl = 130;
      }
      Drehzahl = Drehzahl + 10;
      // Wenn über Max, dann die Drehzahl auf Maxdrehzahl anpassen
      if (Drehzahl > Drehzahlmax)
      {
        Drehzahl = Drehzahlmax;
      }
      Sollalt = Drehzahl;
      Anfahren = 1;
    }
    else
    {
      Anfahren = 0;
    }
    analogWrite(RPWM, Drehzahl);
    analogWrite(LPWM, 0);
    Sekundenablauf04 = millisekunden;
  }
  //------------------------Pumpensteuerung Ende-------------------------------
  //###########################################################################
  // ------------------------Serial Print Ausgabe------------------------------
  if (millisekunden - Sekundenablauf03 >= Pausezeit03) // Serial Ausgabezeit abgelaufen?
  {
    Serial.println("--------------------");
    Serial.print("Drehzahl Pumpe = ");
    Serial.print(Drehzahl);
    Serial.print(" - ");
    Serial.println(Solldrehzahl);
    Serial.print("Temp Pool = ");
    Serial.println(temppool);
    Serial.print("Temp Solar = ");
    Serial.println(tempsolar);
    Serial.print("Temp Differenz = ");
    Serial.println(tempsolar - temppool);
    Sekundenablauf03 = millisekunden;
  }
  //-------------------------Seriale Ausgabe Ende-----------------------------
  //##########################################################################
  //-------------------------------MPPT LOOP----------------------------------
  currentMillis = millis();
  if (currentMillis - previousMillis >= intervall)
  {
    previousMillis = currentMillis; // Zeitpunkt der letzten Schaltung wird festgehalten
    // Read 16 registers beginn mit Adresse  0x3100)
    uint8_t result;
    result = node.readInputRegisters(0x3100, 16);
    if (result == node.ku8MBSuccess)
    { //PV Daten
      pvv = node.getResponseBuffer(0x00) / 100.0f; //Tracer PV Volt
      Serial.print("Panel ");
      Serial.print(pvv);
      Serial.print("V  ");
      pva = node.getResponseBuffer(0x01) / 100.0f;//PV Ampere
      Serial.print(pva);
      Serial.print ("A  ");
      //PV Leistung
      pvwat = ((node.getResponseBuffer(0x06) +  node.getResponseBuffer(0x07) ) / 100.0f); //PV Watt
      Serial.print(pvwat);
      Serial.println("W");

      /*****  Akkustand Anzeigen  *****/
      akkuVolt = node.getResponseBuffer(0x04) / 100.0f; //Tracer Akku Volt
      Serial.print("Akku  ");
      Serial.print(akkuVolt);
      Serial.print ("V  ");

      akkuAmpere = node.getResponseBuffer(0x05) / 100.0f;//Akku Ladedaten in Ampere
      Serial.print(akkuAmpere);
      Serial.print("A  ");
      Serial.print(prozent);
      Serial.println ("%");
      Serial.println ("---------------------------------");
    }
    result = node.readInputRegisters(0x311A , 1);//Akkukapazität in Prozent
    if (result == node.ku8MBSuccess) {
      prozent = node.getResponseBuffer(0x00);
    }
  }
  //-----------------------------MPPT LOOP Ende-------------------------------
  //##########################################################################
}
Bis später, jetzt muss ich erst mal meine Radtour auf dem Fitnesstrainer machen. :()-(): Wenn ich danach noch Lust habe, gehe ich mit dem Notebook auch noch ins Poolhaus. :O:
Antworten

Zurück zu „Hardware / Schaltungstechnik“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 35 Gäste