Hardware Serial TX/RX und I2C Konflikte?

Zuerst mal ein glückliches, erfolgreiches und gesundes neues Jahr!

Zu meinem Problem. Ich habe einen kleinen Roboter der über I2C Daten austauscht. Dies funktioniert alles problemlos. Sobald ich nun einen Motorcontroller über die hardware serielle TX/RX ansteuern möchte, dann friert mir alles ein, sprich der Sende Arduino Mega und dieser Empfangs Arduino Uno bleiben hängen und machen bis zu einem Neustart/Reset nichts mehr.
Ohne die serielle TX/RX Verbindung funktioniert es, sprich auch wenn diese angeschlossen ist, aber keine Befehle darüber gesendet werden funktioniert alles.
Es wird alles von einem Akku mit Strom versorgt. Die TX/RX und GND Leitungen gehen vom Uno an den Motorcontroller. Der Mega ist über SCL/SDA und GND mit dem Uno verbunden. Motorcontroller wäre ein Roboclaw 2x7A falls das benötigt wird.
Ich habe was gelesen, dass bei Interrupts solche Probleme auftreten können, wenn mehrere Libs solche verwenden. Weiss hier jemand mehr darüber oder findet hier das Problem wieso mir direkt alles einfriert sobald ich die Motoren über TX/RX ansteuere?

Hier ist der Problemcode des Empfänger Unos mit der TX/RX Nutzung:

 /**SETTINGS**/
const unsigned long Baudrate = 38400;    //starts serial port for Roboclaw with a baudrate by 38400 b/s

const byte ArduBody = 0x2A;              //I2C address for the Arduino UNO, body
const byte address = 0x80;               //address for Roboclaw from feet motors, address 128
const byte addressDD = 0x82;             //address for Roboclaw from dome motor, address 130

const byte SpeedBP = 30;                 //set the speed for body panels 1-5 (0=full speed, 1-255 slower to faster)
const byte SpeedUAL = 30;                //set the speed for arm left (0=full speed, 1-255 slower to faster)
const byte SpeedUAR = 30;                //set the speed for arm right (0=full speed, 1-255 slower to faster)

const byte SpeedDD = 80;                 //set the speed for dome drive (127=full speed, 0-127 slower to faster)
const byte SpeedFDLR = 100;              //set the maximum, normal speed for foot drive left/right (0=stop, 127=full speed, 0-127 slower to faster)
const byte SpeedFDUD = 100;              //set the maximum, normal speed for foot drive forward/backward (0=stop, 127=full speed, 0-127 slower to faster)

const byte SpeedFDLRfast = 120;          //set the maximum, fast speed for foot drive left/right (if joystick is pressed down) (0=stop, 127=full speed, 0-127 slower to faster)
const byte SpeedFDUDfast = 120;          //set the maximum, fast speed for foot drive forward/backward (if joystick is pressed down) (0=stop, 127=full speed, 0-127 slower to faster)

const unsigned long BPservoMin = 900;    //set minimum pulse length in microseconds for body panels
const unsigned long BPservoMax = 2100;   //set maximum pulse length in microseconds for body panels
const unsigned long UAservoMin = 900;    //set minimum pulse length in microseconds for arms
const unsigned long UAservoMax = 2100;   //set maximum pulse length in microseconds for arms

/*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/

 //Definition of pinnumbers
const byte BodyPanel1 = 7;   //Body panel 1 connected to pin D7
const byte BodyPanel2 = 8;   //Body panel 2 connected to pin D8
const byte BodyPanel3 = 9;   //Body panel 3 connected to pin D9
const byte BodyPanel4 = 10;  //Body panel 4 connected to pin D10
const byte BodyPanel5 = 11;  //Body panel 5 connected to pin D11

const byte ArmL = 5;  //arm left connected to pin D5
const byte ArmR = 6;  //arm right connected to pin D6

 //Definition of designations for reading signals (signals to be received)
byte BP1 = 0;    //Bodypanel 1
byte BP2 = 0;    //Bodypanel 2
byte BP3 = 0;    //Bodypanel 3
byte BP4 = 0;    //Bodypanel 4
byte BP5 = 0;    //Bodypanel 5

byte UAL = 0;    //arm left
byte UAR = 0;    //arm right

byte DD = 0;     //Dome drive
byte FDLR = 0;   //Foot drive left/right
byte FDUD = 0;   //Foot drive forward/backward
byte joybut = 0; //Foot drive joystick-button

byte BUT4 = 0;   //Button 4
byte BUT8 = 0;   //Button 8
byte BUT12 = 0;   //Button 12
byte BUT20 = 0;   //Button 20

 //Definition of designations for storing signals (cache)
byte data[5];                   //create array for packet serial (feet and dome motors)
uint16_t crc = 0;               //checksum crc
volatile byte dataReceived[2];  //byte array for received data over I2C
bool newData;                   //check for new data received

byte lastBP1 = 0;    //last status from body panel 1
byte lastBP2 = 0;    //last status from body panel 2
byte lastBP3 = 0;    //last status from body panel 3
byte lastBP4 = 0;    //last status from body panel 4
byte lastBP5 = 0;    //last status from body panel 5
byte lastUAL = 0;    //last status from arm left
byte lastUAR = 0;    //last status from arm right

byte lastDD = 0;     //last status from dome drive
byte lastFDLR = 0;   //last status from foot drive, left/right
byte lastFDUD = 0;   //last status from foot drive, forward/backward
byte mapFDLR = 0;    //converted value FDLR (foot drive left/right) for the dc motor
byte mapFDUD = 0;    //converted value FDUD (foot drive forward/backward)( for the dc motor
byte mapDD = 0;      //converted value DD (dome drive left/right) for the dc motor

#include <VarSpeedServo.h>    //adds library to control servos
#include <Wire.h>             //adds library for I2C

//create servo object (maximum 8)
VarSpeedServo servoBP1;   //create servo body panel 1
VarSpeedServo servoBP2;   //create servo body panel 2
VarSpeedServo servoBP3;   //create servo body panel 3
VarSpeedServo servoBP4;   //create servo body panel 4
VarSpeedServo servoBP5;   //create servo body panel 5

VarSpeedServo servoUAL;  //create servo arm left
VarSpeedServo servoUAR;  //create servo arm right


void setup() {
  Wire.begin(ArduBody);         //starts I2C bus as slave on address ArduBody
  Wire.onReceive(readCommand);  //function to trigger when something is received over I2C

  Serial.begin(Baudrate);       //starts serial port with a baudrate by "Baudrate" (b/s)

  //attach the servos
  servoBP1.attach(BodyPanel1,BPservoMin,BPservoMax);  //servoBP1 is attached to pin BodyPanel1 with pulse length BPservoMin and BPservoMax
  servoBP2.attach(BodyPanel2,BPservoMin,BPservoMax);  //servoBP2 is attached to pin BodyPanel2 with pulse length BPservoMin and BPservoMax
  servoBP3.attach(BodyPanel3,BPservoMin,BPservoMax);  //servoBP3 is attached to pin BodyPanel3 with pulse length BPservoMin and BPservoMax
  servoBP4.attach(BodyPanel4,BPservoMin,BPservoMax);  //servoBP4 is attached to pin BodyPanel4 with pulse length BPservoMin and BPservoMax
  servoBP5.attach(BodyPanel5,BPservoMin,BPservoMax);  //servoBP5 is attached to pin BodyPanel5 with pulse length BPservoMin and BPservoMax

  servoUAL.attach(ArmL,UAservoMin,UAservoMax); //servoUAL is attached to pin ArmL with pulse length UAservoMin and UAservoMax
  servoUAR.attach(ArmR,UAservoMin,UAservoMax); //servoUAR is attached to pin ArmR with pulse length UAservoMin and UAservoMax

  //initialization of the dome motor on startup
  motor(0,0, addressDD, Serial);  //command for forward, stop movement, address, serial port
  
  //initialization of the feet motors on startup
  motor(10,0, address, Serial);   //command for turn right in mix mode, stop movement, address, serial port
  motor(8,0, address, Serial);    //command for forward in mix mode, stop movement, address, serial port
  
}

void loop() {

  if(newData == true){                    //if new data received is true, then make...

//Utility arms
  if(UAL != lastUAL){                     //if UAL (arm left) not equal to lastUAL, then make...
    servoUAL.slowmove(UAL, SpeedUAL);     //servoUAL moves with angle UAL and speed SpeedUAL (0=full speed, 1-255 slower to faster)
    lastUAL = UAL;                        //stores UAL on lastUAL
  }

  if(UAR != lastUAR){                     //if UAR (arm right) not equal to lastUAR, then make...
    servoUAR.slowmove(UAR, SpeedUAR);     //servoUAR moves with angle UAR and speed SpeedUAR (0=full speed, 1-255 slower to faster)
    lastUAR = UAR;                        //stores UAR on lastUAR
  }
  


//Body panels:
  if(BP1 != lastBP1){                     //if BP1 (body panel 1) not equal to lastBP1, then make...
    servoBP1.slowmove(BP1, SpeedBP);      //servoBP1 moves with angle BP1 and speed SpeedBP (0=full speed, 1-255 slower to faster)
    lastBP1 = BP1;                        //stores BP1 on lastBP1
  }

  if(BP2 != lastBP2){                     //if BP2 (body panel 2) not equal to lastBP2, then make...
    servoBP2.slowmove(BP2, SpeedBP);      //servoBP2 moves with angle BP2 and speed SpeedBP (0=full speed, 1-255 slower to faster)
    lastBP2 = BP2;                        //stores BP2 on lastBP2
  }

  if(BP3 != lastBP3){                     //if BP3 (body panel 3) not equal to lastBP3, then make...
    servoBP3.slowmove(BP3, SpeedBP);      //servoBP3 moves with angle BP3 and speed SpeedBP (0=full speed, 1-255 slower to faster)
    lastBP3 = BP3;                        //stores BP3 on lastBP3
  }

  if(BP4 != lastBP4){                     //if BP4 (body panel 4) not equal to lastBP4, then make...
    servoBP4.slowmove(BP4, SpeedBP);      //servoBP4 moves with angle BP4 and speed SpeedBP (0=full speed, 1-255 slower to faster)
    lastBP4 = BP4;                        //stores BP4 on lastBP4
  }

  if(BP5 != lastBP5){                     //if BP5 (body panel 5) not equal to lastBP5, then make...
    servoBP5.slowmove(BP5, SpeedBP);      //servoBP5 moves with angle BP5 and speed SpeedBP (0=full speed, 1-255 slower to faster)
    lastBP5 = BP5;                        //stores BP5 on lastBP5
  }


//Dome drive
  if(DD != lastDD){                                       //if DD (dome drive) not equal to lastDD, then make...
    if(DD < 87){                                          //if DD is between 0 and 90, then make...
      mapDD = map(DD, 90, 0, 0, SpeedDD);                 //read value from DD, convert the input value from 0 to 90 in a dc motor value from 0 to SpeedDD and store it to mapDD
      motor(0,mapDD, addressDD, Serial);                  //command for forward, movement mapDD, address, serial port
    }
    else if(180 >= DD && DD > 93){                        //if DD is between 90 and 180, then make...
      mapDD = map(DD, 90, 180, 0, SpeedDD);               //read value from DD, convert the input value from 90 to 180 in a dc motor value from 0 to SpeedDD and store it to mapDD
      motor(1,mapDD, addressDD, Serial);                  //command for backward, movement mapDD, address, serial port
    }
    else if(87 <= DD && DD <= 93){                        //if DD is 90, then make...
      motor(0,0, addressDD, Serial);                      //command for forward, stop movement, address, serial port
    }
    lastDD = DD;                                          //stores DD on lastDD
  }


//Foot drive
  if(FDLR != lastFDLR && joybut == HIGH){                 //if FDLR (foot drive left/right) not equal to lastFDLR and joybut is equal to HIGH (not pressed), then make...
    if(FDLR < 87){                                        //if FDLR is between 0 and 90, then make...
      mapFDLR = map(FDLR, 90, 0, 0, SpeedFDLR);           //read value from FDLR, convert the input value from 0 to 90 in a dc motor value from 0 to SpeedFDLR and store it to mapFDLR
      motor(10,mapFDLR, address, Serial);                 //command for turn right in mix mode, movement mapFDLR, address, serial port
    }
    else if(180 >= FDLR && FDLR > 93){                    //if FDLR is between 90 and 180, then make...
      mapFDLR = map(FDLR, 90, 180, 0, SpeedFDLR);         //read value from FDLR, convert the input value from 90 to 180 in a dc motor value from 0 to SpeedFDLR and store it to mapFDLR
      motor(11,mapFDLR, address, Serial);                 //command for turn left in mix mode, movement mapFDLR, address, serial port
    }
    else if(87 <= FDLR && FDLR <= 93){                    //if FDLR is 90, then make...
      motor(10,0, address, Serial);                       //command for turn right in mix mode, stop movement, address, serial port
    }
    lastFDLR = FDLR;                                      //stores FDLR on lastFDLR
  }

  if(FDLR != lastFDLR && joybut == LOW){                  //if FDLR (foot drive left/right) not equal to lastFDLR and joybut is equal to LOW (pressed), then make...
    if(FDLR < 87){                                        //if FDLR is between 0 and 90, then make...
      mapFDLR = map(FDLR, 90, 0, 0, SpeedFDLRfast);       //read value from FDLR, convert the input value from 0 to 90 in a dc motor value from 0 to SpeedFDLRfast and store it to mapFDLR
      motor(10,mapFDLR, address, Serial);                 //command for turn right in mix mode, movement mapFDLR, address, serial port
    }
    else if(180 >= FDLR && FDLR > 93){                    //if FDLR is between 90 and 180, then make...
      mapFDLR = map(FDLR, 90, 180, 0, SpeedFDLRfast);     //read value from FDLR, convert the input value from 90 to 180 in a dc motor value from 0 to SpeedFDLRfast and store it to mapFDLR
      motor(11,mapFDLR, address, Serial);                 //command for turn left in mix mode, movement mapFDLR, address, serial port
    }
    else if(87 <= FDLR && FDLR <= 93){                    //if FDLR is 90, then make...
      motor(10,0, address, Serial);                       //command for turn right in mix mode, stop movement, address, serial port
    }
    lastFDLR = FDLR;                                      //stores FDLR on lastFDLR
  }

  if(FDUD != lastFDUD && joybut == HIGH){                 //if FDUD (foot drive forward/backward) not equal to lastFDUD and joybut is equal to HIGH (not pressed), then make...
    if(FDUD < 87){                                        //if FDUD is between 0 and 90, then make...
      mapFDUD = map(FDUD, 90, 0, 0, SpeedFDUD);           //read value from FDUD, convert the input value from 0 to 90 in a dc motor value from 0 to SpeedFDUD and store it to mapFDUD
      motor(8,mapFDUD, address, Serial);                  //command for forward in mix mode, movement mapFDUD, address, serial port
    }
    else if(180 >= FDUD && FDUD > 93){                    //if FDUD is between 90 and 180, then make...
      mapFDUD = map(FDUD, 90, 180, 0, SpeedFDUD);         //read value from FDUD, convert the input value from 90 to 180 in a dc motor value from 0 to SpeedFDUD and store it to mapFDUD
      motor(9,mapFDUD, address, Serial);                  //command for backward in mix mode, movement mapFDUD, address, serial port
    }
    else if(87 <= FDUD && FDUD <= 93){                    //if FDUD is 90, then make...
      motor(8,0, address, Serial);                        //command for forward in mix mode, stop movement, address, serial port
    }
    lastFDUD = FDUD;                                      //stores FDUD on lastFDUD
  }

  if(FDUD != lastFDUD && joybut == LOW){                  //if FDUD (foot drive forward/backward) not equal to lastFDUD and joybut is equal to LOW (pressed), then make...
    if(FDUD < 87){                                        //if FDUD is between 0 and 90, then make...
      mapFDUD = map(FDUD, 90, 0, 0, SpeedFDUDfast);       //read value from FDUD, convert the input value from 0 to 90 in a dc motor value from 0 to SpeedFDUDfast and store it to mapFDUD
      motor(8,mapFDUD, address, Serial);                  //command for forward in mix mode, movement mapFDUD, address, serial port
    }
    else if(180 >= FDUD && FDUD > 93){                    //if FDUD is between 90 and 180, then make...
      mapFDUD = map(FDUD, 90, 180, 0, SpeedFDUDfast);     //read value from FDUD, convert the input value from 90 to 180 in a dc motor value from 0 to SpeedFDUDfast and store it to mapFDUD
      motor(9,mapFDUD, address, Serial);                  //command for backward in mix mode, movement mapFDUD, address, serial port
    }
    else if(87 <= FDUD && FDUD <= 93){                    //if FDUD is 90, then make...
      motor(8,0, address, Serial);                        //command for forward in mix mode, stop movement, address, serial port
    }
    lastFDUD = FDUD;                                      //stores FDUD on lastFDUD
  }

  newData = false;                          //set new data received to false for receiving new data
  }
}


//Function for reading a command and store it to designation
void readCommand(int bytes){                //function readCommand takes the length of received data (bytes) from onReceive and make...

  if(bytes == 2){                           //if bytes is equal to 2 (received bytes), then make...
    dataReceived[0] = Wire.read();          //store the first byte from received data over I2C to dataReceived array
    dataReceived[1] = Wire.read();          //store the second byte from received data over I2C to dataReceived array

    switch(dataReceived[0]){
      case 'Q' : BP1 = dataReceived[1];     //if the first byte in the array dataReceived is equal to Q, then store the second byte from the array dataReceived to BP1
                 break;                     //finish the command and return
      case 'R' : BP2 = dataReceived[1];
                 break;
      case 'S' : BP3 = dataReceived[1];
                 break;
      case 'T' : BP4 = dataReceived[1];
                 break;
      case 'U' : BP5 = dataReceived[1];
                 break;
      case 'V' : UAL = dataReceived[1];
                 break;
      case 'W' : UAR = dataReceived[1];
                 break;
      case 'X' : DD = dataReceived[1];
                 break;
      case 'Y' : FDLR = dataReceived[1];
                 break;
      case 'Z' : FDUD = dataReceived[1];
                 break;
      case 'd' : joybut = dataReceived[1];
                 break;
      case 'h' : BUT4 = dataReceived[1];
                 break;
      case 'l' : BUT8 = dataReceived[1];
                 break;
      case 'p' : BUT12 = dataReceived[1];
                 break;
      case 'x' : BUT20 = dataReceived[1];
                 break;
    }
    newData = true;
  }
}


//Function for driving the feet and dome motors over serial
void motor(const byte command, const byte value, const byte address, Stream& stream){
  data[0] = address;                            //write address in data array
  data[1] = command;                            //write command for forward/reverse/left/right in data array
  data[2] = value;                              //write movement speed in data array
  for(byte index = 0; index < 3; index++){      //create the checksum for the array data[i] with 0 <= i <= 3
    crc16(data[index]);                         //call the function crc16
  }
  data[3] = crc >> 8;                           //store checksum in data array
  data[4] = crc;
  stream.write(data, sizeof(data));             //send the data array by serial
  crc = 0;                                      //clear the checksum
}


//Calculates CRC16 of nBytes of data[index] in byte array
void crc16(uint8_t data) {

  int i;
  crc = crc ^ ((uint16_t)data << 8);
  for (i=0; i<8; i++){
    if (crc & 0x8000){
      crc = (crc << 1) ^ 0x1021;
    }
    else{
      crc <<= 1;
    }
  }
}

Ein frohes neues, wünsche ich auch.

Du verwendest beim Uno den seriellen D0 und D1. Das musst du ändern, da der auch für die USB Anbindung zum PC verwendet wird.
Setze statt dessen SoftwareSerial an beliebig anderen digitalen Pins ein.
Auch beim Mega solltest du einen von Serial1 -Serial3 verwenden.

Vielen Dank!

Das hatte ich zuerst so gemacht, doch aufgrund dieses Fehlers/Einfrierens dann auf die hardware serielle Schnittstelle gewechselt. Eigentlich in der Hoffnung, dass da das Problem aufgrund eventuell gemeinsam verwendeten Resourcen vielleicht verschwindet.
Wenn ich den Arduino programmiere, dann stecke ich die Verbindung D0/1 einfach kurz aus, das passt so und wäre kein Problem.
Werden denn von der seriellen Verbindung TX/RX und der Wire Lib irgendwelche Timer oder sonst was verwendet die da in Konflikt kommen können?

Diese beiden Funktionen sind direkt in der Hardware implementiert und funktionieren, eine fehlerfreie Programmierung vorausgesetzt, problemlos zusammen.

Evtl. macht ja auch dein Motor Probleme, wenn dieser startet. Da ist I2C sehr empfindlich. Wie lang sind deine I2C Leitungen ?

Leitungen etwa 50cm lang, also sollte eigentlich gehen.
Das mit den Motoren habe ich auch schon gedacht, aber das Problem tritt sogar auf, wenn ich die Motoren vom Motorcontroller entferne, den Controller aber per TX/RX am Arduino lasse! Dann friert das System, resp. die Arduinos auch ein.
Programmtechnisch sollte dies so funktionieren? Oder habe ich was falsch aufgebaut?

Was ich noch testen kann, habe hier paar Ferritkerne herumliegen, diese an die Spannungsversorgung des Motorcontrollers, einer an +24V, der andere an GND zu klemmen. Dass es hier vielleicht Störungen gibt die dann über GND zum Akku und den Arduinos zurück fliessen?
Arduinos haben Spannungswandeler 24V zu 5V und gehen direkt an den 5V Pin.

Mal anderes. Die Komunikation zwischen Arduino und Motortreiber funktioniert ohne I2C?
Funktioniert sie immernoch mit dem Motor angeschlossen?

Die Serielle Schnittstelle D0 un D1 kann man ohne probleme verwenden wenn man USb nicht braucht.

Aber um besser zu verstehen: Du hast einen UNO und einen Mega 2560 über I2C miteinander verbunden. Hast Du zusätzliche Pullupwiderstände auf SDA bzw SCL geschaltet?
Der MEGA ist der Master und der UNO ist der Slave der die Hardware ansteuert. Wieso nicht umgekehrt?

Grüße Uwe

Nur I2C oder nur TX/RX funktionier, sowohl mit wie auch ohne Motoren angeschlossen. Sobald ich aber beides kombiniere wie hier jetzt, dann blockiert es beide Arduinos sobald Befehle an den TX Ausgang gegeben werden.

Ja klar, Pullupwiderstände von 10kOhm habe ich am Mega, da diese ja bereit 10k eingebaut hat, somit habe ich ca. 5kOhm.
Ja weil der Mega mein erster Arduino war und auch die Steuerung der Signalübertragung übernimmt. Der Mega hat auch schon Hardware dran die er ansteuert. Das sollte ja aber egal sein, ob ich nun am Uno oder Mega die hardware seriellen Anschlüsse brauche!?

Der MEGA hat 4 serielle Schnittstellen. Da kannst Du eine für die Verbindung zum UNO und eine für den Motorkontroller nehmen. Dazu bleibt die erste für USB frei.

Grüße Uwe

Nein, sollte ist da falsch.

I2C ist ein Bussystem, welches für eine kurze Verbindung zwischen verschiedenen IC's entwickelt wurde. Da können 50 cm durchaus schon zu lang sein.
Über den Tipp von Uwe, alles per seriell zu lösen, solltest du mal nachdenken.

Ich werde mir das anschauen! Ein Display welches ich auch über I2C nutze, wäre dann aber nicht mehr zu gebrauchen. Sonst habe ich ja wieder RX/TX mit der Wire Lib.
Aber was mich trotzdem verwundert, warum es einzeln ohne Probleme läuft, und sobald es zusammengeführt wird klemmts. Das hat ja nichts mit I2C an und für sich zu tun. Sonst würde es ja auch schon Probleme verursachen mit nur I2C und ohne den ganzen Rest.

Äh; muß nicht sein.

Grüße Uwe

Du solltest genau analysieren, wo deine Fehlerquelle genau ist.
Wie schon geschrieben, es gibt kein Problem mit seriell und I2C, wenn alles fehlerfrei und richtig programmiert wurde und die Hardware Ok ist.
Dazu gehören auch kurze I2C-Verbindungen.
Nochmal I2C ist sehr störanfällig, wenn lange Strippen und Motoren im Einsatz sind.

Das hatte ich schon beschrieben.

Ich habe gerade mal was lustiges versucht...

  • Also, System nur mit Ansteuerung der Motoren per Motorcontroller an TX/RX, sonst nix im Programm => läuft perfekt.
  • System mit nur I2C Verbindungen, ohne TX/RX und abgeklemmtem Motorcontroller => läuft perfekt.
  • System kombiniert I2C mit TX/RX wie es oben im ersten Beitrag gepostet wurde, Motoren angeschlossen => Verbindung friert ein und muss Resettet/Neugestartet werden.
  • System kombiniert I2C mit TX/RX wie es oben im ersten Beitrag gepostet wurde, Motoren abgeklemmt, Motorcontroller jedoch angeschlossen => Verbindung friert ein und muss Resettet/Neugestartet werden.

Gibt in diesem Fall der Motorcontroller irgendwelche Fehlströme/Signale ab? Habe dort ja nur die GND und TX Leitung vom Arduino dran (abgesehen von der Stromversorgung für die Motoren).
Kennt jemand diesen Motorcontroller? Würde ein anderer Motorcontroller vielleicht Abhilfe schaffen? Zum Beispiel der Sabertooth 2x25A, der wäre von den Einstellungen und Aufbau sehr ähnlich.

Das mit Umstellen auf TX/RX für alles geht leider nicht so einfach. Problem Nr.1 ist die VarSpeedServo Lib die mit der SoftwareSerial Lib nicht funktioniert (gibt Störungen auf die Servos). Nr.2 wäre dann wohl wieder die bestehend bleibende I2C Verbindung zwischen dem Mega und Uno, aufgrund des Problems Nr.1, und das gibt dann wohl wieder die Probleme des Einfrierens weil ja auch I2C mit den hardware UARTs im Spiel sind.

Das ist reines Raten und stochern im Nebel.

Zeige uns dein Schaltbild und den Sketch auf dem Mega.

Ist der Motorcontroller dieser hier?

Wo ist da der RX Eingang?
Grüße Uwe

Beim Pin S1 ist der RX Eingang, S2 wäre der TX falls man ihn braucht. Das wird alles mit der Software Motion Control am PC konfiguriert.

Schaltbild und Mega Sketch folgen...

Hier der Mega Code, die Werte bekommt er von einem Xbee gesendet:

 /**SETTINGS**/
const unsigned long Baudrate = 38400;       //starts serial port with a baudrate by 38400 b/s
const unsigned long BaudrateBT_TC = 19200;  //starts serial port with a baudrate by 19200 b/s
const unsigned long BaudrateMP = 9600;      //starts serial port wit ha baudrate by 9600 b/s

const byte ArduBody = 0x2A;                 //I2C address for the Arduino UNO, body
const byte ArduDome = 0x1A;                 //I2C address for the Arduino UNO, dome

const byte RSSIsensitivity = 90;        //received signal strength from Xbee controls the range until signal is lost and the fail safe will stop the motors,
                                        //the Xbee's standard edition will give a value between 0 and 92 and the pro version a value between 0 and 100
                                        
const byte DDstop = 0;         //Dome drive, basic position joystick (stop position)
const byte FDLRstop = 0;       //Foot drive left/right, basic position joystick (stop position)
const byte FDUDstop = 0;       //Foot drive forward/backward, basic position joystick (stop position)

const byte DPangleMIN = 0;      //set minimum angle for dome panels 1-10 to close the panels
const byte DP16angleMAX = 175;  //set maximum angle for dome panels 1-6 to open the panels (lower panels) (when BUT16 is pressed four times)
const byte DP710angleMAX = 165; //set maximum angle for dome panels 7-10 to open the panels (upper panels) (when BUT16 is pressed four times)
const byte SpeedDP = 40;        //set the speed for dome panels 1-10 (when BUT16 is pressed once or four times) (0=full speed, 1-255 slower to faster)
const byte DPangleRattle = 80;  //set maximum angle for dome panels 1-10 to open the panels (rattle functions, BUT16 is pressed twice or three times)
const byte SpeedDPrattle = 0;   //set the speed for dome panels 1-10 (rattle functions, BUT16 is pressed twice or three times)(0=full speed, 1-255 slower to faster)
const byte DPangleMAX = 170;    //set maximum angle for dome panels 1-10 to open the panels (scream function, BUT16 is pressed once)

const unsigned long DPservoMin = 900;    //set minimum pulse length in microseconds for dome panels
const unsigned long DPservoMax = 2100;   //set maximum pulse length in microseconds for dome panels

/*/////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/

 //Definition of pinnumbers
const byte DomePanel1 = 2;  //Dome panel 1 connected to pin D2
const byte DomePanel2 = 3;  //Dome panel 2 connected to pin D3
const byte DomePanel3 = 4;  //Dome panel 3 connected to pin D4
const byte DomePanel4 = 5;  //Dome panel 4 connected to pin D5
const byte DomePanel5 = 6;  //Dome panel 5 connected to pin D6
const byte DomePanel6 = 7;  //Dome panel 6 connected to pin D7

const byte XbeeRSSI = 10;   //Xbee RSSI pin connected to pin D10

 //Definition of designations for reading signals (signals to be received)
byte DP1 = 0;    //Domepanel 1
byte DP2 = 0;    //Domepanel 2
byte DP3 = 0;    //Domepanel 3
byte DP4 = 0;    //Domepanel 4
byte DP5 = 0;    //Domepanel 5
byte DP6 = 0;    //Domepanel 6
byte DP7 = 0;    //Domepanel 7
byte DP8 = 0;    //Domepanel 8
byte DP9 = 0;    //Domepanel 9
byte DP10 = 0;   //Domepanel 10

byte BP1 = 0;    //Bodypanel 1
byte BP2 = 0;    //Bodypanel 2
byte BP3 = 0;    //Bodypanel 3
byte BP4 = 0;    //Bodypanel 4
byte BP5 = 0;    //Bodypanel 5

byte UAL = 0;    //arm left
byte UAR = 0;    //arm right

byte DD = 0;     //Dome drive
byte FDLR = 0;   //Foot drive left/right
byte FDUD = 0;   //Foot drive forward/backward
byte joybut = 0; //Foot drive joystick-button

byte BUT1 = 0;   //Button 1
byte BUT2 = 0;   //Button 2
byte BUT3 = 0;   //Button 3
byte BUT4 = 0;   //Button 4
byte BUT5 = 0;   //Button 5
byte BUT6 = 0;   //Button 6
byte BUT7 = 0;   //Button 7
byte BUT8 = 0;   //Button 8
byte BUT9 = 0;   //Button 9
byte BUT10 = 0;  //Button 10
byte BUT11 = 0;  //Button 11
byte BUT12 = 0;  //Button 12
byte BUT13 = 0;  //Button 13
byte BUT14 = 0;  //Button 14
byte BUT15 = 0;  //Button 15
byte BUT16 = 0;  //Button 16
byte BUT17 = 0;  //Button 17
byte BUT18 = 0;  //Button 18
byte BUT19 = 0;  //Button 19
byte BUT20 = 0;  //Button 20
byte BUT21 = 0;  //Button 21
byte BUT22 = 0;  //Button 22
byte BUT23 = 0;  //Button 23

byte autobut = 0;  //Automatic button

 //Definition of designations for storing signals (cache)
char var = 0;        //variable for reading incoming serial data
byte error = 0;      //error from I2C

byte lastBUT21 = 1;  //last status from button 21 to close all dome panels on power ON

byte step4 = 0;      //counts steps when button 16 pressed 4 times
byte step3 = 0;      //counts steps when button 16 pressed 3 times
byte step2 = 0;      //counts steps when button 16 pressed twice
byte step1 = 0;      //counts steps when button 16 pressed once

byte rssi = 0;       //variable for RSSI value from Xbee, the standard edition will give a value between 0 and 92 and the pro version a value between 0 and 100

String BT_RX;       //stores the letter from BT_var to BT_RX
char BT_var;        //reads the letter from Bluetooth serial

unsigned long interval = 0;       //waiting period in milliseconds (cache)
unsigned long previousMillis = 0; //stores past time

#include <VarSpeedServo.h>    //adds library to control servos
#include <Wire.h>             //adds library for I2C

//create servo object (maximum 8)
VarSpeedServo servoDP1;   //create servo dome panel 1
VarSpeedServo servoDP2;   //create servo dome panel 2
VarSpeedServo servoDP3;   //create servo dome panel 3
VarSpeedServo servoDP4;   //create servo dome panel 4
VarSpeedServo servoDP5;   //create servo dome panel 5
VarSpeedServo servoDP6;   //create servo dome panel 6


void setup() {
  Serial1.begin(Baudrate);       //starts serial port for Xbee with a baudrate by "Baudrate" (b/s)
  Serial2.begin(BaudrateBT_TC);  //starts serial port for Bluetooth module with a baudrate by "BaudrateBT_TC" (b/s)
  Serial2.setTimeout(3);         //sets the maximum milliseconds to wait for serial data
  Serial3.begin(BaudrateMP);     //starts serial port with a baudrate by "BaudrateMP" (b/s)

  Wire.begin();                  //starts I2C
  //Wire.setClock(295000);       //set the clock speed from I2C to 295kHz

  //attach the servos
  servoDP1.attach(DomePanel1,DPservoMin,DPservoMax);  //servoDP1 is attached to pin DomePanel1 with pulse length DPservoMin and DPservoMax
  servoDP2.attach(DomePanel2,DPservoMin,DPservoMax);  //servoDP2 is attached to pin DomePanel2 with pulse length DPservoMin and DPservoMax
  servoDP3.attach(DomePanel3,DPservoMin,DPservoMax);  //servoDP3 is attached to pin DomePanel3 with pulse length DPservoMin and DPservoMax
  servoDP4.attach(DomePanel4,DPservoMin,DPservoMax);  //servoDP4 is attached to pin DomePanel4 with pulse length DPservoMin and DPservoMax
  servoDP5.attach(DomePanel5,DPservoMin,DPservoMax);  //servoDP5 is attached to pin DomePanel5 with pulse length DPservoMin and DPservoMax
  servoDP6.attach(DomePanel6,DPservoMin,DPservoMax);  //servoDP6 is attached to pin DomePanel6 with pulse length DPservoMin and DPservoMax

  
  //definition of input/output pins
  pinMode(XbeeRSSI, INPUT_PULLUP);   //pin XbeeRSSI is an input
  
}

void loop() {

//RSSI value from the Xbee to detect when the signal is missing
  rssi = pulseIn(XbeeRSSI, LOW, 200);                   //read the RSSI value from Xbee (the XBee’s RSSI PWM period is 200µs), the standard edition will give a value between 0 and 92 and the pro version a value between 0 and 100

  if(rssi <= RSSIsensitivity){                          //if RSSI value is less or equal to RSSIsensitivity (inside controllable range), then make...

  //read serial and store it to designation
    readCommand(Serial1);

  }
  else if(rssi > RSSIsensitivity){          //if RSSI value is greater than RSSIsensitivity (out of controllable range), then make...
    command('X',DDstop, ArduBody);          //send the letter X (for dome drive) and dome movement stopped (left < 90 < right, 80 slow left, 0 full throttle resp. 100 slow right, 180 full throttle) to ArduBody
    command('Y',FDLRstop, ArduBody);        //send the letter Y (for foot drive left/right) travel stopped (right < 90 < left, 80 slow right, 0 full throttle resp. 100 slow left, 180 full throttle) to ArduBody
    command('Z',FDUDstop, ArduBody);        //send the letter Z (for foot drive forward/backward) and travel stopped (backwards < 90 < forwards, 80 slow backward, 0 full throttle resp. 100 slow forward, 180 full throttle) to ArduBody
  }

//read serial and send it via serial xx to the device
  while (Serial2.available() > 0) {         //while serial is available, make...
    BT_var = Serial2.read();                //store received string from serial to BT_var
    BT_RX = BT_RX + BT_var;                 //add received string to BT_RX
    if(BT_var == '\0'){                     //if BT_var is equal to '\0', then make...
      Serial3.print(BT_RX);                 //send string from BT_RX
      Serial3.print('\r');                  //send carriage return
      Serial2.print(BT_RX);                 //send string from BT_RX
      Serial2.print('\r');                  //send carriage return
      BT_RX = "";                           //clear BT_RX
    }
  }
  

//Domefunctions:

  //Button16 pressed once:
  while(BUT16 == 1 || step1 > 0){                       //if BUT16 is equal to 1 (pressed once) or step1 is greater than 0, then make...
    
    if(millis() - previousMillis >= interval){          //if millis minus previousMillis is greater or equal to interval, then make...
      
      step1 ++;                                         //step1 +1 (counts steps)
      switch (step1){                                   //switch step1

        case 1:                                         //if step1 is equal to 1
        servoDP1.write(DPangleMAX, SpeedDP);            //set servoDP1 with angle DPangleMAX and speed SpeedDP
        servoDP2.write(DPangleMAX, SpeedDP);            //set servoDP2 with angle DPangleMAX and speed SpeedDP
        servoDP3.write(DPangleMAX, SpeedDP);            //set servoDP3 with angle DPangleMAX and speed SpeedDP
        servoDP4.write(DPangleMAX, SpeedDP);            //set servoDP4 with angle DPangleMAX and speed SpeedDP
        servoDP5.write(DPangleMAX, SpeedDP);            //set servoDP5 with angle DPangleMAX and speed SpeedDP
        servoDP6.write(DPangleMAX, SpeedDP);            //set servoDP6 with angle DPangleMAX and speed SpeedDP
        command('t',BUT16, ArduDome);                   //send the letter t (for BUT16) and the value of BUT16 (how often pressed to set the correct speed value for dome panels) by I2C
        command('G',DPangleMAX, ArduDome);              //send the letter G (for dome panel 7) and the value of DPangleMAX (opening angle for servo) by I2C
        command('H',DPangleMAX, ArduDome);              //send the letter H (for dome panel 8) and the value of DPangleMAX (opening angle for servo) by I2C
        command('I',DPangleMAX, ArduDome);              //send the letter I (for dome panel 9) and the value of DPangleMAX (opening angle for servo) by I2C
        command('J',DPangleMAX, ArduDome);              //send the letter J (for dome panel 10) and the value of DPangleMAX (opening angle for servo) by I2C
        interval = 1000;                                //waiting time to open the panels (milliseconds)
        break;                                          //finish case and return

        case 2:                                         //if step1 is equal to 2
        command('X',75, ArduBody);                      //send the letter X (for dome drive) and dome movement slowly left, about 360 degrees (left < 90 < right, 80 slow left, 0 full throttle resp. 100 slow right, 180 full throttle) by I2C
        interval = 3000;                                //waiting time to turn the dome (milliseconds)
        break;                                          //finish case and return

        case 3:                                         //if step1 is equal to 3
        command('X',DDstop, ArduBody);                  //send the letter X (for dome drive) and dome movement stopped (left < 90 < right, 80 slow left, 0 full throttle resp. 100 slow right, 180 full throttle) by I2C
        interval = 1500;                                //waiting time (milliseconds)
        break;                                          //finish case and return

        case 4:                                         //if step1 is equal to 4
        servoDP1.write(DPangleMIN, SpeedDP);            //set servoDP1 with angle DPangleMIN and speed SpeedDP
        servoDP2.write(DPangleMIN, SpeedDP);            //set servoDP2 with angle DPangleMIN and speed SpeedDP
        servoDP3.write(DPangleMIN, SpeedDP);            //set servoDP3 with angle DPangleMIN and speed SpeedDP
        servoDP4.write(DPangleMIN, SpeedDP);            //set servoDP4 with angle DPangleMIN and speed SpeedDP
        servoDP5.write(DPangleMIN, SpeedDP);            //set servoDP5 with angle DPangleMIN and speed SpeedDP
        servoDP6.write(DPangleMIN, SpeedDP);            //set servoDP6 with angle DPangleMIN and speed SpeedDP
        command('G',DPangleMIN, ArduDome);              //send the letter G (for dome panel 7) and the value of DPangleMIN (closing angle for servo) by I2C
        command('H',DPangleMIN, ArduDome);              //send the letter H (for dome panel 8) and the value of DPangleMIN (closing angle for servo) by I2C
        command('I',DPangleMIN, ArduDome);              //send the letter I (for dome panel 9) and the value of DPangleMIN (closing angle for servo) by I2C
        command('J',DPangleMIN, ArduDome);              //send the letter J (for dome panel 10) and the value of DPangleMIN (closing angle for servo) by I2C
        interval = 1;                                   //waiting time to close the panels (milliseconds)
        break;                                          //finish case and return

        default:
        step1 = 0;                                      //put step1 back to 0
        BUT16 = 0;                                      //put BUT16 back to 0
        interval = 0;                                   //put interval back to 0

      }
      
    previousMillis = millis();                          //previousMillis is millis
    }
  }


  //Button16 pressed twice:
  while(BUT16 == 2 || step2 > 0){                       //if BUT16 is equal to 2 (pressed twice) or step2 is greater than 0, then make...
    
    if(millis() - previousMillis >= interval){          //if millis minus previousMillis is greater or equal to interval, then make...
      
      step2 ++;                                         //step2 +1 (counts steps)
      switch (step2){                                   //switch step2

        case 1:                                         //if step2 is equal to 1
        servoDP1.write(DPangleRattle, SpeedDPrattle);   //set servoDP1 with angle DPangleRattle and speed SpeedDPrattle
        interval = 175;                                 //waiting time to open the panel (milliseconds)
        break;                                          //finish case and return

        case 2:                                         //if step2 is equal to 2
        servoDP1.write(DPangleMIN, SpeedDPrattle);      //set servoDP1 with angle DPangleMIN and speed SpeedDPrattle
        servoDP2.write(DPangleRattle, SpeedDPrattle);   //set servoDP2 with angle DPangleRattle and speed SpeedDPrattle
        interval = 175;                                 //waiting time to open/close the panels (milliseconds)
        break;                                          //finish case and return

        case 3:                                         //if step2 is equal to 3
        servoDP2.write(DPangleMIN, SpeedDPrattle);      //set servoDP2 with angle DPangleMIN and speed SpeedDPrattle
        servoDP3.write(DPangleRattle, SpeedDPrattle);   //set servoDP3 with angle DPangleRattle and speed SpeedDPrattle
        interval = 175;                                 //waiting time to open/close the panels (milliseconds)
        break;                                          //finish case and return

        case 4:                                         
        servoDP3.write(DPangleMIN, SpeedDPrattle);      //set servoDP3 with angle DPangleMIN and speed SpeedDPrattle
        servoDP4.write(DPangleRattle, SpeedDPrattle);   //set servoDP4 with angle DPangleRattle and speed SpeedDPrattle
        interval = 175;                                 //waiting time to open/close the panels (milliseconds)
        break;                                          //finish case and return

        case 5:                                         
        servoDP4.write(DPangleMIN, SpeedDPrattle);      //set servoDP4 with angle DPangleMIN and speed SpeedDPrattle
        servoDP5.write(DPangleRattle, SpeedDPrattle);   //set servoDP5 with angle DPangleRattle and speed SpeedDPrattle
        interval = 175;                                 //waiting time to open/close the panels (milliseconds)
        break;                                          //finish case and return

        case 6:                                         
        servoDP5.write(DPangleMIN, SpeedDPrattle);      //set servoDP5 with angle DPangleMIN and speed SpeedDPrattle
        servoDP6.write(DPangleRattle, SpeedDPrattle);   //set servoDP6 with angle DPangleRattle and speed SpeedDPrattle
        interval = 175;                                 //waiting time to open/close the panels (milliseconds)
        break;                                          //finish case and return

        case 7:                                         
        servoDP6.write(DPangleMIN, SpeedDPrattle);      //set servoDP6 with angle DPangleMIN and speed SpeedDPrattle
        command('t',BUT16, ArduDome);                   //send the letter t (for BUT16) and the value of BUT16 (how often pressed to set the correct speed value for dome panels) by I2C
        command('G',DPangleRattle, ArduDome);           //send the letter G (for dome panel 7) and the value of DPangleRattle (opening angle for servo) by I2C
        interval = 175;                                 //waiting time to open/close the panels (milliseconds)
        break;                                          //finish case and return

        case 8:                                         
        command('G',DPangleMIN, ArduDome);              //send the letter G (for dome panel 7) and the value of DPangleMIN (closing angle for servo) by I2C
        command('H',DPangleRattle, ArduDome);           //send the letter H (for dome panel 8) and the value of DPangleRattle (opening angle for servo) by I2C
        interval = 175;                                 //waiting time to open/close the panels (milliseconds)
        break;                                          //finish case and return

        case 9:                                         
        command('H',DPangleMIN, ArduDome);              //send the letter H (for dome panel 8) and the value of DPangleMIN (closing angle for servo) by I2C
        command('I',DPangleRattle, ArduDome);           //send the letter I (for dome panel 9) and the value of DPangleRattle (opening angle for servo) by I2C
        interval = 175;                                 //waiting time to open/close the panels (milliseconds)
        break;                                          //finish case and return

        case 10:                                         
        command('I',DPangleMIN, ArduDome);              //send the letter I (for dome panel 9) and the value of DPangleMIN (closing angle for servo) by I2C
        command('J',DPangleRattle, ArduDome);           //send the letter J (for dome panel 10) and the value of DPangleRattle (opening angle for servo) by I2C
        interval = 175;                                 //waiting time to open/close the panels (milliseconds)
        break;                                          //finish case and return

        case 11:                                         
        command('J',DPangleMIN, ArduDome);              //send the letter J (for dome panel 10) and the value of DPangleMIN (closing angle for servo) by I2C
        interval = 1;                                   //waiting time to close the panel (milliseconds)
        break;                                          //finish case and return

        default:
        step2 = 0;                                      //put step2 back to 0
        BUT16 = 0;                                      //put BUT16 back to 0
        interval = 0;                                   //put interval back to 0

      }
      
    previousMillis = millis();                          //previousMillis is millis
    }
  }



  //Button21 pressed:
  if(BUT21 == 1 && lastBUT21 != 1){                     //if BUT21 is equal to 1 (extended dome panels) and lastBUT21 not equal to 1, then make...
    
        servoDP1.write(DPangleMAX, SpeedDP);            //set servoDP1 with angle DPangleMAX and speed SpeedDP
        servoDP2.write(DPangleMAX, SpeedDP);            //set servoDP2 with angle DPangleMAX and speed SpeedDP
        servoDP3.write(DPangleMAX, SpeedDP);            //set servoDP3 with angle DPangleMAX and speed SpeedDP
        servoDP4.write(DPangleMAX, SpeedDP);            //set servoDP4 with angle DPangleMAX and speed SpeedDP
        servoDP5.write(DPangleMAX, SpeedDP);            //set servoDP5 with angle DPangleMAX and speed SpeedDP
        servoDP6.write(DPangleMAX, SpeedDP);            //set servoDP6 with angle DPangleMAX and speed SpeedDP
        command('y',BUT21, ArduDome);                   //send the letter y (for BUT21) and the value of BUT21 (how often pressed to set the correct speed value for dome panels) by I2C
        command('G',DPangleMAX, ArduDome);              //send the letter G (for dome panel 7) and the value of DPangleMAX (opening angle for servo) by I2C
        command('H',DPangleMAX, ArduDome);              //send the letter H (for dome panel 8) and the value of DPangleMAX (opening angle for servo) by I2C
        command('I',DPangleMAX, ArduDome);              //send the letter I (for dome panel 9) and the value of DPangleMAX (opening angle for servo) by I2C
        command('J',DPangleMAX, ArduDome);              //send the letter J (for dome panel 10) and the value of DPangleMAX (opening angle for servo) by I2C
        lastBUT21 = BUT21;                              //set lastBUT21 to BUT21
  }
  
  else if(BUT21 == 0 && lastBUT21 != 0){                //if BUT21 is equal to 0 (retracted dome panels) and lastBUT21 not equal to 0, then make...
    
        servoDP1.write(DPangleMIN, SpeedDP);            //set servoDP1 with angle DPangleMIN and speed SpeedDP
        servoDP2.write(DPangleMIN, SpeedDP);            //set servoDP2 with angle DPangleMIN and speed SpeedDP
        servoDP3.write(DPangleMIN, SpeedDP);            //set servoDP3 with angle DPangleMIN and speed SpeedDP
        servoDP4.write(DPangleMIN, SpeedDP);            //set servoDP4 with angle DPangleMIN and speed SpeedDP
        servoDP5.write(DPangleMIN, SpeedDP);            //set servoDP5 with angle DPangleMIN and speed SpeedDP
        servoDP6.write(DPangleMIN, SpeedDP);            //set servoDP6 with angle DPangleMIN and speed SpeedDP
        command('y',BUT21, ArduDome);                   //send the letter y (for BUT21) and the value of BUT21 (how often pressed to set the correct speed value for dome panels) by I2C
        command('G',DPangleMIN, ArduDome);              //send the letter G (for dome panel 7) and the value of DPangleMIN (closing angle for servo) by I2C
        command('H',DPangleMIN, ArduDome);              //send the letter H (for dome panel 8) and the value of DPangleMIN (closing angle for servo) by I2C
        command('I',DPangleMIN, ArduDome);              //send the letter I (for dome panel 9) and the value of DPangleMIN (closing angle for servo) by I2C
        command('J',DPangleMIN, ArduDome);              //send the letter J (for dome panel 10) and the value of DPangleMIN (closing angle for servo) by I2C
        lastBUT21 = BUT21;                              //set lastBUT21 to BUT21
  }

}


//Function for sending a command
void command(const char designation, const byte value, const byte address) {  //the function command contains the sending part inside the ( ) declared as a character and value and the I2C address where to send
  Wire.beginTransmission(address);
  Wire.write(designation);
  Wire.write(value);
  error = Wire.endTransmission();
  errorCode(error);
}


void errorCode(byte error){
  if(error != 0){
    switch(error){
      case 1: Serial.print("Command error: ");
              Serial.print(error);
              Serial.println(" Data too long to fit in transmit buffer!");
              break;
      case 2: Serial.print("Command error: ");
              Serial.print(error);
              Serial.println(" Received NACK on transmit of address!");
              break;
      case 3: Serial.print("Command error: ");
              Serial.print(error);
              Serial.println(" Received NACK on transmit of data!");
              break;
      case 4: Serial.print("Command error: ");
              Serial.print(error);
              Serial.println(" Other error!");
              break;
    }
  }
}


//Function for reading a command and store it to designation or send it via serial xx to the next Arduino
void readCommand(Stream& stream){                       //the function readCommand contains the serial port inside the ( ) where to read from
  while(stream.available() > 0){                        //while serial is available, make...
    var = stream.read();                                //store first character from serial to var
    switch(var){                                        
      case 'A' : DP1 = stream.parseInt();               //if var is equal to A, then store second character from serial to DP1
                 break;                                 //finish the command and return
      case 'B' : DP2 = stream.parseInt();
                 break;
      case 'C' : DP3 = stream.parseInt();
                 break;
      case 'D' : DP4 = stream.parseInt();
                 break;
      case 'E' : DP5 = stream.parseInt();
                 break;
      case 'F' : DP6 = stream.parseInt();
                 break;
      case 'G' : DP7 = stream.parseInt();               //if var is equal to G, then store second character from serial to DP7
                 command('G',DP7, ArduDome);            //if var is equal to G, then send G + DP7 to I2C
                 break;
      case 'H' : DP8 = stream.parseInt();
                 command('H',DP8, ArduDome);
                 break;
      case 'I' : DP9 = stream.parseInt();
                 command('I',DP9, ArduDome);
                 break;
      case 'J' : DP10 = stream.parseInt();
                 command('J',DP10, ArduDome);
                 break;
      case 'Q' : BP1 = stream.parseInt();
                 command('Q',BP1, ArduBody);
                 break;
      case 'R' : BP2 = stream.parseInt();
                 command('R',BP2, ArduBody);
                 break;
      case 'S' : BP3 = stream.parseInt();
                 command('S',BP3, ArduBody);
                 break;
      case 'T' : BP4 = stream.parseInt();
                 command('T',BP4, ArduBody);
                 break;
      case 'U' : BP5 = stream.parseInt();
                 command('U',BP5, ArduBody);
                 break;
      case 'V' : UAL = stream.parseInt();
                 command('V',UAL, ArduBody);
                 break;
      case 'W' : UAR = stream.parseInt();
                 command('W',UAR, ArduBody);
                 break;
      case 'X' : DD = stream.parseInt();
                 command('X',DD, ArduBody);
                 break;
      case 'Y' : FDLR = stream.parseInt();
                 command('Y',FDLR, ArduBody);
                 break;
      case 'Z' : FDUD = stream.parseInt();
                 command('Z',FDUD, ArduBody);
                 break;
      case 'd' : joybut = stream.parseInt();
                 command('d',joybut, ArduBody);
                 break;
      case 'h' : BUT4 = stream.parseInt();
                 command('h',BUT4, ArduBody);
                 break;
      case 'l' : BUT8 = stream.parseInt();
                 command('l',BUT8, ArduBody);
                 break;
      case 'p' : BUT12 = stream.parseInt();
                 command('p',BUT12, ArduBody);
                 break;
      case 't' : BUT16 = stream.parseInt();
                 break;
      case 'w' : BUT19 = stream.parseInt();
                 break;
      case 'x' : BUT20 = stream.parseInt();
                 command('x',BUT20, ArduBody);
                 break;
      case 'y' : BUT21 = stream.parseInt();
                 break;
      case 'z' : autobut = stream.parseInt();
                 break;
      case '@' : BUT22 = stream.parseInt();
                 break;
      case '$' : BUT23 = stream.parseInt();
                 break;
    }
  }
}

Sorry, aber das Schaltbild ist schlecht bis falsch.
Du hast am Arduino 24 Volt ?

Und im Sketch konnte ich bisher nicht erkennen, wie du I2C verwendest.
Es fehlt u.a. Die Wire.h Library und die Initialisierung.

Und was alles soll der UNO machen?
Warum schließt du den Motortreiber nicht direkt am Mega an ?
Der hat doch 3 zusätzliche Serielle. Wenn das nicht reicht, nimmst du dafür eine SoftwareSerial.

Edit:
Wire gefunden.
Das gehört der Übersicht wegen an den Anfang des Sketches. Dann muss keiner suchen.

Nein, das sind zwei 24V zu 5V Wandler. 24V vom Akku (unten). 5V zu den Arduinos. Zumindest so erkenne ich das.

Wieso brauchst Du eigentlich 2 Arduinos?
Grüße Uwe