I2C slave no response

Hi

I have tried the below code on both an Arduino Uno and a Due (with correct voltages) to run them as I2C slaves, but I am not getting any response when trying to make a write to the Arduino.

I have measured the I2C bus with an oscilloscope to verify that the signalling from the master is correct, start bit, address and write bit are all ok, but no ack from the Arduino.

Any suggestions on what could be wrong?

Thanks!

// 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>

void setup()
{
  Wire.begin(8);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
  Serial.println("Ready to receive");
}

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.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
}

Ok, so I got the Due to acknowledge the address and some data. I noticed the master and slave handles the addresses differently. The master sends bit1-bit7 as the 7-bit address, while the slave (due) treats the 7-bit address as bit0-bit6. So, sending address 0x10 equals address 0x08 on receiver side in my case.

I also found someone saying it’s not allowed to have Serial commands in the interrupt routine, and that makes sense. So I re-wrote a bit. But I am not getting any output even though the Due acknowledges data transfer. Any ideas why that may be?

// 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>
char buffer[100];
int incount=0;
int outcount=0;

int x=0;

void setup()
{
 Wire.begin(8);                // join i2c bus with address #4
 Wire.onReceive(receiveEvent); // register event
 Serial.begin(9600);           // start serial for output
 Serial.println("Ready to receive");
}

void loop()
{
 if(incount!=outcount){
   Serial.print(buffer[outcount++]);
   if(outcount==100) outcount=0;
 }
 if(x!=0){
   Serial.println(x);
   x=0;
 }
}

// 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
 {
   buffer[incount++] = Wire.read(); // receive byte as a character
   if(incount==100) incount=0;
   //Serial.print(c);         // print the character
 }
 x = Wire.read();    // receive byte as an integer
 //Serial.println(x);         // print the integer
}

Ok, Got it working! :slight_smile:

Turns out if the data sent to the Arduino on the I2C bus is more than 32 bytes long, it won't return anything. As I understand it, it doesn't even call the receiveEvent IRQ routine. It just disappears into the binary universe.