I2C Interfacing to linux

Hi,
I have a robot in development, and because Arduino is not powerful enough to do all the calculations, I do them on Chumby Hacker Board (Linux computer). The problem is that I need to get values from my sensors and update data to motor driver, which is Arduino. I thought I will have one arduino doing both, driving motor and reading from the sensors. I would like to use I2C, because of the fact there can be more devices on one bus. I tried Ladyada's I2C example (Chumby Hacker Board - i2c access), but I couldn't get it working.
Is there any linux library that would act as Arduino's Wire library? Or something that would allow me to communicate to arduino through I2C?

Thank You

Why dont you use the serial/usb port?

1 Like

I tried Ladyada's I2C example (Chumby Hacker Board - i2c access), but I couldn't get it working.

Ladyada's tutorials are generally pretty good. If she says it works, it works. So, what problems did you encounter?

I didn't use USB/serial port because I already have all the ports used already.

The problem I encountered is simple: I cannot read anything from arduino using the I2C example, probably because the I2C example does something with registers, and I cannot find how to set Arduino to have registers writable/readable.

The registers that the LadyAda tutorial refers to are the addresses that the Wire library refers to. When you run the code from the tutorial, is the Arduino being talked to at all?

The code I am using:

#include <Wire.h>

void setup()
{
  Serial.begin(9600);
  Wire.begin(10);
  Wire.onRequest(myhandler);
}

void loop()
{
}

void myhandler()
{
  Serial.println("it worked");
  Wire.send("a");
  
}

And what I am using on the chumby:

./i2c_twiddler r 10 10

But that doesn’t work, what is going wrong? Arduino part or the linux one?

But that doesn't work

As in the event handler doesn't get called? Or as in the results are wrong? The Wire library is looking for a seven bit address. Whether the address is for reading or writing is handled by the Wire library. Perhaps the address that i2c_twiddler expects is different for reading and writing.

In any case, you are asking for the 10th byte, while the Arduino only returns 1 byte (if it works).

It doesn't work in way that the handler doesn't even get called.

I would revise the i2c_twiddler app, then, to loop through all the addresses from 0 to 255, to see if the Arduino ever responds by running the handler.

Below is a I2C address scanner, it will try all possible I2C address (0-127) and report back (with address in HEX) which addresses got a response. If nothing shows up then you most likely have a wiring problem, wrong pull-up resistors, or a dead device, etc.

/**
 * 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);
}

First time it worked, showed about 5 adresses responding, but after that, it freezes before any adress gets result. I suppose it is dead device, isn't it?

I don’t see how that code will help when it is the Arduino that is supposed to be the slave to the Linux master.

That code will find any working slave devices when the Arduino is the master.