Go Down

Topic: Connecting Arduino Slave and LinkM Master by I2C on Mac OSX (Read 3 times) previous topic - next topic

avenue33

Jan 26, 2011, 06:05 pm Last Edit: Jan 27, 2011, 11:53 pm by avenue33 Reason: 1
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  :0

  • byte is 0..255 unsigned in Arduino but -128..+127 signed on Processing, so we need the int byte2int(byte b0) utility

Code: [Select]
// 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
Code: [Select]
/*
* 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
Code: [Select]
// 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
}

Go Up