I have 2 USB / I2C devices: an Arduino UNO and a LinkM device.
Could I connect them together.
Answer is yes

Some tips and tricks:
- Arduino is programmed with Arduino IDE, C++
- LinkM is programmed with Processing, based on Java
- beware of byte type! It took me A couple of hours to figure out what was wrong

- byte is 0..255 unsigned in Arduino but -128..+127 signed on Processing, so we need the int byte2int(byte b0) utility
// Java byte are signed.
// Convert byte to unsigned integer
int byte2int(byte b0) {
if (b0<0) {
return (b0 & 0xFF);
}
else {
return (b0);
}
}
- on Processing, for the buffer with bytes sent to the I2C device and the buffer with bytes received from the I2C device, both buffers' sizes shall match exact lengths required by the I2C address + instruction
Below are the LinkM Master and the Arduino Slave sketches.
Enjoy!
LinkM Master sketch/*
* Based on
* LinkM -- interface to LinkM USB dongle
* linkm-tool -- Command-line tool for using LinkM.
*
* 2009, Tod E. Kurt, ThingM, http://thingm.com/
*
* Adapted
* avenue33 - Jan 26, 2011
* Arduino I2C address = 4
*/
import thingm.linkm.*;
int LINKMCMDI2CTRANS= 1; // i2c read/wri (N args: addr+other)
int LINKMCMDI2CWRITE= 2; // i2c write (N args: addr+other)
int LINKMCMDI2CREAD = 3; // i2c read (1 args: addr)
int LINKMCMDI2CSCAN = 4; // i2c bus scan (2 args: start,end)
int LINKMCMDI2CCONN = 5; // i2c connect/disc (1 args: 1/0)
int LINKMCMDI2CINIT = 6; // i2c init (0 args: )
int cmd;
byte bytessent;
byte bytesreceived;
LinkM linkm = new LinkM();
int _address = 0x04;
int err;
int _x;
// Java byte are signed.
// Convert byte to unsigned integer
int byte2int(byte b0) {
if (b0<0) {
return (b0 & 0xFF);
}
else {
return (b0);
}
}
void setup() {
size(320, 160);
try {
println("USB I2C ");
linkm.open();
println("***1");
linkm.i2cInit();
println("***2");
linkm.i2cEnable(true);
println("***3");
_x=0;
}
catch( IOException ioe ) {
println("Could not connect: " +ioe);
}
}
// buffers sizes shall match exact lengths
byte cmdbuf[] = new byte[2];
byte resbuf[] = new byte[0];
void draw() {
PFont font;
// The font must be located in the sketch's
// "data" directory to load successfully
font = loadFont("Dialog-24.vlw");
textFont(font, 32);
try {
cmdbuf[0] = byte(_address);
cmdbuf[1] = byte(_x);
fill(192);
rect(0, 0, width, height);
fill(0, 102, 164);
text( _x, 15, 40 );
delay(10);
// Alternatives
linkm.commandi2c(cmdbuf, resbuf );
// linkm.command(LINKMCMDI2CWRITE, cmdbuf, resbuf );
_x ++;
_x %= 10;
delay(5000);
}
catch( IOException ioe ) {
println("Error: " +ioe);
}
}
Arduino Slave sketch// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this
// Created 29 March 2006
// Adapted
// avenue33 - Jan 26, 2011
// Arduino I2C address = 4
#include <Wire.h>
#define LED_OUT 13
int x;
void setup() {
Wire.begin(4); // join i2c bus with address #4
Wire.onReceive(receiveEvent); // register event
Serial.begin(19200); // start serial for output
pinMode(LED_OUT, OUTPUT);
digitalWrite(LED_OUT, LOW);
x = 0;
}
void loop() {
if (x > 0) {
Serial.println(x, HEX);
for (int i=0; i<x; i++) {
digitalWrite(LED_OUT, HIGH);
delay(200);
digitalWrite(LED_OUT, LOW);
delay(200);
}
x = 0;
delay(1000);
}
delay(100);
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
x = Wire.receive(); // receive byte as an integer
}