user11676: I have an Arduino Mega2560 and a Raspberry Pi hooked up through I2C. The Pi is acting as the master, while the Arduino is the slave. While sending data over I2C, the int message gets messed up and will either send the address or the data. Then I can't even receive any useful data from the Arduino. 
So if I turn the receiving function off it sends the data just fine, but when I ask the Pi to start receiving data again it slows down the entire bus and data starts conflicting between the Pi and Arduino. Also it only happens with the Arduino. Every other device works flawlessly. 
Here's what my code looks like on the Pi side. I'm using SMBus to send and receive bytes. I didn't bother to put up code for it because I don't have the source code for SMBus. I just trust that they work because my other I2C devices work without a hitch.
while True:
    #if alternating == true then get the imu if not then get the motor speed
    if alternating == True:
        try: #need the try because an error will stop the program completely
            ypr = IMU.getYPR()
            yaw = int(ypr['yaw'] * 180 / math.pi)
            savedYaw = yaw
        except:
            yaw = savedYaw
            #print "exception"
            pass
            #write yaw to arduino
            i2c.writeByte(yaw)
            alternating = False
        else:
            #start reading data from arduino
            #readArduino()
            alternating = True
            pass

Then on the Arduino side these are my onReceive and onRequest functions:
void readPI(int byteC) {
    if(Wire.available()) {
        reference = Wire.read();
    }
    pid1.getReference(reference);
    pid2.getReference(reference);
}

void sendPI() {
    int values[] = {(int)out, (int)outReversed  };
    Wire.write(values[count]);
    count++;
    if(count > 1) {
        count = 0;
    }
}

Is there something about the Arduino that I don't know? Maybe it's a timing issue? Is there a way to set up registers? I can either receive or send, but I can't do both, and Googling the problem only leads to an example of someone sending 1 - 9 over the Pi. I can't find examples of anyone actually doing something complicated with an Arduino and a Rasp Pi over I2C. Any and all help would be amazing!

user10794: I find your onRequest function obscure:
void sendPI(){
     int values[] = {(int)out, (int)outReversed  };

     Wire.write(values[count]);
     count++;
     if(count > 1){
     count = 0;

     }
 }

Why only send one byte? I think you have a number of problems:

The size of int on the Arduino Uno is 2 bytes, on a Pi it is 4 bytes. So there is a mismatch there for a start.
Wire.write (written like that) sends one byte, so that is only going to be half of your int. So that is even less. 
It isn't obvious what the Pi end is doing, but to make the int sizes match, I would be sending the lot in one hit like this:
void sendPI(){
     long values[] = {(int)out, (int)outReversed  };
     Wire.write((byte *) &values, sizeof values);
 }

Now you just read 8 bytes on the Pi (two ints).


11676: <p>I have an Arduino Mega2560 and a Raspberry Pi hooked up through I2C. The Pi is acting as the master, while the Arduino is the slave. While sending data over I2C, the int message gets messed up and will either send the address or the data. Then I can't even receive any useful data from the Arduino. </p>

<p>So if I turn the receiving function off it sends the data just fine, but when I ask the Pi to start receiving data again it slows down the entire bus and data starts conflicting between the Pi and Arduino. Also it only happens with the Arduino. Every other device works flawlessly. </p>

<p>Here's what my code looks like on the Pi side. I'm using SMBus to send and receive bytes. I didn't bother to put up code for it because I don't have the source code for SMBus. I just trust that they work because my other I2C devices work without a hitch.</p>

<pre><code>while True:
    #if alternating == true then get the imu if not then get the motor speed
    if alternating == True:
        try: #need the try because an error will stop the program completely
            ypr = IMU.getYPR()
            yaw = int(ypr['yaw'] * 180 / math.pi)
            savedYaw = yaw
        except:
            yaw = savedYaw
            #print "exception"
            pass
            #write yaw to arduino
            i2c.writeByte(yaw)
            alternating = False
        else:
            #start reading data from arduino
            #readArduino()
            alternating = True
            pass
</code></pre>

<p>Then on the Arduino side these are my <code>onReceive</code> and <code>onRequest</code> functions:</p>



<pre class="lang-C++ prettyprint-override"><code>void readPI(int byteC) {
    if(Wire.available()) {
        reference = Wire.read();
    }
    pid1.getReference(reference);
    pid2.getReference(reference);
}

void sendPI() {
    int values[] = {(int)out, (int)outReversed  };
    Wire.write(values[count]);
    count++;
    if(count &gt; 1) {
        count = 0;
    }
}
</code></pre>

<p>Is there something about the Arduino that I don't know? Maybe it's a timing issue? Is there a way to set up registers? I can either receive or send, but I can't do both, and Googling the problem only leads to an example of someone sending 1 - 9 over the Pi. I can't find examples of anyone actually doing something complicated with an Arduino and a Rasp Pi over I2C. Any and all help would be amazing!</p>
 10794: 

<p>I find your onRequest function obscure:</p>

<pre class="lang-C++ prettyprint-override"><code>void sendPI(){
     int values[] = {(int)out, (int)outReversed  };

     Wire.write(values[count]);
     count++;
     if(count &gt; 1){
     count = 0;

     }
 }
</code></pre>

<p>Why only send one byte? I think you have a number of problems:</p>

<ul>
<li><p>The size of <code>int</code> on the Arduino Uno is 2 bytes, on a Pi it is 4 bytes. So there is a mismatch there for a start.</p></li>
<li><p><code>Wire.write</code> (written like that) sends one byte, so that is only going to be half of your <code>int</code>. So that is even less. </p></li>
<li><p>It isn't obvious what the Pi end is doing, but to make the <code>int</code> sizes match, I would be sending the lot in one hit like this:</p>

<pre class="lang-C++ prettyprint-override"><code>void sendPI(){
     long values[] = {(int)out, (int)outReversed  };
     Wire.write((byte *) &amp;values, sizeof values);
 }
</code></pre>

<p>Now you just read 8 bytes on the Pi (two ints).</p></li>
</ul>
