I2C Slave Stops Working When Messages Are Too Fast

Hi There,

I'm trying to write an Arduino to be a motor driver (slave) for an RPi Zero (master) I have. However, whenever the message frequency sent by the RPi is too fast the Arduino completely stops working. When the frequency is low (below 40Hz) it works perfect, but I need it to run at least 100Hz. The message size is 25 bytes.

Even when I look for it through the RPi's I2C command line tool it is not there. I'm not sure what is going on and any insight would be nice.

Thanks!

Arduino Sketch:

#include <Wire.h>
int messageCount = 0;
int debug = 1;
unsigned int motors[6];

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

void clearI2CBuffer(){
  while(Wire.available()){
    Wire.read();
  }
}

void loop() {
  delay(500);
  if (debug) {
    Serial.println("****");
    Serial.println(messageCount);
    for (int i = 0; i < 6; i++) {
      Serial.println(motors[i]);
    }
  }
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
  int i = 0;
  int pos[6] = {0};

  while (Wire.available()) {
    byte temp = Wire.read();
    if (i > 0 && i < 25) {
      int ind = (i - 1) / 4;
      pos[ind] = pos[ind] << 8;
      pos[ind] |= temp;
    }
    i++;
  }

  for (int j = 0; j < 6; j++) {
    motors[j] = pos[j];
  }
  messageCount++;
}

slave_receiver.ino (1.96 KB)

Update: Using a scope I have confirmed that the bus doesn't have an ACK on it

If you want to fill an array with 16 bytes, then why don't you transfer 16 bytes ?

volatile int messageCount = 0;
volatile unsigned int motors[6];

void receiveEvent(int howMany) {
  if (howMany == 12) {     // expecting 12 bytes
    for (int i=0; i<6; i++) {
      motors[i] = Wire.read() << 8;
      motors[i] |= Wire.read();
    }
  }
  messageCount++;
}

40Hz is slow. I don't know much about the I2C between a Raspberry Pi and a Arduino. Perhaps it is slow.