user765: I am using Python smbus write_word_data method to send int values from a Raspberry Pi to an Arduino using I²C.
This seems to be the correct method.
When I send values from 0-255, I see the following in my Arduino serial monitor

0,0,0
  0,1,0
  0,2,0
  … 
  0,255,0

Sending 256 I see:

0,0,1

For 257 I see:

0,1,1

Etc, etc...
My question is, how would I modify the following Arduino code to properly 'reconstitute' the int values, and then send them back to the RPi?
#include <Wire.h>

#define SLAVE_ADDRESS 0x04
int number = 0;
int state = 0;
bool newData = false;

void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  // initialize i2c as slave
  Wire.begin(SLAVE_ADDRESS);
  // define callbacks for i2c communication
  Wire.onReceive(receiveData);
  Wire.onRequest(sendData);
  Serial.println("Ready!");
}

void loop() {
  Serial.println(receivedValue);
  newData=false;
}

// callback for received data
void receiveData(int byteCount) {
  while(Wire.available()) {
    newData = true;
    Wire.read();
    if(Wire.available() == 2) {
      receivedValue = Wire.read() | Wire.read() << 8;
    }
  }
}

// callback for sending data
void sendData() {
  Wire.write(number);
}


user2967: Ir seems to me that there is something wrong with the Python Raspberry Pi code. What you show is 3 bytes of data, not 2. That's wrong.
If you're writing a 2 byte word, I would expect to see 2 bytes, not 3. You might want to post a question on the Raspberry Pi forum to get help resolving THAT problem first. 
If you're stuck with the sending code you have, then here's what you would do.
Looking at your data, the first byte is always zero. You want to discard it.
The second byte is your low order byte, and your third byte of data is the high order byte. You need to do some juggling to get the data into the correct byte order, like this:
void readWordWithPadding()
{
  if (Wire.available()<3)
  {
    newData = false;
    return;
  }
    newData = true;

  Wire.read(); //Throw away the filler byte
  int lowByte = Wire.read();
  int hiByte = Wire.read();

  //Shift the high byte by 8 bits and add in the low byte
  receivedValue = (hiByte << 8) + lowByte ;
  return;
}


user313: Unless (and until) your application needs high enough data rates that you need to make the most efficient use possible of your data channel (or you're talking to an inflexible hardware device that dictates the data protocol), you'll save yourself a lot of headaches by sending human-readable strings, something like:
x= 12345, y=   -32
x=   432, y=-33221

You can reconstitute them at the other end with with atol(), log them  to a file, be able to understand them later, and see instantly whether the sender sent what you expected it to. Don't optimize until you have to; you may not have to.

user2973: void receiveData(int byteCount){

  // Looks like your number is sent in a 3 byte packet
  if (bytecount == 3)
  {

    // Discard first number as it is seemingly alway zero
    Wire.read();

    // Read low byte into rxnum
    int rxnum = Wire.read();

    // Read high byte into rxnum
    rxnum += Wire.read() << 8;

    // Send back
    sendInt(rxnum);

  }

}

void sendInt(int num){

  // Uncomment below if you want so send back in same format
  // Wire.write(0);

  // Send low byte
  Wire.write((uint8_t)num);

  // Send high byte
  num >>= 8;
  Wire.write((uint8_t)num);
}


765: <p>I am using Python <strong>smbus</strong> <code>write_word_data</code> method to send int values from a Raspberry Pi to an Arduino using I²C.</p>

<p>This seems to be the correct method.</p>

<p>When I send values from 0-255, I see the following in my Arduino serial monitor</p>

<blockquote>
  <p>0,0,0<br>
  0,1,0<br>
  0,2,0<br>
  … <br>
  0,255,0<br></p>
</blockquote>

<p>Sending 256 I see:</p>

<blockquote>
  <p>0,0,1</p>
</blockquote>

<p>For 257 I see:</p>

<blockquote>
  <p>0,1,1</p>
</blockquote>

<p>Etc, etc...</p>

<p>My question is, how would I modify the following Arduino code to properly 'reconstitute' the int values, and then send them back to the RPi?</p>



<pre class="lang-cpp prettyprint-override"><code>#include &lt;Wire.h&gt;

#define SLAVE_ADDRESS 0x04
int number = 0;
int state = 0;
bool newData = false;

void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  // initialize i2c as slave
  Wire.begin(SLAVE_ADDRESS);
  // define callbacks for i2c communication
  Wire.onReceive(receiveData);
  Wire.onRequest(sendData);
  Serial.println("Ready!");
}

void loop() {
  Serial.println(receivedValue);
  newData=false;
}

// callback for received data
void receiveData(int byteCount) {
  while(Wire.available()) {
    newData = true;
    Wire.read();
    if(Wire.available() == 2) {
      receivedValue = Wire.read() | Wire.read() &lt;&lt; 8;
    }
  }
}

// callback for sending data
void sendData() {
  Wire.write(number);
}
</code></pre>
 2967: <p>Ir seems to me that there is something wrong with the Python Raspberry Pi code. What you show is 3 bytes of data, not 2. That's wrong.</p>

<p>If you're writing a 2 byte word, I would expect to see 2 bytes, not 3. You might want to post a question on the Raspberry Pi forum to get help resolving <strong>THAT</strong> problem first. </p>

<p>If you're stuck with the sending code you have, then here's what you would do.</p>

<p>Looking at your data, the first byte is always zero. You want to discard it.</p>

<p>The second byte is your low order byte, and your third byte of data is the high order byte. You need to do some juggling to get the data into the correct byte order, like this:</p>

<pre><code>void readWordWithPadding()
{
  if (Wire.available()&lt;3)
  {
    newData = false;
    return;
  }
    newData = true;

  Wire.read(); //Throw away the filler byte
  int lowByte = Wire.read();
  int hiByte = Wire.read();

  //Shift the high byte by 8 bits and add in the low byte
  receivedValue = (hiByte &lt;&lt; 8) + lowByte ;
  return;
}
</code></pre>
 313: <p>Unless (and until) your application needs high enough data rates that you need to make the most efficient use possible of your data channel (or you're talking to an inflexible hardware device that dictates the data protocol), you'll save yourself a lot of headaches by sending human-readable strings, something like:</p>

<pre><code>x= 12345, y=   -32
x=   432, y=-33221
</code></pre>

<p>You can reconstitute them at the other end with with <code>atol()</code>, log them  to a file, be able to understand them later, and see instantly whether the sender sent what you expected it to. Don't optimize until you have to; you may not have to.</p>
 2973: <pre><code>void receiveData(int byteCount){

  // Looks like your number is sent in a 3 byte packet
  if (bytecount == 3)
  {

    // Discard first number as it is seemingly alway zero
    Wire.read();

    // Read low byte into rxnum
    int rxnum = Wire.read();

    // Read high byte into rxnum
    rxnum += Wire.read() &lt;&lt; 8;

    // Send back
    sendInt(rxnum);

  }

}

void sendInt(int num){

  // Uncomment below if you want so send back in same format
  // Wire.write(0);

  // Send low byte
  Wire.write((uint8_t)num);

  // Send high byte
  num &gt;&gt;= 8;
  Wire.write((uint8_t)num);
}
</code></pre>
