Hallo,

es sieht nicht so gut aus. Anbei meine aktuellen Testcodes, wo 240 Bytes hin und zurück geschickt und verglichen werden.

MEGA:
Code:
// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

#define REGSIZE 240

byte rspeicher[REGSIZE];
byte wspeicher[REGSIZE];
byte puffer[32];
byte Register=1;
byte rdblock=0;
byte wrblock=0;
byte pos=0;
byte fertig=0;
long dg=0;
long timeout=0;

void setup() {
  Wire.begin(4);                // join I2C bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Wire.onRequest(requestEvent); // register event
  Serial.begin(57600);           // start serial for output

  Serial.println();  
  Serial.println("Starte I2C-Test");  
}

void loop() {
  byte i=0;
  delay(100);
  timeout++;
  if (timeout==90){
      timeout=0;
      Wire.begin(4); 
      Serial.println("TimeOut!");
      dg=0;
  }

  if (fertig !=0){
    fertig=0;
    timeout=0;
    dg++;
    Serial.println(dg);
    
    for (i=0;i<REGSIZE;i++){
      wspeicher[i]=rspeicher[i];
/*      Serial.print(rspeicher[i]);
      Serial.print (" ");*/
    }
//    Serial.println();
  }
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
    byte x=0;
    
    if(howMany == 2){
      rdblock = Wire.read();
      if (rdblock<=240){
        rspeicher[rdblock]=Wire.read();
      }
      if (rdblock==REGSIZE-1){
        fertig=1;
      }
    }else{
      if (howMany == 1){
          x=Wire.read();
          if (x >=10 && x <=250){
            wrblock=x-10;
/*            Serial.print("Lesebyte: ");
            Serial.println(wrblock);*/
          }
      }else{
        Serial.print ("Anzahl Daten: ");
        Serial.println(howMany);
        while (0 < Wire.available()) { //überflüssiges lesen
            x=Wire.read();
        }
      }
    }
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
  //Wire.write(speicher[Register],1);
  puffer[0]=wrblock;
  puffer[1]=wspeicher[puffer[0]];
  Wire.write(puffer,2);
/*  Serial.print("Sendebyte: ");
  Serial.println(puffer[0]);
/*  Serial.print(", Wert: ");
  Serial.println(puffer[1]);*/
  
}
Raspi HW:
Code:
// GCC -Wall -pthread -o /var/scripte/i2cmaster01 /var/scripte/i2cmaster01.c -lpigpio -lrt
// /var/scripte/i2cmaster01
//I2C mit pipgio
//peterfido
//V0.0.2
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pigpio.h>

#define ADDRESS 0x04
#define MSGSIZE  240
char empfdata[MSGSIZE];  // 
char senddata[MSGSIZE];
char commando[32];

int handle=0;
int handles=-1;
unsigned int laenge=0;

volatile sig_atomic_t done = 0;
 
void term(int signum)
{
    done = 1;
/*
    int res=0;
    int dl=0;
    if (handles >= 0){
        for (dl=0;dl<handles;dl++){
            res=i2cClose(dl);    
            printf("%d geschlossen: %d\n",dl, res);
        }
    }
    gpioTerminate();
    printf( "\nSIGINT wurde augeloest - Programm wird beendet\n" );

    exit( 1 );*/
}

void schreiben() {
    
    int res=0;
//    int i=0;
    int wrblock=0;
    int Fehler=0;
    
    for (wrblock=0;wrblock<MSGSIZE;wrblock++){

        commando[0]=wrblock;
        commando[1]=senddata[wrblock];
        res=i2cWriteDevice(handle,commando,2);
        if (res!=0){
            printf("S I2C-Fehler: %d, Block: %d\n", res,wrblock);
            Fehler++;
/*            wrblock--;
            usleep(15000); 
            if (Fehler==10){
                break;
            }*/
            break;
        }
        usleep(15000);
    }
    
/*    printf("Gesendet:\n");
    for(i=0;i<MSGSIZE;i++){
        printf("%d ",senddata[i]);
    }    
    printf("\n");
*/    
}

void lesen() {
    
    int res=0;
//    int i=0;
    int rdblock=0;
    int Fehler=0;    
    
    for (rdblock=0;rdblock<MSGSIZE;rdblock++){

        commando[0]=rdblock+10;
        res=i2cWriteDevice(handle,commando,1);
        if (res==0){
            usleep(1000);
            res=i2cReadDevice(handle,commando,2);
            if (res==2){
            //    printf("Empfangene Daten: %d, Block: %d\n",res,rdblock);
                if (rdblock==commando[0]){
                    empfdata[rdblock]=commando[1];
                }
            }else{
                printf("E Fehler beim Blockeinlesen: %d, Block: %d\n", res,rdblock);
                Fehler++;
                rdblock--;
                usleep(15000);
                if (Fehler==10){
                    break;
                }
                break;
            }
        }else{
            printf("E Fehler beim Leseblock schreiben %d, Block: %d\n", res,rdblock);
            break;
        }
    }    
/*    
    printf("Empfangen:\n");
    for(i=0;i<MSGSIZE;i++){
        printf("%d ",empfdata[i]);
    }    
    printf("\n");    
*/    
}

int vergleichen()
{
    unsigned int i=0;
    int ret=0;
    for (i=0;i<MSGSIZE;i++){
        if (empfdata[i]!=senddata[i]){
            ret=-1;
            break;
        }
    }
    return ret;
}

int main(int argc, char **argv)
{
    int res=0;
    int i=0;
    long dg=1;
    long maxdg=0;
    unsigned int Fehler=0;

    struct sigaction action;
    memset(&action, 0, sizeof(struct sigaction));
    action.sa_handler = term;
    sigaction(SIGINT, &action, NULL);
    sigaction(SIGTERM, &action, NULL);
    
    if (gpioInitialise() < 0)
    {
        printf("Fehler beim Initialisieren von gpio!");
        gpioTerminate();
    }else{
        handle=i2cOpen(1,ADDRESS,0);
        if(handle>=0){
            handles ++;
            printf("\n\n\nStarte I2C-Test (%d)\n\n",handle);
            while (!done)
            {    
                srand(time(NULL));
                for(i=0;i<MSGSIZE;i++){
                     senddata[i]=rand() % 255;
                }        
                schreiben();
                usleep(100000);
                lesen();
                usleep(100000);
                if (vergleichen()==0){
                        printf("Daten OK %ld (%ld)\n",dg,maxdg);
                        Fehler=0;
                        dg++;
                }else{
                    printf("***************************** Daten fehlerhaft %ld *****************************\n",dg);
                    Fehler++;
                    dg=0;
                    if (dg>maxdg){
                        maxdg=dg;
                    }
                    sleep(1);
                    if (Fehler==100){
                        break;
                    }
                }
            }
        }else{
            printf("E Fehler beim Oeffnen: %d\n", handle);    
        }
    }
    res=i2cClose(handle);
    
    if (res!=0){
        printf("E Fehler beim Schliessen: %d\n", res);
    }else{
        handles--;
        printf("E Schliessen OK %d\n",handle);
    }

    gpioTerminate();
    
    return 0;
}
Raspi BitBang:
Code:
// GCC -Wall -pthread -o /var/scripte/bbi2cmaster /var/scripte/bbi2cmaster.c -lpigpio -lrt
// /var/scripte/bbi2cmaster
//I2C mit pipgio
//peterfido
//V0.0.2
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pigpio.h>

#define SDA 2
#define SCL 3
#define TAKT 100000
#define PAUSEN 5000
#define ADDRESS 0x04
#define MSGSIZE  240



char empfdata[MSGSIZE];  // 
char senddata[MSGSIZE];
char commando[64];
char puffer[12];

unsigned int laenge=0;

volatile sig_atomic_t done = 0;
 
void term(int signum)
{
    done = 1;
}

int I2CResetBus(void)
{
    char i;
    int res=0;
    if(gpioRead(SDA) && gpioRead(SCL)) {
        return 0;
    }
    gpioSetMode(SCL, PI_INPUT);
    gpioSetMode(SDA, PI_INPUT);
    gpioSetPullUpDown(SDA, PI_PUD_UP);   // Sets SDA pull-up.
    gpioSetPullUpDown(SCL, PI_PUD_UP);   // Sets SDA pull-up.       
    usleep(50);
    if(!gpioRead(SCL)) {
        return -1; /* SCL wird extern auf Low gehalten, nix zu machen */
    }
    for(i = 0; i<9; i++) { 
        gpioSetMode(SCL, PI_OUTPUT);
        gpioWrite(SCL, 0);
        usleep(50);
        gpioSetMode(SCL, PI_INPUT);
        gpioSetPullUpDown(SCL, PI_PUD_UP);   // Sets SDA pull-up.       
        usleep(50);
        if(gpioRead(SDA)) {
            break; /* SDA ist high STOP */
        }
    } /* for */
    if(!gpioRead(SDA)) {
        return -1; 
    }
    commando[0]= 3;    //stop
    commando[1]= 0;    // Fertig
    res=bbI2CZip(SDA,commando,2,NULL,0);
    if (res!=0){
        printf("Fehler beim Reset!\n");
    }
    if(gpioRead(SDA) && gpioRead(SCL)){  
        return 0;
    }else{
        return -1;  
    }
}


void schreiben() {
    
    int res=0;
//    int i=0;
    int wrblock=0;
    int Fehler=0;
    
    for (wrblock=0;wrblock<MSGSIZE;wrblock++){

        commando[0]= 4;    //'Adresse setzen ankündigen
        commando[1]= ADDRESS;    //'Adresse übergeben
        commando[2]= 2;    //start
        commando[3]= 7;    //'Bytes senden
        commando[4]= 2;    //'Anzahl 
        commando[5]= wrblock;    //Block
        commando[6]= senddata[wrblock];   //Wert
        commando[7]= 3;    //stop
        commando[8]= 0;    //keine weiteren Parameter
        res=I2CResetBus();
        res=bbI2CZip(SDA,commando,9,NULL,0);
        res=I2CResetBus();
        if (res!=0){
            printf("S I2C-Fehler: %d, Block: %d\n", res,wrblock);
            Fehler++;
            wrblock--;
            usleep(PAUSEN*3); 
            if (Fehler==10){
                break;
            }
        }
        usleep(PAUSEN);
    }
/*    
    printf("Gesendet:\n");
    for(i=0;i<MSGSIZE;i++){
        printf("%d ",senddata[i]);
    }    
    printf("\n");
*/
}

void lesen() {
    
    int res=0;
//    int i=0;
    int rdblock=0;
    int Fehler=0;    
    
    for (rdblock=0;rdblock<MSGSIZE;rdblock++){

        commando[0]= 4;    //'Adresse setzen ankündigen
        commando[1]= 4;    //'Adresse übergeben
        commando[2]= 2;    //start
        commando[3]= 7;    //'Bytes senden
        commando[4]= 1;    //'Anzahl 
        commando[5]= rdblock+10;    //Byte
        commando[6]= 2;    //start
        commando[7]= 6;    //Bytes lesen
        commando[8]= 2;    //Anzahl
        commando[9]= 3;    //stop
        commando[10]= 0;    //keine weiteren Parameter
        res=I2CResetBus();
        res=bbI2CZip(SDA,commando,11,puffer,12);    
        res=I2CResetBus();
        
        if (res==0){
            if (puffer[0]==rdblock){
                empfdata[rdblock]=puffer[1];
                Fehler=0;
            }else{
                printf("E Falsche Blocknummer. Erwartet: %d, bekommen: %d, Wert: %d\n",rdblock,puffer[0],puffer[1]);
                Fehler++;
                rdblock--;
                if (Fehler==10){
                    break;
                }
            }
        }else{
            printf("E Fehler beim Blockeinlesen. Block: %d\n",rdblock);
            Fehler++;
            rdblock--;
            if (Fehler==10){
                break;
            }
        }
        usleep(PAUSEN);
    }    
    
    printf("Empfangen:\n");
/*    for(i=0;i<MSGSIZE;i++){
        printf("%d ",empfdata[i]);
    }    
    printf("\n");    
*/    
}

int vergleichen()
{
    unsigned int i=0;
    int ret=0;
    for (i=0;i<MSGSIZE;i++){
        if (empfdata[i]!=senddata[i]){
            ret=-1;
            break;
        }
    }
    return ret;
}

int main(int argc, char **argv)
{
    int res=0;
    int i=0;
    long dg=1;
    long maxdg=0;
    unsigned int Fehler=0;

    struct sigaction action;
    memset(&action, 0, sizeof(struct sigaction));
    action.sa_handler = term;
    sigaction(SIGINT, &action, NULL);
    sigaction(SIGTERM, &action, NULL);
    
    if (gpioInitialise() < 0)
    {
        printf("Fehler beim Initialisieren von gpio!");
        gpioTerminate();
    }else{
        res=bbI2COpen(SDA,SCL,TAKT);
        res=res+gpioSetMode(SDA, PI_INPUT);  // Set SDA as input.
        res=res+gpioSetMode(SCL, PI_INPUT);  // Set SDA as input.
        res=res+gpioSetPullUpDown(SDA, PI_PUD_UP);   // Sets SDA pull-up.
        res=res+gpioSetPullUpDown(SCL, PI_PUD_UP);   // Sets SDA pull-up. 

        if(res==0){
            printf("\n\n\nStarte I2C-Test\n\n");
            while (!done)
            {    
                srand(time(NULL));
                for(i=0;i<MSGSIZE;i++){
                     senddata[i]=rand() % 255;
                }        
                schreiben();
                usleep(5000);
                lesen();
                usleep(5000);
                if (vergleichen()==0){
                        printf("Daten OK %ld (%ld)\n",dg,maxdg);
                        Fehler=0;
                        dg++;
                }else{
                    printf("***************************** Daten fehlerhaft %ld *****************************\n",dg);
                    Fehler++;
                    dg=0;
                    if (dg>maxdg){
                        maxdg=dg;
                    }
                    sleep(1);
                    if (Fehler==100){
                        break;
                    }
                }
            }
        }else{
            printf("E Fehler beim Oeffnen\n");    
        }
    }
    res=bbI2CClose(SDA);
    
    if (res!=0){
        printf("E Fehler beim Schliessen: %d\n", res);
    }else{
        printf("E Schliessen OK\n");
    }

    gpioTerminate();
    
    return 0;
}
Mein Fazit:
Ich bleibe bei UART.