Sunday, June 23, 2013

Connecting Raspberry Pi and Arduino. Software

In my previous post I described how to make hardware connection between Raspberry Pi and Arduino. Now I will describe the software part. I will describe how to make software connection from scratch pretty easily. And I will use some C and C#.

Raspberry Pi

I use Arch Linux on my Raspberry Pi (more lightweight and appropriate distributive for this computer to my mind). But I2C drivers work the same way on other distributives, so, only some system specific commands could be different.

1. Update your system. I2C drivers were released in Fall 2012, so if your system is old enough do this
$ pacman -Syu

2. Load I2C kernel module:
$ modprobe i2c-dev
To load the module automatically on boot, create file /etc/modules-load.d/i2c.conf and add line i2c-dev to the file.

3. Check I2C works. Run
$ i2cdetect 1
Where 1 is the number of I2C bus. The command should output table with addressed of all connected devices. But for now that table is empty as far as we haven't initialized the Arduino as an I2C slave.

Arduino

To work with I2C on Arduino you can use the standard library Wire. The code below initializes the I2C bus, reads sending data and sends data back.
#include <Wire.h>

void setup()
{
  Serial.begin(115200);          // start serial for output
  Wire.begin(42);                // join i2c bus with address #42
  Wire.onReceive(receiveData);
  Wire.onRequest(sendData); 
}

void loop()
{
  delay(100);
}

// callback for received data
void receiveData(int byteCount) 
{
  while(Wire.available())       // loop through all but the last
  {
    char c = Wire.read();       // receive byte as a character
    Serial.print(c);            // print the character
  }
}

// callback for sending data
void sendData()
{ 
  Wire.write (79);
}
After uploading this code to Arduino we can get back to the Raspberry Pi.

Raspberry Pi again

Now, after initializing the Arduino, i2cdetect command should show you that a device with address 42 is connected to the I2C bus. If that works, it's time to send some data from Raspberry Pi. I'm a dotNET guy, and I will use C# and Mono. And to work with I2C I use my library RPi.I2C.Net. The code below is the simple application to send and read data from the Arduino.
static void Main(string[] args)
{
 using (var bus = RPi.I2C.Net.I2CBus.Open("/dev/i2c-1"))
 {
  bus.WriteBytes(42, new byte[] { 49, 50, 51 });
  byte[] res = bus.ReadBytes(42, 1);
  Console.WriteLine(res[0]);
 }
}
Now it's time to create more complex communication.

Saturday, June 22, 2013

Connecting Raspberry Pi and Arduino. Hardware

Though you can control peripheral hardware using Raspberry Pi's GPIO (general ports for input/output), I prefer to do that using an array of Arduino. The advantages are:
  • No limitation in ports. You can always use Arduino Mega, or even use an array of them.
  • Physical separation of controller and Arduino.
  • It's not that scary to burn another Arduino for $10 rather than Raspbery Pi for $35.
And the most effective way to connect several Arduino and Raspberry Pi is I2C (or I2C to be precise). You need only 3 wires (4 in practice) to connect even several Arduino.

So the general connection schema using I2C looks like this:


Unfortunately, you cannot insert wires from Arduino to Raspberry Pi. The problem is the I2C bus does not strictly specify the signal levels. As a result we have 5V for Arduino's I2C implementation, and 3.3V for Raspberry Pi's one. And if you connect the I2C pins directly, you're in great danger of burning your Raspberry Pi (or at least part of it). So we have to use an I2C bridge, or level shifter. You can buy a ready one or create you own, as I did. And the schema for the bridge is pretty simple:

It requires 4 N-channel MOSFETs (I used BS170) and 4 pull-up resistors (10K each). Another important moment is Arduino and Raspberry Pi need to have the common ground. So simply join the ground pins (and that would the the fourth required wire I was talking about earlier).

After soldering I got this:


And the common connection scheme using the I2C bridge now looks like:


Scheme of pins for Raspberry Pi can be found here. And for Arduino SDA is A4, SCL is A5.

That's it with the hardware part. In this post I describe the software part of connecting Arduino and Raspberry Pi.