Pages: [1]   Go Down
Author Topic: I2C Oddity  (Read 348 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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:
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?
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Don't do a serial print inside an ISR.

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

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 551
Posts: 46240
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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?
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So the chip doesn't get hot.

Just kidding. smiley
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Pages: [1]   Go Up
Jump to: