I2C Kommunikation gestört

Moin zusammen,

ich habe mir eine Bewässerungsanlage gebaut. Das ganze soll so Funktionieren: Zwei Feuchtigkeitssensoren pro Pflanze werden von einem Arduino Nano (Slave) verarbeitet und nach Anfrage von dem Master (auch ein Arduino Nano) Seriell als Datenpaket verpackt und verschickt. Die Anlage lief vorher ohne den Slave. Über ein I2c angeschlossenes Display kann man über den Master nun die Anlage beobachten und steuern.

Nun zum Problem: Das Display zeigt nur ein schwarzes Bild, wenn ich den neuen Mastercode rein lade. Auch der Nano reagiert kaum noch auf die Veränderung von den Eingängen. Lade ich nur den ersten Teil rein, fehlt nur die Variable " Display_Data" sonst sieht man alles auf dem Display.

Ich vermute mal die Kommunikation wird irgendwie gestört. Ich habe bereits "Software Seriell" und jetzt "AltSoftSerial" ausprobiert. Einen Defekt kann ich ausschließen, da der alte Code ohne Slave funktioniert. Ich bin aber leider jetzt mit meinem Latein am Ende. Kann mir jemand helfen?

Hier der Code vom Master:

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <AltSoftSerial.h>
#define OLED_RESET -1
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
// Diplaygroeße:
Adafruit_SSD1306 display(OLED_WIDTH, OLED_HEIGHT, &Wire, OLED_RESET);
// Serielle Schnittstelle definieren
  //SoftwareSerial mySerial(10, 11); // RX, TX
  AltSoftSerial mySerial; // RX = D8, TX = D9

int S1 = 7;
int S0 = 6;
int Hand = 11;
int Auto = 10;
int IRPin = A6;
int Led_Schaltschrank_R = 12;//Leuchte im Schaltschrank Rot
int P1 = 4;                  // Leuchte unten Rechts
int P2 = 5;                  // Leuchte unten Links
int M1 = 2;                  // Pumpe 1 (ohne Markierung) // Hier passt etwas nicht M1 = BGE 34 
int M2 = 3;                  // Pumpe 2 (mit Markierung)   // Hier passt etwas nicht M2 = BGE 12

//Variablen:
unsigned long alte_blink_Millis = 0;
unsigned long aktuelle_Millis = 0;
const long blink_Intervall = 1000;
int LED_Status = 0;
unsigned long WasserZeitMillis = 0;   // Laufzeit Automatik
unsigned long Start_Zeit = 0;       // Speichert die Startzeit für Auto Betrieb
unsigned long Zeit_Puffer = 0;    // Zwischenspeicher für die Zeit
int WasserZeitStunden = 0;  // Laufzeit Automatik in Stunden für das Display
unsigned long Pumpenpause_M1 = 0;
unsigned long Pumpenpause_M2 = 0;
unsigned long Pumpenlaufzeit_M1 = 0;
unsigned long Pumpenlaufzeit_M2 = 0;
unsigned long Anfragezeit = 0;  // Zeit zum Senden einer Anfrage
unsigned long Pakete = 0;   //Paketzähler
bool Slave_bereit = 0;  // Slave bereit?
String StrSLAVEber = "Slavebereit";
String STOEsens = "STOEsens"; // Slavesensorik gestört

int Pos_Flanke_M1 = false;  // Speicher Positive Flanke M1
int Pos_Flanke_M2 = false;  // Speicher Positive Flanke M2
bool Quittierung = false;   // Quittierung Störungen
bool Start = false;         // Automatik 
bool Stoerung = true;     // Störung
bool Handbetrieb = false; // Handbetrieb
bool HandM1 = false;  // Pumpe M1 in Hand steuern
bool HandM2 = false;  // Pumpe M2 in Hand steuern
int Pumpzaehler = 0;    // Anzahl der Pumpvorgänge zählen und abbilden
int Display_Case = 0;   // Hier wird ausgewählt, was in der Variable stehen soll
String Display_Data = " ";  // Speicher für das Display
bool Wasser_nio = false;  // Wasser auffüllen
int sollwert = 0;  // Sollwert Feuchte für die Pflanzenbewässerung 
int MessBGE12 = 0;  // Messwert BGE12
int MessBGE34 = 0;  // Messwert BGE34

void setup() {
//Eingänge:
  pinMode(S1, INPUT_PULLUP);
  pinMode(S0, INPUT_PULLUP);
  pinMode(Hand, INPUT_PULLUP);
  pinMode(Auto, INPUT_PULLUP);
//Ausgänge:
  pinMode(P1, OUTPUT);
  pinMode(P2, OUTPUT);
  pinMode(M1, OUTPUT);
  pinMode(M2, OUTPUT);
  digitalWrite(M1, LOW);
  digitalWrite(M2, LOW);
  digitalWrite(P1, LOW);
  digitalWrite(P2, LOW);

// Pumpenpause für die Pumpen für den ersten Durchlauf auf 5 Minuten setzen
  Pumpenpause_M1 = 180000;
  Pumpenpause_M2 = 180000;

  sollwert = 450;

  Serial.begin(9600); // Schnittstelle USB
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  mySerial.begin(9600); // Schnittstelle zum Nano

  mySerial.println("Masterbereit"); // Nano aufwecken

}

void loop() {
aktuelle_Millis = millis();
// Funktion aufrufen
langsamer_Blinker ();
// Sensorikstörung

// Quittierungen bei Störungen
  if ((digitalRead(Hand) == true) && (digitalRead(Auto) == true) && (digitalRead(S1) == false) && (digitalRead(S0) == true)) {
    // Quittierung aktivieren
    Quittierung = true;
    } 
  else {
    // Quittierung nicht aktiv
    Quittierung = false;
  }

  // Störung zurücksetzen, wenn Quittierung aktiv ist
  if ((Stoerung == true) && (Start == false) && (Quittierung == true)) {
    
    Stoerung = false; // Störung zurücksetzen, wenn Quittierung aktiv ist
    }
  
  // Quittierung des Pumpzählers (Reset des Pumpzählers)
  if ((Start == false) && (digitalRead(Auto) == false) && (digitalRead(S1) == false) && (digitalRead(S0) == true)) {
    
    Pumpzaehler = 0;        // Pumpzähler zurücksetzen
    }
  
//    Kommunikation: Überprüfen, ob Slave bereit ist
  if (mySerial.available() && (Slave_bereit == false)) {
    String Slave = mySerial.readStringUntil('\n');
    Slave.trim(); // Leerzeichen und \r entfernen

    Serial.println("Slave: " + String(Slave));  // Slave ist ready

    if (StrSLAVEber.equals(Slave))  {
      Slave_bereit = true;
    }
  }
//   Kommunikation: Paket empfangen
  if (Slave_bereit == true) {

        // Anfrage an den Slave senden
        // Zeit für eine Anfrage, aktuell 500ms
    if ((millis() - Anfragezeit) >= 500)  {
      Anfragezeit = millis();

      // Anfrage schicken
      mySerial.println("REQ");
    
      delay(10); // Warte auf Antwort

      // Antwort vom Nano verarbeiten
      if (mySerial.available()) {
        String antwort = mySerial.readStringUntil('\n');
        antwort.trim(); // Leerzeichen und \r entfernen

        // Beispielformat: "AA|355|355|370"
        int sep1 = antwort.indexOf('|');
        int sep2 = antwort.indexOf('|', sep1 + 1);
        int sep3 = antwort.indexOf('|', sep2 + 1);

      // Wenn der erste "|" nicht vorne steht und ein weiterer "|" daneben
      if (sep1 > 0 && sep2 > sep1 && sep3 > sep2 && (!StrSLAVEber.equals(antwort))) {
        // neue String bilden und mit substring in die einzelnen Bestandteile zerlegen substring(from, to)
        String startkennung = antwort.substring(0, sep1);
        String messwertStr_BGE12 = antwort.substring(sep1 + 1, sep2);
        String messwertStr_BGE34 = antwort.substring(sep2 + 1, sep3);
        String pruefsummeStr = antwort.substring(sep3 + 1);

        // Messwert in Int wandeln
        MessBGE12 = messwertStr_BGE12.toInt();
        MessBGE34 = messwertStr_BGE34.toInt();
        // Prüfsumme in Int wandeln.: strtol: string to long (const char), ...Str.c_str() wandelt String in C String (const char), 16 steht für HEX  
        int pruefsumme = strtol(pruefsummeStr.c_str(), NULL, 16); // HEX nach int
        Pakete = Pakete + 1;  // Pakte zählen

      // Prüfsumme überprüfen
      if ((MessBGE12 + MessBGE34 + 170) != pruefsumme) {
        
        Serial.println("Ungültige Prüfsumme");
        mySerial.println("STOEno");   // flasche Prüfsumme
      }

      // Ausgabe zur Kontrolle
        Serial.println("Empfangenes Paket:");
        Serial.println("Kennung: " + startkennung);
        Serial.println("Messwert 12: " + String(MessBGE12));
        Serial.println("Messwert 34: " + String(MessBGE34));
        Serial.println("Prüfsumme (HEX): " + pruefsummeStr);
        Serial.print("Prüfsumme (dezimal): ");
        Serial.println(pruefsumme);
        Serial.println(Pakete);
      } 
    }
    }
  } else {
    mySerial.println("STOEno");
    Slave_bereit = false; 
    delay(50);
  }

  //Handbetrieb auswählen
  if ((!digitalRead(Hand) == true) && (digitalRead(Auto) == true) && (Stoerung == false) && (Wasser_nio == false)) {
    
    Handbetrieb = true;
    Display_Case = 3; // Hand angewählt
    }

  // Handbetrieb ausschalten
  if ((digitalRead(Hand) == true) || (!digitalRead(Auto) == true) || (Stoerung == true)) {
    
    Handbetrieb = false;
        
    if ((Stoerung == false) && (Wasser_nio == false) && (Start == false)) {
        
        Display_Case = 1; // Display: Anlage Startbereit/Ready (Ohne Störung)
      }  
  }

  // Pumpe 1 in Hand steuern
  if ((Handbetrieb == true) && (!digitalRead(S1) == true) && (Start == false)) {
    
    HandM1 = true;
  } else {
    
    HandM1 = false;
  }

  // Pumpe 2 in Hand steuern
  if ((Handbetrieb == true) && (digitalRead(S0) == true) && (Start == false)) {
    
    HandM2 = true;
  } else {
    
    HandM2 = false;
  }

  // Startbedingung
  if ((!digitalRead(S1) == true) && (!digitalRead(Auto) == true) && (digitalRead(Hand) == true) && (Stoerung == false) && (Wasser_nio == false)) {
    
    Start = true; // Starten, wenn keine Störung und Schalter betätigt
    Display_Case = 2; // Display: Anlage gestartet
    // Wasserzeitlaufzeit in Z. 231 geschrieben
    }

  // Stoppbedingung
  if ((digitalRead(S0) == true) || (digitalRead(Auto) == true) || (!digitalRead(Hand) == true) || (Stoerung == true) || (Wasser_nio == true)) {
    
    Start = false; // Stoppen bei Fehler oder weiteren Bedingungen
      
      if ((Stoerung == false) && (Wasser_nio == false) && (Handbetrieb == false)) {
        
        Display_Case = 1; // Display: Anlage Startbereit/Ready (Ohne Störung)
      }  
    }
  
  // Aktoren bei Störung
  if (Stoerung == true) {
    
    digitalWrite(Led_Schaltschrank_R, LED_Status);
    Display_Case = 0; // Display: Anlage in Störung
  }
  else {
    
    digitalWrite(Led_Schaltschrank_R, LOW);
  }

  
  // Schaltschrankbeleuchtung steuern
  if ((analogRead(IRPin) < 300) || ((analogRead(IRPin) >= 340) && (analogRead(IRPin) < 360)))  {
    
    digitalWrite(Led_Schaltschrank_R, HIGH); // Schaltschrankbeleuchtung Grün einschalten
  }
  else {
    
    digitalWrite(Led_Schaltschrank_R, LOW); // Schaltschrankbeleuchtung Grün ausschalten
  }

  // Zeit berechnen, wenn Automatik an ist
  if (Start == true) {
      // Start_Zeit setzen, wenn Automatik an ist
      if (Start_Zeit == 0) {

          Start_Zeit = millis();
      }
      
      WasserZeitMillis = millis() - Start_Zeit + Zeit_Puffer; // Laufzeit schreiben in Wasserzeit -> nach 7 Tagen wird Wasser_nio ausgelöst
  }
  // Zwischenzeitspeicher schreiben und WasserZeitMillis zurücksetzen
  if ((Start == false) && (WasserZeitMillis >= 1)) {

    Zeit_Puffer = WasserZeitMillis;     // Zwischenzeitpuffer schreiben
    WasserZeitMillis = 0;
    Start_Zeit = 0;                     // Startzeit Automatik zurücksetzen
  }

 // Wasserzeit in Stunden umrechnen (Betriebsstunden berechnen)
    WasserZeitStunden = WasserZeitMillis / 3600000;

  // Bitte wasser nachfüllen Variable Wassernio setzen: Wenn Pumpzähler 6 erreicht oder eine Woche Automatik lief
  if ((Pumpzaehler >= 6) || (WasserZeitMillis >= 604800000)) {
        
      Wasser_nio = true;
  }      
  
  // Wasser_nio zurücksetzen
  if (Wasser_nio == true) {
    
    // Der Pumpzähler muss erst noch zurückgesetzt werden!
    if ((Quittierung == true) && (Pumpzaehler == 0))  {
      
      Wasser_nio = false;
      WasserZeitMillis = 0;   // Wasserzeit zurücksetzen
      WasserZeitStunden = 0;  // Wasserzeit Stunden zurücksetzen
      Zeit_Puffer = 0;        // Zwischenzeitspeicher zurücksetzen
      Start_Zeit = 0;         // Startzeit Automatik zurücksetzen
    }
  }
  
  // Sollwert einstellen, wenn Störung, Wasser_nio, Automatik und Handbetrieb aus sind
  if ((Stoerung == false) && (Wasser_nio == false) && (Handbetrieb == false) && (Start == false)) {
    
    // Sollwert Einstellen: Erhöhen
    if ((digitalRead(Hand) == true) && (digitalRead(Auto) == true) && (digitalRead(S1) == false) && (digitalRead(S0) == false)) {

      sollwert = sollwert + 25;
    }

    // Sollwert Einstellen: Senken
    if ((digitalRead(Hand) == true) && (digitalRead(Auto) == true) && (digitalRead(S1) == true) && (digitalRead(S0) == true)) {

      sollwert = sollwert - 25;
    }
  }
  
  // Ausgang: der LED bei Wassernio blinken lassen
  if (Wasser_nio == true) {
    
     Display_Case = 4; // Wasser_nio anzeigen
  }
  
  // Ausgang: P1 einschalten
  if ((Start == true) || (HandM2 == true)) {
    
    digitalWrite(P1, HIGH); // Led Einschalten
  }
  
  // Ausgang: P1 ausschalten
  if ((Start == false) && (HandM2 == false)) {
    
    digitalWrite(P1, LOW);
  }  
  
  //Ausgang: P2 einschalten
  if (HandM1 == true) {

    digitalWrite(P2, HIGH);
  }

  // Ausgang: P2 ausschalten
  if (HandM1 == false) {

    digitalWrite(P2, LOW);
  }

  // Ausgang: Pumpe M1 einschalten
  if ((HandM1 == true) || ((MessBGE34 > sollwert) && (Start == true) && (millis() - Pumpenpause_M1 >= 180000) && (digitalRead(M1) == LOW)))  {
    
    digitalWrite(M1, HIGH);
    Pumpenlaufzeit_M1 = millis();
      // Positve Flanke erkennen und Zähler erhöhen, Flankenimpuls speichern
      if ((Pos_Flanke_M1 == false) && (HandM1 == false)) {
        
        Pumpzaehler++;
        Pos_Flanke_M1 = true;
      }
  }

  // Ausgang: Pumpe M1 ausschalten
  if ((MessBGE34 < (sollwert - 1)) && (Start == false) && (HandM1 == false) ||  (digitalRead(M1) == HIGH) && (millis() - Pumpenlaufzeit_M1 >= 3500) && (HandM1 == false) || (Stoerung == true) || (Wasser_nio == true))  {
                        // Pumpenlaufzeit für kleine Pflanze angepasst
    digitalWrite(M1, LOW);
    Pumpenlaufzeit_M1 = 0;
    Pumpenpause_M1 = millis();
  }

  // Flanke M1 zurücksetzen wenn die Pumpe ausgeschaltet wird
  if ((digitalRead(M1) == false) && (Pos_Flanke_M1 == true))  {

    Pos_Flanke_M1 = false;
  }

  // Ausgang: Pumpe M2 einschalten
  if ((HandM2 == true) || ((MessBGE12 > sollwert) && (Start == true) && (millis() - Pumpenpause_M2 >= 180000) && (digitalRead(M2) == LOW)))  {
                      
    digitalWrite(M2, HIGH);
    Pumpenlaufzeit_M2 = millis();
      // Positve Flanke M2 erkennen und Zähler erhöhen, Flankenimpuls speichern
      if ((Pos_Flanke_M2 == false) && (HandM2 == false)) {
        
        Pumpzaehler++;
        Pos_Flanke_M2 = true;
      }
  }

  // Ausgang: Pumpe M2 ausschalten
  if ((MessBGE12 < (sollwert - 1)) && (Start == false) && (HandM2 == false) ||  (digitalRead(M2) == HIGH) && (millis() - Pumpenlaufzeit_M2 >= 6000) && (HandM2 == false) || (Stoerung == true) || (Wasser_nio == true))  {
                        // Pumpenlaufzeit für die greoße Pflanze angepasst
    digitalWrite(M2, LOW);
    Pumpenlaufzeit_M2 = 0;
    Pumpenpause_M2 = millis();
  }
  
  // Flanke M2 zurücksetzen wenn die Pumpe ausgeschaltet wird
  if ((digitalRead(M2) == false) && (Pos_Flanke_M2 == true))  {

    Pos_Flanke_M2 = false;
  }

  // Störungen vor Wasser_NIO anzeigen
  if ((Stoerung == true) && (Wasser_nio == true)) {

    // Zeige Störungen an
    Display_Case = 0; // Störung zuerst anzeigen
  }


  switch (Display_Case) {

    case 0:
      Display_Data = "Failure";
      break;
    case 1:
      Display_Data = "Ready";
      break;
    case 2:
      Display_Data = "Auto";
      break;
    case 3:
      Display_Data = "Hand";
      break;
    case 4:
      Display_Data = "WassrNIO";
      break;
  }

   display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(2);
  display.setCursor(1, 1);
  display.println(Display_Data);
  display.setTextSize(1);
  display.setCursor(98, 1);
  display.println("Soll:");
  display.setTextSize(1);
  display.setCursor(103, 15);
  display.println(sollwert);
  display.setTextSize(1);
  display.setCursor(1, 25);
  display.println("Pumpzaehler:");
  display.setTextSize(1);
  display.setCursor(75, 25);
  display.println(Pumpzaehler);
  // Betriebsstunden anzeigen, wenn Start aktiv ist
  if ((Start == true) || (Wasser_nio == true))  {
    
      display.setTextSize(1);
      display.setCursor(103, 25);
      display.println(WasserZeitStunden);
      display.setTextSize(1);
      display.setCursor(121, 25);
      display.println("h");
  }
  display.setTextSize(1);
  display.setCursor(1, 40);
  display.println("Avg. Value BGE 12:");
  display.setTextSize(1);
  display.setCursor(110, 40);
  display.println(MessBGE12);
  display.setTextSize(1);
  display.setCursor(1, 50);
  display.println("Avg. Value BGE 34:");
  display.setTextSize(1);
  display.setCursor(110, 50);
  display.println(MessBGE34);
  display.display();

}
void langsamer_Blinker() {
  if (aktuelle_Millis - alte_blink_Millis >= blink_Intervall) {
      alte_blink_Millis = aktuelle_Millis;
    if (LED_Status == LOW) {
      LED_Status = HIGH;
    }else {
      LED_Status = LOW;
    }
  }
}

Hier noch der Code vom Slave:

#include <SoftwareSerial.h>

// Verwende 10 (RX), 11 (TX) für SoftwareSerial auf dem Nano
SoftwareSerial mySerial(11, 10); // RX, TX
                        //0,1
int BGE1 =  A2;             // Sensor 1 (mit Markierung)
int BGE2 =  A3;             // Sensor 2 (mit Markierung)
int BGE3 =  A1;             // Sensor 3 (ohne Markierung) 
int BGE4 =  A0;             // Sensor 4 (ohne Markierung)
int Summe_1 = 0;    // Summe von BGE 12
int Ergebnis_1 = 0; // Ergebnis von Summe 1
int Summe_2 = 0;    // Summe von BGE 34
int Ergebnis_2 = 0; // Ergebnis von Summe 2
int STOE = 0;
int P_STOE = 3;   // Störung LED
int P_Paket = 4;  // Grüne LED für Betrieb-Pakete
int P_Eingriff = 5; // Blaue LED für Eingriff

int Messwert_BGE12 = 0;
int Messwert_BGE34 = 0;
byte AA = 0xAA;
int Pruf = 0;
String Anfrage = "REQ";
String STOESLV = "STOEno";
String Quit = "QUIT";
String MASRR = "Masterbereit";

unsigned long aktuelle_Millis = 0;
unsigned long alte_blink_Millis = 0;
bool LED_Status = 0;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);         // Für Diagnose im Monitor
  mySerial.begin(9600);       // SoftwareSerial-Verbindung
  Serial.println("Slavebereit");
  mySerial.println("Slavebereit");
  
  
  pinMode(P_STOE, OUTPUT);
  digitalWrite(P_STOE, LOW);
  pinMode(P_Paket, OUTPUT);
  digitalWrite(P_Paket, LOW);
  pinMode(P_Eingriff, OUTPUT);
  digitalWrite(P_Eingriff, LOW);
}

void loop() {

  aktuelle_Millis = millis();

  // Sensorikstörung
  if ((analogRead(BGE1) < 75) || (analogRead(BGE2) < 75) || (analogRead(BGE3) < 75) || (analogRead(BGE4) < 75)) {
    // Variable Störung setzen
    STOE = 1;   // Sensorik Störung
  }
  
  
  // Pflanzensensoren auswerten und Mittelwert bilden, je feuchter die Erde desto, niedriger ist der Messwert.
  for (int i = 0; i < 3; i++)  {
    
    Summe_1 += analogRead(BGE1);
    Summe_1 += analogRead(BGE2);
  // Beide Sensordaten addieren mit += (Hinzufügen und speichern)  
  // kurz warten 
    delay(3);
    
  } 
  // Ergebnis bilden und Wert zurücksetzen
  Ergebnis_1 = Summe_1 / 6;
  Summe_1 = 0;

  // Pflanzensensoren BGE 3 und 4 auswerten und Mittelwert bilden, je feuchter die Erde desto, niedriger ist der Messwert.
  for (int i = 0; i < 3; i++)  {
    
    Summe_2 += analogRead(BGE3);
    Summe_2 += analogRead(BGE4);
  // Beide Sensordaten addieren mit += (Hinzufügen und speichern)  
  // kurz warten 
    delay(3);
    
  } 
  // Ergebnis bilden und Wert zurücksetzen
  Ergebnis_2 = Summe_2 / 6;
  Summe_2 = 0;
 
 if (mySerial.available()) {
    String command = mySerial.readStringUntil('\n');
    command.trim();

      // Bei "STOEno" oder "Masterbereit" Verbindungsabbruch, wieder neu anmelden
      
      if (STOESLV.equals(command) || MASRR.equals(command))  { 

        for (int i = 0; i < 2; i++) {
        
          mySerial.print("Slavebereit");
          Serial.println("Slavebereit");  // debugg
        
        delay(30);
        
          if (mySerial.available()) {
            String cmd = mySerial.readStringUntil('\n');
            cmd.trim();
              if (Anfrage.equals(cmd)) {
                
              break;
              }
          }
        }
      }

      // Paket schicken
      if (Anfrage.equals(command) && (STOE == 0))  {

        digitalWrite(P_Paket, LOW);
        Messwert_BGE12 = Ergebnis_1;
        Messwert_BGE34 = Ergebnis_2;
        
        delay (3);
        Pruf = Messwert_BGE12 + Messwert_BGE34 + 170;  // AA (Hex) sind 170 (dez)

        // Prüfsumme in Hex umwandeln:
        String PrufHex = String(Pruf, HEX);   // String(..) ist ein String erzeuger (Konstruktor)
        PrufHex.toUpperCase(); // in Großbuchstaben verwandeln

        // Paket erzeugen:
        String antwort = "AA|" + String(Messwert_BGE12) + "|" + String(Messwert_BGE34) + "|" + PrufHex + "\n";



      mySerial.print(antwort);    // Sende an Master
      //Serial.print("Sende: ");
      Serial.print(antwort);      // Debug am Monitor
      digitalWrite(P_Paket, HIGH);
      }
      
      // Störung Sensorik übermitteln
      if (STOE == 1)  {
        
        for (int j = 0; j < 5; j++) {
        
          mySerial.print("STOEsens");
        
          if (Quit.equals(command))  { // nicht mehr antworten, wenn ein "QUIT" kommt
            
            STOE = 0; // Störung zurücksetzen
            break;
          }
        }
      }
      // Störungsled Blinken lassen
      if (STOE == 1)  {
        
        digitalWrite(P_STOE, LED_Status);
        digitalWrite(P_Eingriff, LED_Status);
      }
  }

}

Das hat beides nichts mit dem I2C Bus zu tun.
Wie lang ist dein Kabel des I2C-Bus ?
Und poste mal ein Schaltbild deines Aufbaus.

Ich sehe, das Du den Seriellen Monitor eingerichtet hast, aber nur für eine Ausgabe nutzt.

Benutze den SerMon zum debuggen! Es ist die beste Möglichkeit, Fehlern auf die Spur zu kommen.

Du hast einen Blinker mitlaufen, wenn Du den auf LED_BUILTIN mitlaufen lässt, dann kannst Du auf dem Board die LED blinken sehen, ob das so passt.
Alternativ auch hier: AUf dem Seriellen Monitor einen kurzen Text ausgeben.

Dann sehe ich mehrere WarnungeN während des compilieren. Deine Klammerkonstrukte mit && und || in den Beidngungen machen Probleme.

Auch sehe ich viele Variablen die ggfls. durch Funktionen ersetzt werden können. Müsste man sehen, was da vereinfacht werden kann, nicht dass Du Dir da zwischendurch was überschreibst...

Wenn der Code da oben sonst funktioniert, was musst Du auskommentieren, damit Dein Display wieder etwas anzeigt?

das ist für mich nicht nachvollziehbar. Was ist "der erste Teil" was ist dann der "zweite Teil?

Wenn ich dich richtig verstehe hast du zwischen Master und Slave eine Serielle Kommunikation.
Wenn dem so ist, rate ich dir dringend dieses Tutorial durchzugehen:

darin ist erklärt, wie man eine verlässliche Kommunikation aufbaut.
Wenn irgendwie möglich würde ich an deiner Stelle sowohl auf Master wie auch auf Slave Seite die gleiche SoftSerial verwenden - und nicht mischen.

P.S.: wenn du dein Programm in Funktionen aufteilst, ist es nicht nur für Helfer leichter nachvollziehbar sondern auch du kannst es besser debuggen, da du dann einzelne Softwarekomponenten temporär deaktivieren kannst und so leichter deinen Fehler findest.

die 4,7k für SDA SCL sind aber schon verbaut der i2c benötigt dringend einen PULLUP
und die 100nF am Bauteil ds i2c nicht vergessen sonst ist echt fehlerbehaftet

Hatte schon das gleiche problem und habe auch noch 1uF VCC-GND am bauteil 2meter distanz verbaut das hat dann auch wieder sicherheit gebracht.

Wen die sind verbaut wo zu noch welsche?
Dazu wissen wir nicht wie lang ist die Leitung.

Hallo

hier wird dir geholfen:

Das Kabel ist nicht lang, ich verwende zwei geschirmte LiYCY Einzeladern mit 0,5mm². Möchtest du ein Bild oder den Schaltplan?

Vielleicht unterscheidet sich dein lang von meinem lang.

Benutze den SerMon zum debuggen! Es ist die beste Möglichkeit, Fehlern auf die Spur zu kommen.

Du hast einen Blinker mitlaufen, wenn Du den auf LED_BUILTIN mitlaufen lässt, dann kannst Du auf dem Board die LED blinken sehen, ob das so passt.
Alternativ auch hier: AUf dem Seriellen Monitor einen kurzen Text ausgeben.

Werde ich mal testen. Danke

Wen mehr als 0,5m dann ist schon außer Norme

Das kann sein. Bei mir passt alles. Mir ist nur aufgefallen, dass ich die Blinkfunktion beim Slave beim Kopieren des Codes vergessen habe.

Ein Schaltbild, weil das auch dir hilft bei der Fehlersuche.

Das sagt nichts über die tatsächliche Länge aus.

Ja genau. Wenn ich den ganzen Serielle Schnittstellencode rauskommentiere und nur noch

Serial.begin(9600); // Schnittstelle USB
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  mySerial.begin(9600); // Schnittstelle zum Nano

  mySerial.println("Masterbereit"); // Nano aufwecken

den Teil stehen lasse, kann man auf dem Display Schrift erkennen, aber die Variable "Display_Data" fehlt

Ja sry. ich meine den code als ersten Teil:

Serial.begin(9600); // Schnittstelle USB
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  mySerial.begin(9600); // Schnittstelle zum Nano

  mySerial.println("Masterbereit"); // Nano aufwecken

leider kommt es schon bei dem kleinen Code zu störungen, wie oben beschrieben

Danke ich werde mir das Tutorial mal anschauen

Danke für den Tipp. Aber das Display hat auch schon ohne die Serielle Schnittstelle super Funktioniert. Die Leitung ist auch nicht so lang.

Die Leitungen sind ca 30cm lang

30cm ist schon lang oder ? :slight_smile:

Das waren die einzigen geschirmten Einzelader Leitungen die ich auf die Schnelle gefunden habe. Daher habe ich die Verbaut