I2C slave receiver problem


I am trying to use the Wire library for I2C communication. However I have the following problem: the first byte sent by the master is reported incorrectly by the Wire library. More specific:

  • if I send 0x12 from the master, I get 0x31, 0x32 on Arduino
  • if I send 0x12, 0X34 from the master, I get 0x31, 0x32, 0x34 on Arduino

It looks like the first received byte is split in half and reported as ASCII codes. The master is a iPort/AFM RS232-I2C Host adapter which was extensively used in our lab and works reliably.

Did anybody notice this problem? Any suggestions are welcome.

No, this is most unlikely. There has to be a "user transformation" inbetween - either your master or your program makes the conversion. Could you give the code of the slave?


It’s basically the slave_receiver example, just modified to show the byte value in hex.

#include <Wire.h>

void setup()
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(19200);           // start serial for output
  Serial.println("receive test");

void loop()

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
  while(1 < Wire.available()) // loop through all but the last
    char c = Wire.receive(); // receive byte as a character
    Serial.println(c, HEX);         // print the character
  int x = Wire.receive();    // receive byte as an integer
  Serial.println(x, HEX);         // print the integer

I can try to capture of the iPort waveforms also, to show that it outputs correctly. We’ve used this device extensively with no problems, but a second check never hurts …

The I2C/Wire "receiveEvent" is called from an interrupt handler and this puts some restrictions on what you can do from within the handler. Calling "Serial.print" is no good.

Remove print from your receive handler and try again (you can set a global flag and print from within the loop).

No argument from me on this, but if it’s not good maybe it should not be in the official Wire library examples either. The code that you see is the slave_receiver.pde with HEX added for formatting.

I’ll try your suggestion to see if it makes any difference.

I’m beginning to suspect the scripts that I use to control the I2C master, but unfortunately I have to wait until Monday to ask my colleagues about them.

Thank you all for your help and quick replies.

Wire.receive returns a byte not an int. If you need to read 16 bit values you need to read the two bytes separately and combine them ( you can use the word function macro to do this).

Also, it looks like you are calling receive outside the check to wire.avaiilable. Receive should only be called after you have confirmed that data is available

Hi all,

Turns out I've used some old scripts to control the master, everything seems to work for now.

Thanks for all your help.