Softwareproblem bei Benützung von I2C

Guten Tag. Ich habe ein Softwareproblem beim benützen des I2C Bus. Problembeschreibung:
Ich habe 2 Arduinos Mega2560 per I2C verbunden. Einer wurde als Master und der andere als Slave mit der Nummer 22 definiert. Der Master sendet einen String zum Slave. Mein Problem besteht im Slave.
Hier der receiveEvent:

//------------------------------------------------------------------------------
void receiveEvent(int anzahl)
{
i=0;
while(Wire.available()) // alle Bytes holen
{
char c = Wire.read(); // Empfangenes Zeichen als char in der
// Variablen c ablegen
empfangeneDaten = c; // und im Array empfangeneDaten ablegen

  • i++; // Zaehler i = i + 1*
  • }*
    _ empfangeneDaten = '\0'; // String im Array mit '\0' abschließen_

* MasterDaten = String(empfangeneDaten); //Array in Kommando ablegen*
* Serial.println(MasterDaten);*
* DatenVomMaster=true; // DatenVomMaster auf Daten empfangen setzen*
* Serial.println(MasterDaten);*
}
Bis hier funktioniert es auch. Mein Problem besteht darin, dass ich den empfangenen String, der sich in der Variablen MasterDaten befindet, in der LOOP benötige. Dafür wurde die Routine DatenVomMaster auf true gesetzt. Die IF-Bedingung in der LOOP funktioniert auch, aber ich bekomme keine Daten rüber. Die Variable MasterDaten ist auf einmal nur in der LOOP ohne Inhalt. Was mache ich falsch?
Hier den Quellcode der LOOP:
//------------------------------------------------------------------------------
void loop()
{
* if (DatenVomMaster) // Sind Daten vom Master vorhanden?*
* { // Wenn ja, das Folgende ausführen*
* //Kommando = MasterDaten;*
* //Serial.print("Daten vom Master: ");*
* //Serial.println(Kommando);*

* Serial.println("----------------------------------");*
* // jetzt zuerst alle Variablen löschen*
* datensatzG = "";*
* command = "";*
* rechtslinks = "";*
* gradzahl = "";*
* lowGeschw = "";*
* highGeschw = "";*
* testByte = "";*
* cmStrecke = "";*

* datensatzG = MasterDaten; // ??????? Hier sind die Daten nicht mehr vorhanden*
* Serial.print("Empfangene Daten vom Master: ");*
* Serial.println(datensatzG);*

* // Datensatz zerlegen*
* command = (datensatzG.substring(1, 4));*
* rechtslinks = (datensatzG.substring(4, 5));*
* gradzahl = (datensatzG.substring(5, 8));*
* lowGeschw = (datensatzG.substring(8, 11));*
* highGeschw = (datensatzG.substring(11, 14));*
* testByte = (datensatzG.substring(14, 15));*
* cmStrecke = gradzahl;*
* DatenVomMaster=false; // und DatenVomMaster zurücksetzen *
* Serial.print("command: ");*
* Serial.println(command);*
* Serial.print("rechtslinks: ");*
* Serial.println(rechtslinks);*
* Serial.print("gradzahl: ");*
* Serial.println(gradzahl);*
* Serial.print("lowGeschw: ");*
* Serial.println(lowGeschw);*
* Serial.print("highGeschw: ");*
* Serial.println(highGeschw);*
* Serial.print("testByte: ");*
* Serial.println(testByte);*
* Serial.print("cmStrecke: ");*
* Serial.println(cmStrecke);*
* Serial.println("----------------------------------"); *
}
Ich bin für jede Hilfe dankbar.
Mit freundlichen Grüßen
pds14 Peter
Arduino_I2C_Slave22.ino (5.39 KB)

Setze deinen Sketch bitte in Code-Tags, dann ist dieser auch für jeden richtig lesbar.
Das kannst du auch nachträglich machen.
Benutze dafür die Schaltfläche </> oben links im Editorfenster.

Das ist viel zu verworren mit der ganzen String Orgie. Da werden mehrmals Daten zwischen C Strings und String Objekten hin- und her-gewandelt. Das braucht man alles nicht

Das ist z.B. totaler Quatsch:

void requestEvent(void) {
  Hilf1variable.toCharArray(Endevariable, 24);
  SendenZumMaster = Endevariable;
  Wire.write(Endevariable);   // Antwort zum Master senden
  DatenZumMaster=true;         // DatenZumMaster auf Daten senden setzen
}

1.) toCharArray() braucht man nur wenn die Daten verändert werden müssen. Um zum Lesen an das interne Array eines String Objekts zu kommen gibt es c_str()
2.) Wire.write() kann denke ich mit String Objekten umgehen
3.) Welchen Sinn soll es haben erst einen String in ein char Array zu kopieren und dann wieder direkt danach ein String Objekt daraus zu machen?

Aber es fängt schon beim Einlesen an. Es wird in ein char Array eingelesen. Und dann in ein String Objekt gewandelt. Wahrscheinlich unter der falschen Annahme dass es dadurch einfacher wird. Dabei sind C Strings viel einfach zu splitten als String Objekte.
Wenn du Strings verwenden willst dann verwende sie auch von Anfang an.

Generell läuft receiveEvent() in einem Interrupt Kontext. Das heißt Serial.print() darf man darin nicht aufrufen

Das soll so funktionieren?

while(Wire.available())      // alle Bytes holen  
   {
       char c = Wire.read();    // Empfangenes Zeichen als char in der
                                // Variablen c ablegen
       empfangeneDaten = c;  // und im Array empfangeneDaten ablegen
       i++;                     // Zaehler i = i + 1
   }

Da steht in Wirklichkeit das dort:

empfangeneDaten[i] = c;

Aber da keine Code Tags verwendet wurden ist das nun kursiv

Womit wir wieder bei Post 1 wären.

HotSystems:
Setze deinen Sketch bitte in Code-Tags, dann ist dieser auch für jeden richtig lesbar.
Das kannst du auch nachträglich machen.
Benutze dafür die Schaltfläche </> oben links im Editorfenster.