I2C Oddity

I'm working on a home automation system using a Beaglebone, an Arduino Uno, and several home-built arduino clones.

My issue is with my Uno and the I2C setup I'm using.

I've written code to have my Uno act as a I2C recieving slave. I'm trying to figure out why the following code doesn't work.

#include <Wire.h>

void setup()
{
  Wire.begin(4);
  Wire.onReceive(receiveEvent);
  Serial.begin(9600);
  //Serial.println("Debug Spot 1");
}

void loop()
{
  delay(100);
}

void receiveEvent(int howMany)
{
  byte data[howMany];
  byte ELC = 0xFF;
  byte off = 0xA0;
  byte on = 0xA1;
  byte kitchenLights = 0x01;
  //Serial.println("Debug Spot 2");
  while(Wire.available())
  {
    for (int i=0; i <= howMany; i++){
      data[i] = Wire.read();
    }
  }
  for (int i=0; i < howMany; i++) {
    if (data[i] == ELC){
      Serial.println("Aborting...");
      break;
    } 
    if (data[0] == kitchenLights) {
      Serial.print("Kitchen Lighting selected. Action: ");
      if (data[1] == on) { Serial.println("Turn On"); }
      if (data[1] == off) { Serial.println("Turn Off"); }
    }
  }
}

With this code, everything appears to work correctly (i.e. I get the first debug line printed when it's not commented out, and the Uno appears on the bus at 0x04), until I send data to the Uno. When I do that, the Uno freezes, and locks the entire bus. I've done troubleshooting, and I've tracked the bug to the following snippet:

if (data[0] == kitchenLights) {

If I change the 0 to an i, it works perfectly, but doing this limits to only using 0x01 in the first byte I send to the Uno.

While I can live with the limitation, I'm a bit stumped as to why the original code causes the Uno to hang.

Any ideas?

Don't do a serial print inside an ISR.

void loop()
{
  delay(100);
}

Why? Do you care if loop() executes a million times a second, or 10,000? Why not make the delay a couple of hours?

So the chip doesn't get hot.

Just kidding. :slight_smile:

I don't plan on leaving those Serial prints in there, they're just place holders while I work out how best to code this.

Even without them there, it seems like I'd be better of just populating the data array with the ISR, and then having loop() check it's contents outside the ISR and performs actions based on that.

Thanks Nick.