ficeto
Posts: 2
Joined: Thu Jun 13, 2013 9:34 am

Interfacing with arduino[s] through I2C

Thu Jun 13, 2013 10:11 am

Hello guys :) I'm new here and to the Pi/Arduino scene, but I fell in love with both and it was only natural to marry them together :)
While there are many ways described on how to interface with Arduino over Serial port, I found very few on anything else.
Both serial and ICSP communication require logic level converters and I have none of those... :(
But not to be too sad, I2C does not! And it lets you talk to more than one device on the I2C network!
So I went out searching and stumbled upon https://github.com/binerry/RaspberryPi/ ... 2c-arduino which is a sample implementation showing a working I2C communication between RPi and Arduino. But... how can you stop at that? :)
So after some editing and whatnot, I ended up with a binary for the Pi and a small library for the Arduino that lets you do just about anything you want with them.
Here is the usage for the binary:

Code: Select all

Controll your Arduino through I2C
Usage: i2c-arduino ADDRESS COMMAND [ARG]...
Returns: -1 on error or integer value of the result
Commands:
    read <pin>              Sets pin mode to INPUT and returns digitalRead(pin)
    pread <pin>             Sets pin mode to INPUT_PULLUP and returns digitalRead(pin)
    aread <pin>             Returns analogRead(pin)
    write <pin> <value>     Sets pin mode to OUTPUT and executes digitalWrite(pin, value). Returns the set value
    awrite <pin> <value>    Sets pin mode to OUTPUT and executes analogWrite(pin, value). Returns the set value
    <custom_command>        Execute custom command declared in the arduino sketch. Separate the command from the arguments with forward slash (ex: P13/1)
Custom commands?
Yes you can define your own commands to send to the arduinos and get an integer result :)
Here is the example sketch included:

Code: Select all

#include "Commander.h"
#include <Wire.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(2,3,4,5,6,7);

Commander i2c = Commander::init(0x04);//I2C Address

//custom i2cCommander Command Functions
int i2cP13(String command){
  int pos = command.indexOf("/");
  if(pos != -1){
    int value = command.substring(pos + 1).toInt();
    i2c.dw(13, value);
    return value;
  }
  return pos;
}

int i2cLCD(String command){
  if(Commander::countSlashes(command) < 3){
    return -1;
  }
  String args = command.substring(command.indexOf("/") + 1);
  int charPos = args.substring(0, args.indexOf("/")).toInt();
  args = args.substring(args.indexOf("/") + 1);
  int line = args.substring(0, args.indexOf("/")).toInt();
  args = args.substring(args.indexOf("/") + 1);
  lcd.setCursor(charPos,line);
  lcd.print(args);
  return 0;
}

void setup(){
  //init LCD
  lcd.begin(16,2);
  lcd.setCursor(0,0);
  lcd.print("Raspberry Pi I2C");
  lcd.setCursor(0,1);
  lcd.print(" Arduino Bridge ");
  
  //add custom commands to be called from I2C bridge
  Command_t i2cCustomCmd;//simple control of pin 13 demo
  i2cCustomCmd.execCommand = "P13";//name of the command to listen for
  i2cCustomCmd.callback = i2cP13;//function to be called when the command is received
  i2c.addCommand(i2cCustomCmd);//add it to the i2c commander
  
  Command_t i2cLCDcmd;
  i2cLCDcmd.execCommand = "LCD";//print stuff to the LCD
  i2cLCDcmd.callback = i2cLCD;
  i2c.addCommand(i2cLCDcmd);
}

void loop() {
  
}
It adds two custom commands. One for controlling Pin 13 (just sample ;) you can "write 13 1" also) and one for printing text to the attached 16x2 LCD. You can call them as follows:

Code: Select all

sudo ./i2c-arduino 4 P13/1 //set pin 13 to HIGH
sudo ./i2c-arduino 4 P13/0 //set pin 13 to LOW
sudo ./i2c-arduino 4 LCD/0/0/"I2C is AWESOME!!!" // print "I2C is AWESOME!!!" from first character on the first line of the screen
And you can add up to 16 of those to interface with attached to the arduino devices and sensors (limit can be changed but has memory impact!)

And at the end of the day you can control and monitor 127 Arduinos attached on the I2C bus :)
i2c-arduino.tar
Source
(20 KiB) Downloaded 419 times
I hope someone gets some use of it other than me :)

subnet
Posts: 39
Joined: Wed Dec 26, 2012 10:30 pm

Re: Interfacing with arduino[s] through I2C

Sun Jul 14, 2013 8:58 pm

Hello and thanks for this nice work :-)

I'm trying to use your method to interfacing Rpi & Arduino, but I have following errors...

On Arduino, when I compile (with Arduino 1.0.5 IDE) the I2C_Commander script:

Code: Select all

I2C_Commander\Commander.cpp.o: In function `Commander':
D:\Subnet\Documents\Arduino\libraries\I2C_Commander/Commander.cpp:8: multiple definition of `Commander::Commander()'
Commander.cpp.o:C:\Users\subnet\AppData\Local\Temp\build1949788161635463256.tmp/Commander.cpp:8: first defined here
I2C_Commander\Commander.cpp.o: In function `Commander':
D:\Subnet\Documents\Arduino\libraries\I2C_Commander/Commander.cpp:8: multiple definition of `Commander::Commander()'
Commander.cpp.o:C:\Users\subnet\AppData\Local\Temp\build1949788161635463256.tmp/Commander.cpp:8: first defined here
I2C_Commander\Commander.cpp.o: In function `Commander::countSlashes(String)':
D:\Subnet\Documents\Arduino\libraries\I2C_Commander/Commander.cpp:136: multiple definition of `Commander::countSlashes(String)'
Commander.cpp.o:C:\Users\subnet\AppData\Local\Temp\build1949788161635463256.tmp/Commander.cpp:136: first defined here
I2C_Commander\Commander.cpp.o: In function `Commander::aw(int, int)':
D:\Subnet\Documents\Arduino\libraries\I2C_Commander/Commander.cpp:125: multiple definition of `Commander::aw(int, int)'
Commander.cpp.o:C:\Users\subnet\AppData\Local\Temp\build1949788161635463256.tmp/Commander.cpp:125: first defined here
I2C_Commander\Commander.cpp.o: In function `Commander::dw(int, int)':
D:\Subnet\Documents\Arduino\libraries\I2C_Commander/Commander.cpp:114: multiple definition of `Commander::dw(int, int)'
Commander.cpp.o:C:\Users\subnet\AppData\Local\Temp\build1949788161635463256.tmp/Commander.cpp:114: first defined here
I2C_Commander\Commander.cpp.o: In function `Commander::ar(int)':
D:\Subnet\Documents\Arduino\libraries\I2C_Commander/Commander.cpp:110: multiple definition of `Commander::ar(int)'
Commander.cpp.o:C:\Users\subnet\AppData\Local\Temp\build1949788161635463256.tmp/Commander.cpp:110: first defined here
I2C_Commander\Commander.cpp.o: In function `Commander::dp(int)':
D:\Subnet\Documents\Arduino\libraries\I2C_Commander/Commander.cpp:105: multiple definition of `Commander::dp(int)'
Commander.cpp.o:C:\Users\subnet\AppData\Local\Temp\build1949788161635463256.tmp/Commander.cpp:105: first defined here
I2C_Commander\Commander.cpp.o: In function `Commander::dr(int)':
D:\Subnet\Documents\Arduino\libraries\I2C_Commander/Commander.cpp:100: multiple definition of `Commander::dr(int)'
Commander.cpp.o:C:\Users\subnet\AppData\Local\Temp\build1949788161635463256.tmp/Commander.cpp:100: first defined here
I2C_Commander\Commander.cpp.o: In function `Commander::addCommand(Command_t)':
D:\Subnet\Documents\Arduino\libraries\I2C_Commander/Commander.cpp:64: multiple definition of `Commander::addCommand(Command_t)'
Commander.cpp.o:C:\Users\subnet\AppData\Local\Temp\build1949788161635463256.tmp/Commander.cpp:64: first defined here
I2C_Commander\Commander.cpp.o: In function `Commander::sendResult()':
D:\Subnet\Documents\Arduino\libraries\I2C_Commander/Commander.cpp:84: multiple definition of `Commander::sendResult()'
Commander.cpp.o:C:\Users\subnet\AppData\Local\Temp\build1949788161635463256.tmp/Commander.cpp:84: first defined here
I2C_Commander\Commander.cpp.o:(.bss.pt2Object+0x0): multiple definition of `pt2Object'
Commander.cpp.o:(.bss.pt2Object+0x0): first defined here
I2C_Commander\Commander.cpp.o:(.bss.outBuffer+0x0): multiple definition of `outBuffer'
Commander.cpp.o:(.bss.outBuffer+0x0): first defined here
I2C_Commander\Commander.cpp.o: In function `Commander::processCommand(String)':
D:\Subnet\Documents\Arduino\libraries\I2C_Commander/Commander.cpp:23: multiple definition of `Commander::processCommand(String)'
Commander.cpp.o:C:\Users\subnet\AppData\Local\Temp\build1949788161635463256.tmp/Commander.cpp:23: first defined here
I2C_Commander\Commander.cpp.o: In function `Commander::receiveCommand(int)':
D:\Subnet\Documents\Arduino\libraries\I2C_Commander/Commander.cpp:74: multiple definition of `Commander::receiveCommand(int)'
Commander.cpp.o:C:\Users\subnet\AppData\Local\Temp\build1949788161635463256.tmp/Commander.cpp:74: first defined here
I2C_Commander\Commander.cpp.o: In function `Commander::init(int)':
D:\Subnet\Documents\Arduino\libraries\I2C_Commander/Commander.cpp:14: multiple definition of `Commander::init(int)'
Commander.cpp.o:C:\Users\subnet\AppData\Local\Temp\build1949788161635463256.tmp/Commander.cpp:14: first defined here
On Rpi, when I do:

Code: Select all

cc -o i2c-arduino i2c-arduino.c
I have this:

Code: Select all

cc -o i2c-arduino i2c-arduino.c
In file included from i2c-arduino.c:39:0:
/usr/include/linux/i2c.h:67:8: error: redefinition of 'struct i2c_msg'
/usr/include/linux/i2c-dev.h:38:8: note: originally defined here
/usr/include/linux/i2c.h:125:7: error: redefinition of 'union i2c_smbus_data'
/usr/include/linux/i2c-dev.h:90:7: note: originally defined here
Is my fault? What I'm missing?

Thanks in advance for your help

Return to “Interfacing (DSI, CSI, I2C, etc.)”