why might i2c not work when a Bluesmirf Bluetooth modem connects?

Hello all,

I am developing an application that uses the SM130 RFID transceiver to read RFID tags, and it stores them in EEprom memory. The goal is to then send this EEprom database to an Android app to see the list.

This was actually all working fine, until I switched Arduino Boards. I recently fried my Uno by using a not-so-good 12V lithium ion battery, so now I am using the Duemilanove arduino board. I2C works great in my sketch, right until i connect my bluesmirf bluetooth modem with ANY android-arduino connectivity app, including mine. This leads me to believe it is definitely not my Java development for the Android. As soon as the bluetooth socket disconnects from said Android apps (software close, literally shutting down the app), the I2c goes back to working as desired. The Bluetooth modem is using hardware serial.

I DO believe this all started when switching from Uno to Duemilanove, but I could be mistakened. Is there any reason that opening the bluetooth socket serial buffer on an Android app may make the I2C cease?

Here is my sketch:

#include <Wire.h>
#include <EEPROM.h>

// There are 512 bytes of EEPROM available. The data stored there 
//remains when the Arduino is switched off or reset
// Each tag uses 5 bytes (1 byte status, 4 bytes tag number), 
//so 512 / 5 = 102 cards may be stored

#define MAX_NO_CARDS 102 


// define the LED pins:
#define androidLED 6
#define waitingLED 7
#define successLED 8
#define failureLED 9

int toggleState = 0;    // state of the toggling LED
long toggleTime = 0;    // delay time of the toggling LED
byte tag[4];            // tag serial numbers are 4 bytes long

void setup() {           
  Wire.begin();                      // join i2c bus  
  Serial.begin(115200);                // set up serial port

  Wire.beginTransmission(0x42);      // the RFID reader's address is 42
  Wire.write(0x01);                   // Length
  Wire.write(0x80);                   // reset reader 
  Wire.write(0x81);                   // Checksum
  Wire.endTransmission();            

  // initialize the LEDs:
  pinMode(androidLED, OUTPUT);
  pinMode(waitingLED, OUTPUT);
  pinMode(successLED, OUTPUT);
  pinMode(failureLED, OUTPUT);

  // print user instructions serially:
   Serial.println("n - add card to database");
   Serial.println("c - clear entire database");  
   Serial.println("d - delete card from database");
   Serial.println("p - print database"); 

  // delay to allow reader startup time:
  delay(2000);
} 


void loop() {
  if (Serial.available() > 0) {
    // read the latest byte:
    int incomingByte = Serial.read(); 
    // Serial.println(incomingByte);  
    switch (incomingByte) {
    case 'n':            // if user enters 'n' then store tag number
      seekNewTag();
      break;  
      case 68: 
      eraseEEPROM();    // if user enters 'c' then erase database
      blink(failureLED, 700, 5);
      Serial.println("Database deleted"); 
      break;     
    case 'd':           // if user enters 'd' then delete the last tag
      seekAndDeleteTag();
      break;
      case 65:    //Write Database to Android
      blink(androidLED, 50, 10);
      printTags();     
      break;      
    }
  } 
  else {
    //if there's no serial data coming in, 
    // the default action is to seek new tags:
    seekNewTag(); 
  }
  // delay before next command to the reader:
  delay(200);
}

// erase the entire EEPROM memory storage:
void eraseEEPROM(){                 
  for(int i = 0; i < 512; i++){
    EEPROM.write(i, 0);   
  }
}
// writes tag number in a location:
void writeTag(int startingAddress, byte byte0, byte byte1, byte byte2, byte byte3){    
  EEPROM.write( startingAddress*5, byte(1));   
  EEPROM.write(startingAddress*5+1, byte0);
  EEPROM.write(startingAddress*5+2, byte1);
  EEPROM.write(startingAddress*5+3, byte2);
  EEPROM.write(startingAddress*5+4, byte3);

}

// delete tag from a specified location
void deleteTag(int startingAddress){                                    
  EEPROM.write( startingAddress*5, byte(0));   
  EEPROM.write(startingAddress*5+1, byte(0));
  EEPROM.write(startingAddress*5+2, byte(0));
  EEPROM.write(startingAddress*5+3, byte(0));
  EEPROM.write(startingAddress*5+4, byte(0));
}
// find the first empty entry in the database:
int findEmptyTag(){                              
  for (int startingAddress = 0; startingAddress< MAX_NO_CARDS; startingAddress++){
    byte value = EEPROM.read(startingAddress*5);
    if (value == byte(0)) {
      return(startingAddress);
    } 
  }  
  return(200);
}

// print the entire database
void printTags(){                                
  for (int thisTag = 0; thisTag< MAX_NO_CARDS; thisTag++){
    printOneTag(thisTag);
  }    
}

void printOneTag(int address) {
  //Serial.print(address);
  Serial.print(":");
  for (int offset = 1; offset < 5; offset++) {
    int thisByte = int(EEPROM.read(address*5+offset));
    // if the byte is less than 16, i.e. only one hex character
    // add a leading 0:
    if (thisByte < 0x10) {
      Serial.print("0"); 
    }
    // print the value:
    Serial.print(thisByte,HEX);
  }
  // add a final linefeed and carriage return:
  //Serial.println();
}
//lookup tag in the database:
int lookupTag(byte byte0, byte byte1, byte byte2, byte byte3){   
  for (int thisCard = 0; thisCard< MAX_NO_CARDS; thisCard++){
    byte value = EEPROM.read(thisCard*5);   
    if (value != byte(0)){                    //it is a valid tag
      //see if all four bytes are the same as the ones we're looking for
      if(byte0 == EEPROM.read(thisCard*5+1) && byte1 == EEPROM.read(thisCard*5+2) 
        && byte2 == EEPROM.read(thisCard*5+3) && byte3 == EEPROM.read(thisCard*5+4)) {
        return(thisCard); 
      }
    } 
  }
  // if you don't find the tag, return 200;
  return(200);   
}

int getTag(){
  byte count = 0;
  byte valid = 0;
  byte byteFromReader = 0;

  Wire.beginTransmission(0x42);
  Wire.write(0x01);           // Length
  Wire.write(0x82);           // Seek for tags
  Wire.write(0x83);           // Checksum
  Wire.endTransmission();
  
  delay(100);
  Wire.requestFrom(0x42, 8); // get data (8 bytes) from reader

  count = 0;                 // keeps track of which byte it is in the response from the reader
  valid = 0;                 // used to indicate that there is a tag there   
  while(Wire.available())  { // while data is coming from the reader
    byteFromReader = Wire.read();
    // no RFID found: reader sends character 2:
    if ((count == 0) && (byteFromReader == 2)) { 
      return(0);
    }
    if ((count == 0) && (byteFromReader== 6)) {
      //if reader sends 6, the tag serial number is coming:
      valid = 1;                                   
    }
    count++;

    if ((valid == 1) && (count > 3) && (count < 8)) {
      // strip out the header bytes  :
      tag[count-4] = byteFromReader;            
    }
    // all four bytes received: tag serial number complete:
    if ((valid == 1) && (count == 8)) {         
      return(1);
    }
  }  
}

void seekNewTag() {
   Serial.println("Waiting for card");
   
  while(getTag() == 0){
    // wait for tag
    if (millis() - toggleTime > 1000) {
      toggle(waitingLED); 
      toggleTime  = millis();
    }
    // unless you get a byte of serial data,
    if (Serial. available()) {
      // break out of the while loop 
      // and out of the seekNewTag() method:
      return;
    }
  }
  blink(successLED, 100, 1);

  // look it up in the database:
  int tagToCheck = lookupTag(tag[0], tag[1], tag[2], tag[3]);      

  if (tagToCheck != 200){
    Serial.println("That tag is already stored");
     deleteTag(tagToCheck); // NEW
     //ENTER CONFIRMATION LED FLASH HERE
    printOneTag(tagToCheck);    
  }
  else {
    int emptyTagLocation = findEmptyTag();
    if (emptyTagLocation != 200){
      writeTag(emptyTagLocation, tag[0], tag[1], tag[2], tag[3]);   
      Serial.println("That tag is new");  
      printOneTag(emptyTagLocation);
      blink(successLED, 100, 1);
    }
    else {
      Serial.println("Maximum number of cards stored");  
      blink(failureLED, 50, 10);
    }
  }
}

void seekAndDeleteTag() {
  Serial.println("Deleting the next card");
  Serial.println("Waiting for card");
  while(getTag() == 0){
    // do nothing; wait for tag
    // unless you get a byte of serial data,
    if (Serial. available()) {
      // break out of the while loop 
      // and out of the method:
      return;
    }
  }
  int tagToDelete = lookupTag(tag[0], tag[1], tag[2], tag[3]);      
  if (tagToDelete == 200){
    Serial.print("That tag is not stored");      
  }
  else {
    deleteTag(tagToDelete);       
  } 
}

void toggle(int thisLED) {
  toggleState = !toggleState;
  digitalWrite(thisLED, toggleState);
}

void blink(int thisLED, int interval, int count) {
  for (int i = 0; i < count; i++) {
    digitalWrite(thisLED, HIGH);
    delay(interval/2);
    digitalWrite(thisLED, LOW);
    delay(interval/2);
  }
}

Thanks for any help.

Which pins did you wire the smirf to? (Pin clash?) How are you powering your Due? (Current too low when running the BT board?) Did you google? http://forum.arduino.cc/index.php?topic=97452.0

digitalWrite(thisLED, HIGH); delay(interval/2); digitalWrite(thisLED, LOW); delay(interval/2);

delay is blocking and might disrupt communication

After Googling around, I have deduced that there is something "odd" about the Duemilanove and the i2c configuration. I've replaced the due with a new Arduino Uno and alas, the problem has vanished, and i2c and hardware serial play nicely together once again.

It appears to be a problem with the due's integrated pull up pins on SDA, SCL, not registering meaningful logic levels?