Serielle Komunikation Arduiono (Slave) über I2c mit Raspberry(Master)

Hallo , ich bin dabei eine Luft-Kegelbahn (https://www.youtube.com/watch?v=8qlskI6hipI) nachzubauen. Als Master benutze ich einen Raspberry (der hat einen HDMI - Ausgang für einen Monitor) für die 13 Siebensegmentanzeigen benutze ich 12 Arduino Nano , die über I2C-Bus angesteuert werden. Das funktioniert auch. Nun will ich über einen weiteren Arduino die umgefallenen Kegel über Initiatoren( NO ) abfragen . Das Programm zum erkennen der umgefallenen Kegel steht bereits und über den seriellen Monitor kann ich das auch prüfen.Mein Problem ist nun die Anzahl der umgefallenen Kegel über I2C-Bus an den Raspberry zu übertragen. Ich habe schon den Gockel gefragt aber mit den Be``ispielen komme ich nicht klar. `


// *****************************************
// Tool Einstellungen für Arduino Nano von AZ Delivery
// Board = Arduino Nano
// Prozessor = Atmega 328P (old Bootloader)
// ##########################################
// RPI mit Aeduino verbinden
// RPI               Arduino
//  -------------------------
//  GPIO 0 (SDA) <--> Pin 4 (SDA) (Analog 4)
//  GPIO 1 (SCL) <--> Pin 5 (SCL) (Analog 5)
//  Masse        <--> Masse
// #############################################
// ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//  hier sieht man wie die "Kegelbahn" aufgebaut ist.
//  Link https://www.youtube.com/watch?v=8qlskI6hipI)
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Die Eingänge 2 bis 11 erzeugen bei Low eine 1 , die dann zu einer "kegel_summe" addiert werden.
// Da es nur 9 Kegel gibt und ich im Programm des Raspberry bei einer Zahl > 9 einen Pudel erkenne, erzeugt der Eingang 12 bei LOW-Signal eine 10.
// Wenn der Pudel_Kegel fällt werden alle anderen Kegel ignoriert und es gibt 0 Punkte für diesen Wurf.
//
#include <Wire.h>

#define Slave_ADDRESS 0x21

int kegel_summe;
int kegel_1;
int kegel_2;
int kegel_3;
int kegel_4;
int kegel_5;
int kegel_6;
int kegel_7;
int kegel_8;
int kegel_9;
int kegel_10;




void setup() {
  Wire.begin(Slave_ADDRESS);  // join I2C bus with address #21
  Wire.onReceive(receiveEvent);
  //Wire.onRequest(requestEvent);
  Serial.begin(9600);



  pinMode(2, INPUT);   // Kegel 1
  pinMode(3, INPUT);   // Kegel 2
  pinMode(4, INPUT);   // Kegel 3
  pinMode(5, INPUT);   // Kegel 4
  pinMode(6, INPUT);   // Kegel 5
  pinMode(7, INPUT);   // Kegel 6
  pinMode(8, INPUT);   // Kegel 7
  pinMode(9, INPUT);   // Kegel 8
  pinMode(10, INPUT);  // Kegel 9
  pinMode(11, INPUT);  // Erkennung Pudel
  pinMode(14, OUTPUT);
  pinMode(15, OUTPUT);
  pinMode(16, OUTPUT);
  pinMode(17, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {



  int Eingang_1 = digitalRead(2);
  int Eingang_2 = digitalRead(3);
  int Eingang_3 = digitalRead(4);
  int Eingang_4 = digitalRead(5);
  int Eingang_5 = digitalRead(6);
  int Eingang_6 = digitalRead(7);
  int Eingang_7 = digitalRead(8);
  int Eingang_8 = digitalRead(9);
  int Eingang_9 = digitalRead(10);
  int Eingang_10 = digitalRead(11);
  // Die 4 LED dienen nur dazu, die Summe zu überprüfen .
  // 1 = Wert 1 ,2 = Wert 2, 3 = Wert 1 + Wert 2, 4 = Wert 4 , 5 = Wert 1 + Wert 4 usw.
  int LED1 = 14;  // Wert 1
  int LED2 = 15;  // Wert 2
  int LED4 = 16;  // Wert 4
  int LED8 = 17;  // Wert 8
  kegel_summe = (kegel_1 + kegel_2 + kegel_3 + kegel_4 + kegel_5 + kegel_6 + kegel_7 + kegel_8 + kegel_9 + kegel_10);

  // ###### Logic Tabelle ##########################
  //
  // LED->|_1_|_2_|_4_|_8_|
  //   _1_|_X_|_-_|_-_|_-_| X bedeutet LED leuchtet (HIGH), - bedeutet LED dunkel (LOW)
  //   _2_|_-_|_X_|_-_|_-_|
  //   _3_|_X_|_X_|_-_|_-_|
  //   _4_|_-_|_-_|_X_|_-_|
  //   _5_|_X_|_-_|_X_|_-_|
  //   _6_|_-_|_X_|_X_|_-_|
  //   _7_|_X_|_X_|_X_|_-_|
  //   _8_|_-_|_-_|_-_|_X_|
  //   _9_|_X_|_-_|_-_|_X_|
  //   10_|_-_|_X_|_-_|_X_|

  //##################################################

  // Kontroll-LED ansteuern.
  if (kegel_summe == 1) {
    digitalWrite(LED1, HIGH);
  } else if (kegel_summe == 3) {
    digitalWrite(LED1, HIGH);
  } else if (kegel_summe == 5) {
    digitalWrite(LED1, HIGH);
  } else if (kegel_summe == 7) {
    digitalWrite(LED1, HIGH);
  } else if (kegel_summe == 9) {
    digitalWrite(LED1, HIGH);
  } else {
    digitalWrite(LED1, LOW);
  }
  if (kegel_summe == 2) {
    digitalWrite(LED2, HIGH);
  } else if (kegel_summe == 3) {
    digitalWrite(LED2, HIGH);
  } else if (kegel_summe == 6) {
    digitalWrite(LED2, HIGH);
  } else if (kegel_summe == 7) {
    digitalWrite(LED2, HIGH);
  } else if (kegel_summe == 10) {
    digitalWrite(LED2, HIGH);
  } else {
    digitalWrite(LED2, LOW);
  }
  if (kegel_summe == 4) {
    digitalWrite(LED4, HIGH);
  } else if (kegel_summe == 5) {
    digitalWrite(LED4, HIGH);
  } else if (kegel_summe == 6) {
    digitalWrite(LED4, HIGH);
  } else if (kegel_summe == 7) {
    digitalWrite(LED4, HIGH);
  } else {
    digitalWrite(LED4, LOW);
  }
  if (kegel_summe == 8) {
    digitalWrite(LED8, HIGH);
  } else if (kegel_summe == 9) {
    digitalWrite(LED8, HIGH);
  } else if (kegel_summe == 10) {
    digitalWrite(LED8, HIGH);
  } else {
    digitalWrite(LED8, LOW);
  }

  // an den Eingaengen 2 bis 11 sind Initiatoren angeschlossen ( Schaltcharateristik Typ "NO" oder auch "Öffner" dh. wenn der Schalter belegt ist, ist der Kontakt oder Stromkreis geöffnet)

  //  9V + ______
  //             |
  //             |
  //             |_
  //              \     Schalter geschloss wenn Kegel aufrecht stehen.D.H High-Signal wenn Kegel stehen.
  //               |
  //               |
  //              _|_
  //             |   |
  //             |   | 100 Ohm
  //             |___|
  //               |
  //              _|_
  //             |   |
  //             |   | 100 Ohm
  //             |___|
  //               |________________________Pin 2 bis 11 Arduino
  //              _|_
  //             |   |
  //             |   | 100 Ohm
  //             |___|
  //               |
  //  GND__________|__

  // Aus der vorstehenden Skizze ist zu ersehen warum ich das Signal nachfolgend invertieren muss

  if (Eingang_1 == 0) {
    kegel_1 = 1;
  } else if (Eingang_1 == 1) {
    kegel_1 = 0;
  }

  if (Eingang_2 == 0) {
    kegel_2 = 1;
  } else if (Eingang_2 == 1) {
    kegel_2 = 0;
  }

  if (Eingang_3 == 0) {
    kegel_3 = 1;
  } else if (Eingang_3 == 1) {
    kegel_3 = 0;
  }

  if (Eingang_4 == 0) {
    kegel_4 = 1;
  } else if (Eingang_4 == 1) {
    kegel_4 = 0;
  }

  if (Eingang_5 == 0) {
    kegel_5 = 1;
  } else if (Eingang_5 == 1) {
    kegel_5 = 0;
  }

  if (Eingang_6 == 0) {
    kegel_6 = 1;
  } else if (Eingang_6 == 1) {
    kegel_6 = 0;
  }

  if (Eingang_7 == 0) {
    kegel_7 = 1;
  } else if (Eingang_7 == 1) {
    kegel_7 = 0;
  }

  if (Eingang_8 == 0) {
    kegel_8 = 1;
  } else if (Eingang_8 == 1) {
    kegel_8 = 0;
  }

  if (Eingang_9 == 0) {
    kegel_9 = 1;
  } else if (Eingang_9 == 1) {
    kegel_9 = 0;
  }

  if (Eingang_10 == 0) {
    kegel_10 = 10;  // Wert fuer Pudel
  } else if (Eingang_10 == 1) {
    kegel_10 = 0;
  }

  // Aufbereiitung für Seriellen Monitor als Programierhilfe.Wird bei Inbetriebnahme auskommentiert.
  Serial.println("kegel_summe");
  Serial.println(kegel_summe);
  delay(10);
  Serial.println("kegel_1");
  Serial.println(Eingang_1);
  delay(10);
  Serial.println("kegel_2");
  Serial.println(Eingang_2);
  delay(10);
  Serial.println("kegel_3");
  Serial.println(Eingang_3);
  delay(10);
  Serial.println("kegel_4");
  Serial.println(Eingang_4);
  delay(10);
  Serial.println("kegel_5");
  Serial.println(Eingang_5);
  delay(10);
  Serial.println("kegel_6");
  Serial.println(Eingang_6);
  delay(10);
  Serial.println("kegel_7");
  Serial.println(Eingang_7);
  delay(10);
  Serial.println("kegel_8");
  Serial.println(Eingang_8);
  delay(10);
  Serial.println("kegel_9");
  Serial.println(Eingang_9);
  delay(10);
  Serial.println("kegel_10");
  Serial.println(Eingang_10);
  delay(10);
}


void receiveEvent() {
  Wire.write(kegel_summe);



  // print out the state of the button:

  //Serial.println(Eingang_2);
  //Serial.println(Eingang_3);
  //Serial.println(Eingang_4);
  //Serial.println(Eingang_5);
  //Serial.println(Eingang_6);
  //SSerial.println(Eingang_7);
  //Serial.println(Eingang_8);
  //Serial.println(Eingang_9);
  //Serial.println(Eingang_10);
  delay(1);  // delay in between reads for stability
}

`

Was ist Dein Problem? Willst Du nur die Anzahl übertragen oder auch welche Kegel gefallen sind?
Der Slave kann nicht von sich aus senden. Er muss vom Master aufgefordert werden.
Evtl. kann der Slave dem Master über eine gesonderte Leitung signalisieren, dass Daten bereit stehen. Diese sollte beim Abholen wieder ausgeschaltet werden.

Du könntest die 10 Kegel in den Bits eines uint16_t speichern und übertragen.

Gruß Tommy

Doch, bei I2C geht das (multi-master). Der Empfänger (RasPi) muß nur eine Slave-Adresse haben und darauf reagieren, dann kann ihm jeder Knoten auch ungefragt etwas schicken.

Hallo Tommy, ich will nur die Anzahl, also wenn 1 Kegel gefallen ist eine 1, oder wenn 7 Kegel gefallen sind eine 7 übertragen. Also die" kegel_summe". Der Raspberry ordnet sie dann den einzelnen Würfen zu, und überträgt sie dann zu den entsprechenden Anzeigen. Die Aufforderung zum Senden kann das auch ein High-Signal am Eingang D12 sein.
Z.B. Ausgang GPIO 23 vom Pi an Eingang D12 Ardunino ?
Wie sieht das Programmtechnisch beim Arduino aus ?

Gruß Detlev

Ja, Multimaster habe ich ausgeblendet, da das oft problematisch ist.

Gruß Tommy

Na genau so, wie bei den anderen Slaves. Wenn Du schon 12 am laufen hast, weist Du doch, wie es geht oder ist Dein Problem anders gelagert? Dann musst Du es beschreiben.

Gruß Tommy

Das muss ich mir noch einmal genauer anschauen. Also müsste ich lesen vom Bus gegen schreiben vom auf den Bus tauschen. Das muss ich mir morgen nochmal anschauen. Jetzt muss ich erstmal schlafen.
Danke erstmal.

Nein, beides implementieren. Der Slave Code reagiert auf die Callbacks (OnRequest/Receive), der Mater Code ruft begin/endTransmission und requestFrom auf.

dann lass den Raspberry doch auch den Zähl-Nano abfragen.
In dem Rhythmus wie der Raspberry die Daten verarbeiten kann.
Dann brauchst im Zähl-Nano-Sketch auch kein Delay.

Wobei man auch hinterfragen könnte, weswegen es so viele Microcontroller sein müssen.

Und du solltest dich zu Arrays belesen - dann hat dein Sketch vermutlich nicht mal mehr ein drittel der Zeilen.

Das Problem ist gelöst. :sweat_smile:
Ich habe mir nochmal das Programm der Anzeigen-Nano`s angesehen. Da fiel es mir wie Schuppen aus den Haaren.
Ja, ich weis dass man Sketche oder Programme verkürzen, und dadurch scheinbar vereinfachen kann. Ich lasse das Programm so wie es ist und wie es zur Zeit läuft. Ich glaube , das schadet den Arduinos auch nicht.Bis jetzt sind sie nicht sehr warm geworden. :wink:
Der Raspberry soll ja auch den Zähl-Nano abfragen, das macht er ja auch schon. Nur der Zähl-Nano sendete bis heute um 14:00 Uhr keine Daten.

Die Anzeigen-Nano`s haben mir viel Lötarbeit erspart.
Danke für Eure Hilfe

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