I2C with Raspberry Pi, MCP23017 and Arduino: Part 2

In Part 1 I described how to connect the Raspberry Pi, MCP23017 and Arduino to the same I2C bus. In this part I’ll show you how to control a servo from the Pi via an Arduino over I2C.

To clarify you don’t need the MCP23017 to be present for this circuit to work, its just there to demonstrate having multiple devices on the I2C bus.

I’ve connected a cheap Chinese servo from eBay up to the Arduino. Its hooked up to pin 9 (PWM enabled) and the 5v+gnd rails on the breadboard.
On the Arduino I’m running the sketch below, it listens for events over I2C on address 0×03. If it receives 2 bytes, the first of which is 1 (servo identifier) it moves the servo to the position specified in the second byte.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include Wire.h
#include Servo.h
 
Servo myservo;
 
void setup() {
  Wire.begin(3);  // address 0x03
  Wire.onReceive(receiveEvent);
  myservo.attach(9); //  pin 9
}
 
void loop() {
  delay(100);
}
 
void receiveEvent(int Size) {
  if (Size == 2) {
    int a = Wire.read();
    int b = Wire.read();
    if (a == 1) {
     myservo.write(b);
    }
  }
}

Running on the Raspberry Pi is a tiny Python script that takes a number from a user and sends it to the Arduino over I2C. This uses the Python SMBUS library, available in Debian / Raspbian (via the python-smbus package).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#! /usr/bin/python
import smbus
bus = smbus.SMBus(0)
 
address = 0x03
 
while True:
 pos = None
 try:
  pos=int(raw_input('Position: '))
 except ValueError:
   print "Not a number"
 if pos != None:
  bus.write_byte_data(address,0x01,pos)

Here’s a video of it in action:

In part 3 I’ll look at how to send values (such as temperatures) from the Arduino back to the Raspberry Pi over I2C.

I2C with Raspberry Pi, MCP23017 and Arduino: Part 1

This week I’ve been trying to get a Raspberry Pi on the same I2C bus as both an MCP23017 I/O Expander and an Arduino.

There are already lots of tutorials online for hooking up your Raspberry Pi to an MCP23017 (such as Nathan Chantell’s), but I couldn’t find any using I2C to connect the Pi and Arduino, only via the USB which I’d rather not do.

The I2C lines on Pi run at 3.3v, to safely connect these to multiple 5v I2C slaves the levels need changing, to do this I built a bi-directional level shifter using a pair of 2N7000 MOSFETs.

Below you can see the circuit laid out in Fritzing, a 10k pull-up resistor is used on each of the 3.3 and 5v SDA and SCL lines.

Using i2cdetect on the Pi you can see the MCP23017 at 0×20 and the Arduino on address 0×03:

nat@pi1 ~ $ i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          03 -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

To push this a little further I attached a Nanode to the same bus on 0×04…

And it also appeared on the bus:

nat@pi1 ~ $ i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          03 04 -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

In the next part I’ll post code samples for the both the Raspberry Pi and Arduino showing how to send values back and forth using I2C. Part 2

New start

Finally got around to moving the odd bits of content off my old homepage and setup a blog, various people have been nagging for me to write about what I get up to, so I thought I might as well give it a go.

Over the next couple of week I’m planning on writing about how I’ve redesigned the integration behind Feedtoby and also my adventures with the Raspberry Pi.