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.


