I2C Kommunikation plus I2C Display an beiden Arduinos

Hallo zusammen,

ich möchte zwischen zwei Arduinos (Mega) Daten austauschen bzw. soll ein Arduino (Receiver) regelmäßig Daten von einem zweiten (Sender) abfragen. Die beiden Arduinos sind jeweils SCL1-SCL1, SDA1-SDA1, GND-GND verbunden. Zusätzlich habe ich an jedem Arduino ein Display mit unterschiedlichen Adressen ( HD44780 2004 LCD Display) per I2C jeweils an die PIN's 20SDA, 21SCL, GND, 5V angeschlossen. Leider funktioniert weder die Abfrage der Daten, noch die Displayanzeige und die Arduinos hängen sich auf.

Sketch für Sender

// I2C_Sender.ino

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); // I2C Display auf Adresse 0x27 instanzieren

// I2C Communication:
const int Slave_Adr = 8; //Adresse des Slave Device für I2C Kommunikation
union DataSend_u
{
  struct
  {
    int value1;
    int value2;
    int value3;
    int value4;
    float value5;
    byte value6;
  };
  byte bytes[13];
};
DataSend_u DataSend;

void setup() {
  lcd.init(); //Im Setup wird der LCD gestartet 
  lcd.backlight(); //Hintergrundbeleuchtung einschalten
  lcd.setCursor(0, 0);lcd.print(F("Sender")); // Display Ausgabe Zeile 1 Überschrift

  Wire.begin(Slave_Adr);                // join i2c bus with address #Slave_Adr
  Wire.onRequest(requestEvent); // register event

  DataSend.value1 = 1;
  DataSend.value2 = 4;
  DataSend.value3 = 12;
  DataSend.value4 = 30000;
  DataSend.value5 = -12000.3252;
  DataSend.value6 = 1;
}

void loop() {
     delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {

  DataSend.value1 = random(0,30000);
  DataSend.value2 = random(0,30000);
  DataSend.value3 = random(0,30000);

  Wire.write(DataSend.bytes, sizeof(DataSend)); // respond with Data

  lcd.setCursor(0,0);lcd.print("Gesendet");
  lcd.setCursor(0,1);lcd.print(DataSend.value1);
  lcd.setCursor(0,2);lcd.print(DataSend.value2);
  lcd.setCursor(0,3);lcd.print(DataSend.value3);
    
}

Sketch für Empfänger

// I2C_Receiver.ino

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x26, 20, 4); // I2C Display auf Adresse 0x26 instanzieren

const int Slave_Adr = 8; //Adresse des Slave Device für I2C Kommunikation
union DataReceived_u
{
  struct
  {
    int value1;
    int value2;
    int value3;
    int value4;
    float value5;
    byte value6;
  };
  byte bytes[13];
};
DataReceived_u DataReceived;

void setup() {
  Serial.begin(9600);  // start serial for output
  lcd.init(); //Im Setup wird der LCD gestartet 
  lcd.backlight(); //Hintergrundbeleuchtung einschalten
  lcd.setCursor(0,0);lcd.print("Empfaenger");

  Wire.begin();        // join i2c bus (address optional for master)

}

void loop() {
  getData();

  lcd.setCursor(0,0);lcd.print("Empfangen");
  lcd.setCursor(0,1);lcd.print(DataReceived.value1);
  lcd.setCursor(0,2);lcd.print(DataReceived.value2);
  lcd.setCursor(0,3);lcd.print(DataReceived.value3);

  delay(1000);
}

void getData()
{
  Serial.println("Request I2C von Slave: ");

  Wire.requestFrom(Slave_Adr, sizeof(DataReceived));    // request from peripheral device #Slave_Adr
  for (unsigned int i = 0; i < sizeof(DataReceived); i++)
    DataReceived.bytes[i] = Wire.read();

  Serial.println(DataReceived.value1);
  Serial.println(DataReceived.value2);
  Serial.println(DataReceived.value3);
  Serial.println(DataReceived.value4);
  Serial.println(DataReceived.value5);
  Serial.println("Ende\n");
}

Wenn ich beide Sketches ohne die Ausgabe auf LCD-Display ausführe, funktioniert die Kommunikation. Ebenso funktioniert die Ausgabe auf die Displays ohne die I2C Kommunikation/Verbindung.

Hat jmd. ein Tip für mich, wie ich es so programmieren kann, dass sich die I2C Kommunikation und die I2C-Ausgabe auf den Display miteinander nicht Stören? Wahrscheinlich liegt der Fehler darin, dass es nur ein Master geben kann und bei der Ausgabe auf die Displays ist jeder der beiden Arduinos "Master".

Hier zur Referenz noch die beiden funktionierenden Sketches zur Kommunikation ohne Ausgabe auf die Displays.

Sketch für Sender

// I2C_Sender.ino

#include <Wire.h>

// I2C Communication:
const int Slave_Adr = 8; //Adresse des Slave Device für I2C Kommunikation
union DataSend_u
{
  struct
  {
    int value1;
    int value2;
    int value3;
    int value4;
    float value5;
    byte value6;
  };
  byte bytes[13];
};
DataSend_u DataSend;

void setup() {
  Wire.begin(Slave_Adr);                // join i2c bus with address #Slave_Adr
  Wire.onRequest(requestEvent); // register event

  DataSend.value1 = 1;
  DataSend.value2 = 4;
  DataSend.value3 = 12;
  DataSend.value4 = 30000;
  DataSend.value5 = -12000.3252;
  DataSend.value6 = 1;
}

void loop() {
     delay(100);
}

// function that executes whenever data is requested by master
void requestEvent() {

  DataSend.value1 = random(0,30000);
  DataSend.value2 = random(0,30000);
  DataSend.value3 = random(0,30000);

  Wire.write(DataSend.bytes, sizeof(DataSend)); // respond with Data
}

Sketch für Empfänger

// I2C_Receiver.ino

#include <Wire.h>

const int Slave_Adr = 8; //Adresse des Slave Device für I2C Kommunikation
union DataReceived_u
{
  struct
  {
    int value1;
    int value2;
    int value3;
    int value4;
    float value5;
    byte value6;
  };
  byte bytes[13];
};
DataReceived_u DataReceived;

void setup() {
  Serial.begin(9600);  // start serial for output
  Wire.begin();        // join i2c bus (address optional for master)
}

void loop() {
  getData();
  delay(1000);
}

void getData()
{
  Serial.println("Request I2C von Slave: ");

  Wire.requestFrom(Slave_Adr, sizeof(DataReceived));    // request from peripheral device #Slave_Adr
  for (unsigned int i = 0; i < sizeof(DataReceived); i++)
    DataReceived.bytes[i] = Wire.read();

  Serial.println(DataReceived.value1);
  Serial.println(DataReceived.value2);
  Serial.println(DataReceived.value3);
  Serial.println(DataReceived.value4);
  Serial.println(DataReceived.value5);
  Serial.println("Ende\n");
}

Danke für eure Hilfe!

Die beiden Megas und die beiden Displays hängen alle am selben Bus. Wenn die Displays gleiche Adressen haben, dann gibt das Ärger. Schau mal nach, ob/wie sich die Display-Adressen einstellen lassen.

Versuche mal die Programme mit nur 1 Display laufen zu lassen.

:warning:
Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden.
Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.
mfg ein Moderator.

Danke für deine Antwort, die beiden Displays haben unterschiedliche Adressen 0x26 und 0x27 per Lötbrücke eingestellt. Ohne die I2C-Kommunikation funktionieren beide Arduinos mit Ihren Displays auch ohne Probleme :man_shrugging:

Zur Kommunikation sollte einer der beiden Arduinos als Slave arbeiten, um jeweils ein Display anzusteuern muss er aber Master sein. Dieser Betrieb ist nicht trivial zu realisieren.
Einfacher wäre es, wenn der Master beide Displays ansteuert und mit dem Slave kommuniziert.

Gruß Tommy

imho klappt I2C Multimaster nicht mit zwei Arduino und der Wire.h lib.

Mach die Kommunikation zwischen den Arduinos mit etwas anderem. Entweder (soft-)Serial oder SPI.

Beide Arduinos haben die Slave Adresse 8!
Das ist der erste Bock!

Dann ist beim Multimaster Betrieb in einigen Situationen wichtig, dass man den Repeated Start verwendet.
Macht deine LCD Lib das richtig?

Problemlos!
Erst mit 3 Mastern, wird es "schwierig"

Das sieht nur so aus:

Stimmt...

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.