chipKIT® Development Platform

Inspired by Arduino™

I2C via Wire Library acting strange

Created Wed, 11 Apr 2012 20:32:23 +0000 by Verdris


Verdris

Wed, 11 Apr 2012 20:32:23 +0000

Hi all,

I'm using this code:

/**
 * I2CScanner.pde -- I2C bus scanner for Arduino
 *
 * 2009, Tod E. Kurt, http://todbot.com/blog/
 *
 */

#include "Wire.h"
extern "C" { 
#include "utility/twi.h"  // from Wire library, so we can do bus scanning
}

// Scan the I2C bus between addresses from_addr and to_addr.
// On each address, call the callback function with the address and result.
// If result==0, address was found, otherwise, address wasn't found
// (can use result to potentially get other status on the I2C bus, see twi.c)
// Assumes Wire.begin() has already been called
void scanI2CBus(byte from_addr, byte to_addr, 
                void(*callback)(byte address, byte result) ) 
{
  byte rc;
  byte data = 0; // not used, just an address to feed to twi_writeTo()
  for( byte addr = from_addr; addr <= to_addr; addr++ ) {
    rc = twi_writeTo(addr, &data, 0, 1);
    callback( addr, rc );
  }
}

// Called when address is found in scanI2CBus()
// Feel free to change this as needed
// (like adding I2C comm code to figure out what kind of I2C device is there)
void scanFunc( byte addr, byte result ) {
  Serial.print("addr: ");
  Serial.print(addr,HEX);
  Serial.print( (result==0) ? " found!":"       ");
  Serial.print( (addr%4) ? "\t":"\n");
}


byte start_address = 1;
byte end_address = 127;

// standard Arduino setup()
void setup()
{
    delay(2000);
    Wire.begin();
    Serial.begin(38400);
    Serial.println("\nI2CScanner ready!");

    Serial.print("starting scanning of I2C bus from ");
    Serial.print(start_address,HEX);
    Serial.print(" to ");
    Serial.print(end_address,HEX);
    Serial.println("...Hex");

    // start the scan, will call "scanFunc()" on result from each address
    scanI2CBus( start_address, end_address, scanFunc );

    Serial.println("\ndone");
}

// standard Arduino loop()
void loop() 
{
    // Nothing to do here, so we'll just blink the built-in LED
    digitalWrite(13,HIGH);
    delay(300);
    digitalWrite(13,LOW);
    delay(300);
}

to verify that the address of my digipot is in fact 0x2C, 0x2E, or 0x2F depending on how I wire things up. It's working just fine, but I'm also "finding" other addresses on the bus, even when only the digipot is connected. Here's the output from the serial monitor:

I2CScanner ready!
starting scanning of I2C bus from 1 to 7F...Hex
addr: 1 found!	addr: 2 found!	addr: 3 found!	addr: 4 found!
addr: 5 found!	addr: 6 found!	addr: 7 found!	addr: 8       
addr: 9       	addr: A       	addr: B       	addr: C       
addr: D       	addr: E       	addr: F       	addr: 10       
addr: 11       	addr: 12       	addr: 13       	addr: 14       
addr: 15       	addr: 16       	addr: 17       	addr: 18       
addr: 19       	addr: 1A       	addr: 1B       	addr: 1C       
addr: 1D       	addr: 1E       	addr: 1F       	addr: 20       
addr: 21       	addr: 22       	addr: 23       	addr: 24       
addr: 25       	addr: 26       	addr: 27       	addr: 28       
addr: 29       	addr: 2A       	addr: 2B       	addr: 2C       
addr: 2D       	addr: 2E       	addr: 2F found!	addr: 30       
addr: 31       	addr: 32       	addr: 33       	addr: 34       
addr: 35       	addr: 36       	addr: 37       	addr: 38       
addr: 39       	addr: 3A       	addr: 3B       	addr: 3C       
addr: 3D       	addr: 3E       	addr: 3F       	addr: 40       
addr: 41       	addr: 42       	addr: 43       	addr: 44       
addr: 45       	addr: 46       	addr: 47       	addr: 48       
addr: 49       	addr: 4A       	addr: 4B       	addr: 4C       
addr: 4D       	addr: 4E       	addr: 4F       	addr: 50       
addr: 51       	addr: 52       	addr: 53       	addr: 54       
addr: 55       	addr: 56       	addr: 57       	addr: 58       
addr: 59       	addr: 5A       	addr: 5B       	addr: 5C       
addr: 5D       	addr: 5E       	addr: 5F       	addr: 60       
addr: 61       	addr: 62       	addr: 63       	addr: 64       
addr: 65       	addr: 66       	addr: 67       	addr: 68       
addr: 69       	addr: 6A       	addr: 6B       	addr: 6C       
addr: 6D       	addr: 6E       	addr: 6F       	addr: 70       
addr: 71       	addr: 72       	addr: 73       	addr: 74       
addr: 75       	addr: 76       	addr: 77       	addr: 78       
addr: 79       	addr: 7A       	addr: 7B       	addr: 7C found!
addr: 7D       	addr: 7E       	addr: 7F       	
done

So what's the deal with 0x01-0x07 and 0x7C? There's only one device on the bus.

I'm using 4.7k pullup resistors. Would changing them have any effect? I'm going to test that now.

Edit: changed the pullups to 10k. Now the program responds faster, but still finds the other addresses.

Edit Edit: I should add that when I run the code from an Arduino, it works correctly, only finding the appropriate addresses.


Ryan K

Wed, 25 Apr 2012 11:43:59 +0000

Hello,

That probably has to do with the fact that in the pic32mx family it only recognizes 0x08 - 0x77 as valid 7-bit addresses. If you look on page 409 of this datasheet you'll see a table detailing this:

http://ww1.microchip.com/downloads/en/devicedoc/pic32mx_datasheet_v2_61143b.pdf

Best Regards, Ryan K Digilent


EmbeddedMan

Sun, 29 Apr 2012 22:34:54 +0000

Ryan,

I think that table only deals with slave mode addressing, and the OP appears to be talking about using the PIC32 in I2C master mode. Unless I'm reading something wrong here (which is quite possible) the PIC32 can, as a master, address any I2C slave address. If it could not, it would be a major bug in Microchip's I2C implementation.

*Brian