Class Bewässerung Problem mit der Initialisierung

Hallo,

dies ist meine erste Frage in diesem Forum und ich hoffe, dass ich alles richtig mache.
ich habe für meinen Arduino ESP32 den folgenden Sketch gefunden und angepasst:

#include <Streaming.h>
#include <LiquidCrystal_I2C.h>
#include <String.h>
LiquidCrystal_I2C lcd(0x27,16,2);

const uint16_t MINBEWAESSERUNGSZEIT = 5000;

int Menue_Schalter = 3;
String Menue_Text1;
String Menue_Text2;

char* names[] = {"Vent.1 ", "Vent.2 "};
uint32_t tw[2] = {320, 30};
uint8_t cpos;

class Bewaesserung
{
    const byte ventilPin;
    const byte sensorPin;
    char* Name;
    const byte zeile;
    const uint32_t trockenwert;
    const uint32_t bewaesserungszeit;

  public:
    Bewaesserung(const byte ventilPin, const byte sensorPin, char Name[], const byte zeile, uint32_t trockenwert, uint32_t bewaesserungszeit) 
      : ventilPin(ventilPin), sensorPin(sensorPin), Name(Name), zeile(zeile), trockenwert(trockenwert), bewaesserungszeit(bewaesserungszeit) 
    {
    }

    void Menue()
    {
    }

    void init()
    {
      pinMode(ventilPin, OUTPUT);
      digitalWrite(ventilPin, HIGH);
      lcd.init();                    // Display initialisieren 
      lcd.backlight();               // Hintergrundbeleuchtung
      lcd.clear();

      // pinMode (Menue_Schalter, INPUT_PULLUP);
    }

    void bewaessern()
    {
      uint16_t sensorWert = analogRead(sensorPin);      // Wert von Sensor wird gelesen

      Serial << "vor dem giesen " << "  Name: " << Name << "  \tSensor Wert : " << sensorWert << "  \tTrockenwert: " << trockenwert << " \tBewässerungszeit: " << bewaesserungszeit/1000 << " sec." << endl;
      
      drucklcd(zeile,Name,sensorWert);

      if (sensorWert > trockenwert)
      {
        digitalWrite(ventilPin, LOW);           // Ventil öffnen
        Serial.print(Name);
        Serial.println("ist auf");
        druckMenue(11,zeile, "giest");
        if (digitalRead(Menue_Schalter) == HIGH) {
          Serial.println("Schalter gedrückt");
          Menue();
        }
        delay(bewaesserungszeit);
        digitalWrite(ventilPin, HIGH);
        Serial.print(Name);
        Serial.println("ist zu");

        sensorWert = analogRead(sensorPin);
        drucklcd(zeile, Name, sensorWert);
        Serial << "nach dem giesen  " << "  Name: " << Name << "  \tSensor Wert : " << sensorWert << "  \tTrockenwert: " << trockenwert << " \tBewässerungszeit: " << bewaesserungszeit/1000 << " sec." << endl;
      } else {
        Serial.print(Name);
        Serial.println("muss nicht geöffnet werden!");
        if (digitalRead(Menue_Schalter) == HIGH) {
          Serial.println("Schalter gedrückt");
          Menue();
        }
        delay( 12 * MINBEWAESSERUNGSZEIT );
      }
      sensorWert = analogRead(sensorPin);
      drucklcd(zeile, Name, sensorWert);

      Serial << "  Name: " << Name << "  \tSensor Wert : " << sensorWert << "  \tTrockenwert: " << trockenwert << endl;      
    }
  
    void drucklcd(byte zeile, String Name, uint16_t sensorWert)
    {
        // Zahlen des Sensors rechtsbündig ausgeben
        if (sensorWert < 10 && sensorWert > 0)
          cpos = Name.length() + 3;
        if(sensorWert > 9 && sensorWert < 100)
          cpos = Name.length() + 2;
        if(sensorWert > 99 && sensorWert < 1000)
          cpos = Name.length() + 1;
        if(sensorWert > 999)
          cpos = Name.length();

        lcd.setCursor(0, zeile);
        lcd.print("                ");  //kpl. Zeile löschen
        // Zeile neu beschreiben
        lcd.setCursor(0, zeile);
        lcd.print(Name);
        lcd.setCursor(cpos, zeile);
        lcd.print(sensorWert);
        
        lcd.setCursor(12,zeile);
        lcd.print(trockenwert);
    }

    void druckMenue(byte pos, byte zeile, String wert)
    {
      lcd.setCursor(pos,zeile);
      lcd.print(wert);
    }
};

Bewaesserung bewaesserung[] =
{ // ventilPin, sensorPin, Name, zeile, trockenwert, bewässerungszeit
  {2, A7, names[0], 0, tw[0], 30000},
  {6, A6, names[1], 1, tw[1], 120000},
};

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  for (auto &b : bewaesserung) b.init();
}

void loop()
{
  for (auto &b : bewaesserung) b.bewaessern();
}

Dies funktioniert sehr gut.
Ich möchte jetzt die Werte Name, trockenwert und bewässerungszeit aus einer MySQL-Datenbank holen und einsetzen. Das holen aus der Datenbank habe ich bereits erfolgreich installiert. Aber ich bekomme es nicht hin diese Werte ins Programm zu integrieren. Folgendes habe ich dafür geändert:

char* names[] = {"Vent.1 ", "Vent.2 "};
uint32_t tw[2] = {320, 30};

in das geändert:

char* names[2]; 
int arrTrockenwert;
uint bewZeit[2]  ;

und das:

Bewaesserung bewaesserung[] =
{ // ventilPin, sensorPin, Name, zeile, trockenwert, bewässerungszeit
  {2, A7, names[0], 0, tw[0], 30000},
  {6, A6, names[1], 1, tw[1], 120000},
};

in das geändert:

Bewaesserung bewaesserung[] =
{ // ventilPin, sensorPin, Name, zeile, trockenwert, bewässerungszeit
  {2, A7, names[0], 0, arrTrockenwert[0], bewZeit[0]},
  {6, A6, names[1], 1, arrTrockenwert[1], bewZeit[1]},
};

im setup() werden die Daten aus der Datenbank zugefügt:

  idWerte = atoi(strtok(buffer, ","));
  MINBEWAESSERUNGSZEIT = atoi(strtok(NULL, ","));
  interval = atol(strtok(NULL, ","));
  arrTrockenwert[0] = atoi(strtok(NULL, ","));
  arrTrockenwert[1] = atoi(strtok(NULL, ","));
  bewZeit[0] = atoi(strtok(NULL, ","));
  bewZeit[1] = atoi(strtok(NULL, ","));
  names[0] = (strtok(NULL, ","));
  names[1] = (strtok(NULL, ","));

Auch das funktioniert gut.

Was muss ich jetzt tun damit die Variablen names[0] und names[1] jeweils in die Variable Name,
die Variablen arrTrockenwert[0] und arrTrockenwert[1] jeweils in die Variable trockenwert,
und die Variablen bewZeit[0] und bewZeit[1] jeweils in die Variable bewaesserungszeit übernommen werden?

Ich habe in meiner aktiven Zeit einiges in C programmiert aber mit C++ stehe ich noch auf dem Kriegsfuss und bitte deshalb um Nachsicht. Danke schön.

Viele Grüße
Dieter

1 Like

Zeig mal den Sketch wo du die Were aus der DB holst und zunächst einfach auf der Seriellen Schnittstelle ausgibst.

Damit du Werte von (private) member Variablen deiner Klasse Bewaesserung verändert kannst, dürfen diese nicht const sein. Weiters brauchst du je einen Setter
z.B.:

	void setTrockenwert (uint32_t value) {
		trockenwert = value;
	}

dann kannst du (wenn trockenwert nicht mehr const ist) das setzen:

  int i = 0;  
  bewaesserung[i].setTrockenwert(arrTrockenwert[i]);

Und für einen variablen Namen würde ich ein char Array mit z.B. 16 byte vorschlagen und dann auch wieder einen setter

Hallo noiasca,

hier der MySQL-Sketch:

void conMySQL() {
    if (conn.connectNonBlocking(server, server_port, user, password, default_database) != RESULT_FAIL) {
    delay(500);
    runQuery();
    conn.close();  // close the connection
  } else {
    ESP32_MYSQL_DISPLAY("\nConnect failed. Trying again on next iteration.");
  }

  delay(1000);
}

void runQuery() {

  ESP32_MySQL_Query query_mem = ESP32_MySQL_Query(&conn);

  // Execute the query
  // ESP32_MYSQL_DISPLAY(query);

  if (!query_mem.execute(query.c_str())) {
    ESP32_MYSQL_DISPLAY("Querying error");
    return;
  }

  // Show the result
  // Fetch the columns and print them
  column_names *cols = query_mem.get_columns();

  for (int f = 0; f < cols->num_fields; f++) {
    // ESP32_MYSQL_DISPLAY0(cols->fields[f]->name);

    if (f < cols->num_fields - 1) {
      // ESP32_MYSQL_DISPLAY0(", ");
    }
  }
  // ESP32_MYSQL_DISPLAY("\n--------------------");

  // Read the rows and print them
  row_values *row = NULL;
  do {
    row = query_mem.get_next_row();

    if (row != NULL) {
      for (int f = 0; f < cols->num_fields; f++) {
        // ESP32_MYSQL_DISPLAY0(row->values[f]);
        strcat(buffer, row->values[f]);
        strcat(buffer,",");
        if (f < cols->num_fields - 1) {
          // ESP32_MYSQL_DISPLAY0(", ");
        }
      }
    }
  } while (row != NULL);

  delay(500);
}

Das const war nur ein Versuch. Auch ohne gings nicht.
Das mit setTrockenwert verstehe ich nicht so ganz. Ich dachte, dass daurch:

char* names[2]; 
int arrTrockenwert[2]; 
int bewZeit[2]; 
uint cpos;
int cnt = 0;

die Zuweisung damit erfolgt:

class Bewaesserung
{
    byte ventilPin;
    byte sensorPin;
    char* Name;
    byte zeile;
    int trockenwert;
    int bewaesserungszeit;

  public:
    Bewaesserung(byte ventilPin, byte sensorPin, char* Name, byte zeile, int trockenwert, int bewaesserungszeit) 
      : ventilPin(ventilPin), sensorPin(sensorPin), Name(Name), zeile(zeile), trockenwert(trockenwert), bewaesserungszeit(bewaesserungszeit) 
    {
    }

Du hast schon recht, die privaten Member-Variablen werden in deinem Konstruktor per Initialisierungsliste gefüllt.
Wenn sie danach nicht mehr geändert werden, brauchst du keine Setter-Methode und sie können als const deklariert sein.

Allerdings hast du evtl. ein Problem mit char* Name. Das ist nur ein Zeiger, der auf eine Stelle in buffer zeigt. Ist das nur eine lokale Variable mit temporärer Gültigkeit???

Oder stehen die Werte für deine zwei Elemente von Bewaesserung bewaesserung[] in einer einzigen Zeile der Datenbank in der Reihenfolge wie du sie hinterher mit der strtok -Sequenz wieder auseinanderpflückst? Dann muss buffer nur global oder static sein, und groß genug.
buffer erst mit strcat zusammenmontieren und hinterher mit strtok trennen finde ich zwar unschön, kann man aber machen. Falls du ein Problem hast, hängt das wohl an diesem buffer.

Wenn die Datenbank aus zwei Zeilen für die zwei Elemente von Bewaesserung besteht, passt die Sache mit deinem buffer so nicht.

Du kannst bewaesserungszeit erst initialisieren, wenn deine Hilfsvariablen gefüllt sind.

Das ist vermutlich immer noch eine globale Variable und wird lange vor setup erzeugt.
Entweder dynamisch erzeugen oder die Elemente nicht const machen und sie erst später füllen.

Musst du unbedingt eine Datenbank haben. ??

Ich habe bei meiner Bewässerungssteuerung eine 2 Euro Membranentastatur eingebaut.

Beim Druck auf MENÜ kann ich mich durch die einzelnen Werte (Messzeit, Laufzeit der Pumpe, Mind. Wert für Feuchtesensor etc) durchschalten.
Dann mit + / - Taste den neuen Wert eingeben und SPEICHERN.
Gespeichert wird das im Internen Flashspeicher da ich ein Nano benutze. Bei einen anderen MC gibt es da oft auch andere Möglichkeiten.

Bei einen Neustart werden die Werte einfach in der INI Routine aus den Speicher gelesen und in die passenden Variablen übergeben.

Wäre vielleicht auch für dich eine Möglichkeit.

Gruß

Pucki

Nano v3 hat auch Eeprom. Im Fash speichern, na ja.

Hallo michael_x,

der komplette Satz aus der Datenbank ist in einer Zeile.
Ich werde heute Deine Ratschläge testen.

Hallo pucki 007,

es ist eigentlich egal wo die Daten herkommen. Mein Problem ist eigentlich nur die einbindung an der richtigen Stelle. Die Daten bekomme ich zuverlässig aus der Datenbank und dort kann kann ich sie problemlos anpassen. Aber danke für deine Antwort.

Hab ich tief geschlafen beim Tippen. ;(

Selbstverständlich im Eeprom. Sonnst ist ja alles weg bei Strom weg.

Danke für Hinweis.

int16_t wert_sensor_1;   // ini die Variable für Sensor 1 (2 Kästen je Kasten eine Punke)

void setup() {
 ii = Rtc.GetMemory(3);  // lese feuchte_wert 1
 wert_sensor_1 = (ii * 200) + Rtc.GetMemory(4);
}

// Da der Wert > 256 sein kann brauchte ich 2 Speicherstellen. Und 200 ist einfacher zu rechnen  ;)

Ach kleiner Hinweis (Weshalb ich mich vertan habe) Um Speicher zu sparen und da ich nur wenige Werte auslagern muss habe ich den Speicher des Uhrenmodul benutzt.
Weshalb ich keine Eeprom Libs laden musste. Die Uhren Libs war ja eh da.

Gruß

Pucki
Pucki

Dann schau dir mein Mirco-Beispiel an.

Ich setze eine INTEGER Variable und füttere sie in den Setup-Routine.

Ob du nun ein UHRmodul (wie ich) nimmst, oder eine DB ist eigentlich egal. Hauptsache die Variable ist ordentlich deklariert.

Und für eine Bewässerung brauchst du (falls du kein Zeit-Protokoll willst) eh nur Integer-Variablen m.M.n.

Gruß

Pucki

Für solch einen Fall gibt es für die ESP extra Preferences. Damit legst du derartige Daten sehr komfortabel ab.

Wie sieht denn deine Zeile mit den Daten in der Datenbank aus ?

Also in der Datenbanktabelle ist nur eine Zeile vorhanden und die sieht so aus:

Feldnamen:
idWerte,MINBEWAESSERUNGSZEIT,interval,Trockenwert1,Trockenwert2,bewaesserungszeit1,bewaesserungszeit2,Name1,Name2
und so stehen die Werte der Felder in der globalen Variable buffer:
1,5000,30000,400,40,10000,5000,Vent.1,Vent.2

und so wird sie den nötigen Variablen zugewiesen:

  idWerte = atoi(strtok(buffer, ","));
  MINBEWAESSERUNGSZEIT = atoi(strtok(NULL, ","));
  interval = atol(strtok(NULL, ","));
  arrTrockenwert[0] = atoi(strtok(NULL, ","));
  arrTrockenwert[1] = atoi(strtok(NULL, ","));
  bewZeit[0] = atoi(strtok(NULL, ","));
  bewZeit[1] = atoi(strtok(NULL, ","));
  names[0] = (strtok(NULL, ","));
  names[1] = (strtok(NULL, ","));

Ich weiß, dass dies nicht elegant ist aber das Ziel war jetzt schnellstmöglich an die Daten zu kommen. Wenn alles soweit funktioniert werde ich das natürlich eleganter gestalten.

Ich muss jetzt mal den Programmablauf erklären:

im setup wird eine Verbindung zu meinem WLAN aufgebaut.
wenn die verbindung steht wird ein connect zur Datenbank hergestellt und in diesem connect wird char buffer[100] mit den Werten gefüllt. schaut dann so aus:
1,5000,30000,400,40,10000,5000,Vent.1,Vent.2,
vor dem connect zur Datenbank musste ich dies auführen:

strncpy(buffer, " ", 100);

ohne diesen strncpy hat der connect nicht geklappt.
dann werden diese Befehle ausgeführt:

  idWerte = atoi(strtok(buffer, ","));
  MINBEWAESSERUNGSZEIT = atoi(strtok(NULL, ","));
  interval = atol(strtok(NULL, ","));
  arrTrockenwert[0] = atoi(strtok(NULL, ","));
  arrTrockenwert[1] = atoi(strtok(NULL, ","));
  bewZeit[0] = atoi(strtok(NULL, ","));
  bewZeit[1] = atoi(strtok(NULL, ","));
  names[0] = (strtok(NULL, ","));
  names[1] = (strtok(NULL, ","));

  Serial << "\narrTrockenwert[0]: " << arrTrockenwert[0] << "\tarrTrockenwert[1]: " << arrTrockenwert[1] << "\tbewZeit[0]: " << bewZeit[0] << "\tbewZeit[1]: " << bewZeit[1] << "\tnames[0]: " << names[0] << "\tnames[1]: " << names[1] << endl;
 

im Serialmonitor wird dieses angezeigt:
arrTrockenwert[0]: 400 arrTrockenwert[1]: 40 bewZeit[0]: 10000 bewZeit[1]: 5000 names[0]: Vent.1 names[1]: Vent.2

das sind genau die werte aus der Datenbank.

dann kommt init() da wird nur das Display vorbereitet
im loop() wird

for (auto& b : bewaesserung) b.bewaessern();

ausgeführt.
Ich meine, dass mit diesem for diese Parameter an die funktion void bewaessern()
übergeben werden:

Bewaesserung bewaesserung[] = {  // ventilPin, sensorPin, Name, zeile, trockenwert, bewässerungszeit
  { 2, A7, names[0], 0, arrTrockenwert[0], bewZeit[0] },
  { 6, A6, names[1], 1, arrTrockenwert[1], bewZeit[1] },
};

in der Klasse Bewaesserung geht es so los:

class Bewaesserung {
  byte ventilPin;
  byte sensorPin;
  char* Name;
  byte zeile;
  int trockenwert;
  int bewaesserungszeit;

public:
  Bewaesserung(byte ventilPin, byte sensorPin, char* Name, byte zeile, int trockenwert, int bewaesserungszeit)
    : ventilPin(ventilPin), sensorPin(sensorPin), Name(Name), zeile(zeile), trockenwert(trockenwert), bewaesserungszeit(bewaesserungszeit) 
  {
  }

dann wird die Funktion bewaessern() einmal mit diesen Parametern:

{ 2, A7, names[0], 0, arrTrockenwert[0], bewZeit[0] },

und ein 2. mal mit diesen Parametern aufgerufen:

{ 6, A6, names[1], 1, arrTrockenwert[1], bewZeit[1] },

diese Parameter werden aber nicht übergeben und da sind meine c++ Kenntnisse am Ende.
in der Klasse Bewaesserung steht diese Funktion bewaessern() in der dann die Feuchtigkeit gemessen wird und die Magnetventile gesteuert werden.

wenn ich die globalen variablen so definiere:

char* names[2] = {"Vent.1 ", "Vent.2 "};
int arrTrockenwert[2] = {400, 60};
int bewZeit[2] = {60000, 20000} ;
uint cpos;
int cnt = 0;

funktioniert das ganze.

Hier der komplette Sketch:

#include "Credentials.h"
#include <ESP32_MySQL.h>
#include <Streaming.h>
#include <LiquidCrystal_I2C.h>
#include <String.h>
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include <time.h>
#include <vector>

#include <WiFi.h>

long timezone = 1;
byte daysavetime = 1;

// Debug Level from 0 to 4
#define _ESP32_MYSQL_LOGLEVEL_ 1

#define USING_HOST_NAME false

#if USING_HOST_NAME
// Optional using hostname
char server[] = "servername";  // change to your server's hostname/URL
#else
IPAddress server(192, 168, 178, 28);
#endif

uint16_t server_port = 3306;

char default_database[] = "Bewaesserung";
char default_table[] = "Werte";

ESP32_MySQL_Connection conn((Client*)&client);

// Create an instance of the cursor passing in the connection
ESP32_MySQL_Query sql_query = ESP32_MySQL_Query(&conn);

String SELECT_column = "*";
String WHERE_column = "Name1";
String default_value = "Vent.1";

// String query = String("SELECT ") + SELECT_column + " FROM " + default_database + "." + default_table
//                   + " WHERE " + WHERE_column + " = '" + default_value + "';";
String query = "SELECT * FROM Werte;";

char pars[100];
static char buffer[100];

LiquidCrystal_I2C lcd(0x27, 16, 2);

uint idWerte;
uint MINBEWAESSERUNGSZEIT = 5000;

unsigned long currentMillis;
unsigned long prevMillis = 0;
unsigned long interval = 60000;

int Menue_Schalter = 3;
String Menue_Text1;
String Menue_Text2;

// #define USE_LittleFS                  // Einkommentieren um den LittleFS Tab zu verwenden

#ifdef USE_LittleFS
#define SPIFFS LittleFS
#include <LittleFS.h>
#else
#include <SPIFFS.h>
#endif

#define DEBUGGING  // Einkommentieren für die Serielle Ausgabe

#ifdef DEBUGGING
#define DEBUG_B(...) Serial.begin(__VA_ARGS__)
#define DEBUG_P(...) Serial.println(__VA_ARGS__)
#define DEBUG_F(...) Serial.printf(__VA_ARGS__)
#else
#define DEBUG_B(...)
#define DEBUG_P(...)
#define DEBUG_F(...)
#endif

char* names[2];         // = {"Vent.1 ", "Vent.2 "};
int arrTrockenwert[2];  // = {400, 60};
int bewZeit[2];         // = {60000, 20000} ;
uint cpos;
int cnt = 0;

//*********************************************************************
// Start Klasse Bewaesserung
//*********************************************************************
class Bewaesserung {
  byte ventilPin;
  byte sensorPin;
  char* Name;
  byte zeile;
  int trockenwert;
  int bewaesserungszeit;

public:
  Bewaesserung(byte ventilPin, byte sensorPin, char* Name, byte zeile, int trockenwert, int bewaesserungszeit)
    : ventilPin(ventilPin), sensorPin(sensorPin), Name(Name), zeile(zeile), trockenwert(trockenwert), bewaesserungszeit(bewaesserungszeit) 
  {
  }

  void init() {
    pinMode(ventilPin, OUTPUT);
    digitalWrite(ventilPin, HIGH);
    lcd.init();       // Display initialisieren
    lcd.backlight();  // Hintergrundbeleuchtung
    lcd.clear();
    //pinMode (Menue_Schalter, INPUT_PULLUP);
    Serial << "\nin public: >>> Name: " << Name << " trockenwert: " << trockenwert << " bewaesserungszeit: " << bewaesserungszeit << endl;
  }

  void bewaessern() {
    
    uint sensorWert = analogRead(sensorPin);  // Wert von Sensor wird gelesen

    Serial << "\nvor dem giesen " << "  Name: " << Name << "  \tSensor Wert : " << sensorWert << "  \tTrockenwert: " << trockenwert << " \tBewässerungszeit: " << bewaesserungszeit / 1000 << " sec." << endl;

    drucklcd(zeile, Name, sensorWert);

    if (sensorWert > trockenwert) {
      digitalWrite(ventilPin, LOW);  // Ventil öffnen
      Serial.print(Name);
      Serial.println("ist auf");
      druckMenue(11, zeile, "giest");
      if (digitalRead(Menue_Schalter) == HIGH) {
        Serial.println("Schalter gedrückt");
        Menue();
      }
      delay(bewaesserungszeit);
      digitalWrite(ventilPin, HIGH);
      Serial.print(Name);
      Serial.println("ist zu");

      sensorWert = analogRead(sensorPin);
      drucklcd(zeile, Name, sensorWert);
      // Serial << "\nnach dem giesen  " << "  Name: " << Name << "  \tSensor Wert : " << sensorWert << "  \tTrockenwert: " << trockenwert << " \tBewässerungszeit: " << bewaesserungszeit/1000 << " sec." << endl;
    } else {
      Serial.print(Name);
      Serial.println("muss nicht geöffnet werden!");
      if (digitalRead(Menue_Schalter) == HIGH) {
        Serial.println("Schalter gedrückt");
        Menue();
      }
    }
    delay(MINBEWAESSERUNGSZEIT);
  }

  void drucklcd(byte zeile, String Name, uint sensorWert) {
    // Zahlen des Sensors rechtsbündig ausgeben
    if (sensorWert < 10 && sensorWert > 0)
      cpos = Name.length() + 3;
    if (sensorWert > 9 && sensorWert < 100)
      cpos = Name.length() + 2;
    if (sensorWert > 99 && sensorWert < 1000)
      cpos = Name.length() + 1;
    if (sensorWert > 999)
      cpos = Name.length();

    lcd.setCursor(0, zeile);
    lcd.print("                ");  //kpl. Zeile löschen
    // Zeile neu beschreiben
    lcd.setCursor(0, zeile);
    lcd.print(Name);
    lcd.setCursor(cpos, zeile);
    lcd.print(sensorWert);

    lcd.setCursor(12, zeile);
    lcd.print(trockenwert);
  }

  void druckMenue(byte pos, byte zeile, String wert) {
    lcd.setCursor(pos, zeile);
    lcd.print(wert);
  }

  void Menue() {
    lcd.clear();

    for (int i = 1; i < 5; i++) {
      switch (i) {
        case 1:
          {
            Menue_Text1 = "BETRIEB    ";
            Menue_Text2 = "   ";
            druckMenue(0, 0, Menue_Text1);
            druckMenue(0, 1, Menue_Text2);
            delay(3000);
            break;
          }
        case 2:
          {
            Menue_Text1 = "Feuchtigkeit   ";
            Menue_Text2 = " % ";
            druckMenue(0, 0, Menue_Text1);
            druckMenue(0, 1, Menue_Text2);
            delay(3000);
            break;
          }
        case 3:
          {
            Menue_Text1 = "Mess-Wartezeit ";
            Menue_Text2 = "Sek";
            druckMenue(0, 0, Menue_Text1);
            druckMenue(0, 1, Menue_Text2);
            delay(3000);
            break;
          }
        case 4:
          {
            Menue_Text1 = "Zeit Pumpe-EIN ";
            Menue_Text2 = "Sek";
            druckMenue(0, 0, Menue_Text1);
            druckMenue(0, 1, Menue_Text2);
            delay(3000);
            break;
          }
        case 5:
          {
            Menue_Text1 = "Zeit Pumpe-AUS ";
            Menue_Text2 = "Sek";
            druckMenue(0, 0, Menue_Text1);
            druckMenue(0, 1, Menue_Text2);
            delay(3000);
            break;
          }
      }
      lcd.clear();
    }
  }
};
//*********************************************************************
// Ende Klasse Bewaesserung
//*********************************************************************

Bewaesserung bewaesserung[] = {  // ventilPin, sensorPin, Name, zeile, trockenwert, bewässerungszeit
  { 2, A7, names[0], 0, arrTrockenwert[0], bewZeit[0] },
  { 6, A6, names[1], 1, arrTrockenwert[1], bewZeit[1] },
};

void setup() {
  //  Serial.begin(115200);
  DEBUG_B(115200);
  while (!Serial && millis() < 5000);  // wait for serial port to connect

  Serial.println("\nStart...");

  Connect();

  strncpy(buffer, " ", 100);

  conMySQL();

  Serial.println(buffer);

  // if(!SD.begin()){
  //   Serial.println("Card Mount Failed");
  //   // return;
  // }
  // uint8_t cardType = SD.cardType();

  // if(cardType == CARD_NONE){
  //   Serial.println("No SD card attached");
  //   // return;
  // }

  configTime(3600 * timezone, daysavetime * 3600, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
  struct tm tmstruct;
  delay(2000);
  tmstruct.tm_year = 0;
  getLocalTime(&tmstruct, 5000);
  Serial.printf("\nNow is : %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1, tmstruct.tm_mday, tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec);
  Serial.println("");

  // writeFile(SD, "/Werte.txt", buffer);

  idWerte = atoi(strtok(buffer, ","));
  MINBEWAESSERUNGSZEIT = atoi(strtok(NULL, ","));
  interval = atol(strtok(NULL, ","));
  arrTrockenwert[0] = atoi(strtok(NULL, ","));
  arrTrockenwert[1] = atoi(strtok(NULL, ","));
  bewZeit[0] = atoi(strtok(NULL, ","));
  bewZeit[1] = atoi(strtok(NULL, ","));
  names[0] = (strtok(NULL, ","));
  names[1] = (strtok(NULL, ","));

  Serial << "\narrTrockenwert[0]: " << arrTrockenwert[0] << "\tarrTrockenwert[1]: " << arrTrockenwert[1] << "\tbewZeit[0]: " 
    << bewZeit[0] << "\tbewZeit[1]: " << bewZeit[1] << "\tnames[0]: " << names[0] << "\tnames[1]: " << names[1] << endl;
  for (auto& b : bewaesserung) b.init();
}

void loop() {
  currentMillis = millis();

  if (currentMillis - prevMillis >= interval) {
    prevMillis = currentMillis;
    for (auto& b : bewaesserung) b.bewaessern();
  } else {
    uint sensorWert = analogRead(A7);  // Wert von Sensor wird gelesen
    delay(1000);
    sensorWert = analogRead(A6);
    delay(1000);
    Serial.print(".");
  }
}

Ich weiss, dass das ein bisschen viel ist aber ich hoffe irgend jemand sieht den Fehler auf Anhieb und kann mir helfen. Dafür wäre ich sehr dankbar.

Um das weiter zu verarbeiten ist das doch schon mal nicht so falsch. Nur würde ich die int in ein int-Array kopieren, z.B. intDaten(x) und die Strings in strDaten(x).
Danach kannst du doch in deinem Sketch sehr einfach drauf zugreifen.

Edit:
Und von for-Schleifen rate (wenn möglich) ich ab, da die den Sketch sehr gerne bremsen. Ein weiteres Problem ist evtl. deine Ansteuerung des Displays. Wenn du das mit 5 Volt betreibst, wird es kritisch an den I2C-Pins. Die vertragen nur 3,3V und können daher Schaden nehmen.
Ein I2C-Levelshifter ist da von nöten.

#include "Credentials.h"

was hast du alles in diesem File definiert sodass dein Sketch kompiliert?

Das wifi und den Datenbank Connect hab ich in zusätzlichen Dateien definiert.

Kannst du mir das mit int array und intDaten(x) etwas näher erklären. Das mit dem for hab ich hier im forum gefunden. Wie würdest du das lösen? Mit dem Display gab es bisher keine Probleme dies ist letzten Sommer rund um die Uhr gelaufen.

ach hdosw ... sollen wir das nun alles erraten? ändere die Passwörter und lade die Datei hoch!

Wozu? WLAN und MYSQL Connect funktionieren. Mein Problem ist die Initialisierung der Parameter für die bewaesserung Funktion.