Go Down

Topic: I2C Oddity (Read 506 times) previous topic - next topic

Corbski

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.

Code: [Select]
#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:

Code: [Select]
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?

Nick Gammon

Don't do a serial print inside an ISR.

http://www.gammon.com.au/interrupts
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

PaulS

Code: [Select]
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?

Nick Gammon

So the chip doesn't get hot.

Just kidding. :)
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Corbski


Don't do a serial print inside an ISR.

http://www.gammon.com.au/interrupts


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.

Go Up