Servo control with a Yún and a Pi

Lead Image © Phil Wohlrab,

In Control

We show how to wirelessly control pan/tilt servos with an Arduino Yún and a Raspberry Pi.

A while back, I gave a talk at Fossetcon about wirelessly controlling pan/tilt servos running on an Arduino Yún [1]. The on-screen sliders worked on a Linux notebook with code written using the Processing language [2]. So, I asked myself, "Could a Raspberry Pi replace the notebook for this job?"

It turns out that moving the Processing code over to a Pi is fairly straightforward. However, there are plenty of moving parts, even for a simple multidevice "system" like this one, and making the pieces all work right together can be a challenge.

The major components of this project include the Arduino Yún, its servos, and the Arduino code needed to interpret the data sent from the Raspberry Pi. There's also the Raspberry Pi hardware and its Processing code used to display and manage the sliders, the local area network (LAN) needed to connect the two parts together, and, finally, the Linux notebook used to program the Yún, which I'll explain in a minute.

I'll start with the Arduino Yún, then talk about what's needed with the Raspberry Pi, and finish up with some challenges and enhancements you can make to your own project.

Prep the Yún

The Yún is a unique beast in the Arduino world. It has two processors. The AR 9331 chip runs an ultra-small version of Linux handling the WiFi connection and a few other tasks. The ATmega 32u4 chip takes care of the traditional super-fast, microcontroller input/output and functions similar to an Arduino Leonardo. They are tied together by the "bridge library" that allows the two processors to interact with each other. The bridge library connects the servos to the network.

I chose to keep the programming of the Yún on the Linux laptop for this project instead of doing everything on the Pi. The default Arduino IDE for my version of Raspbian Linux (on the Pi) is stuck at 1.0.1. You need at least version 1.5.4 to be able to upload firmware with the Yún's WiFi capability. Working it this way makes it easy to troubleshoot the Arduino code and upload it over the air, right into the Yún.

Although it might be interesting to program the Yún from the Pi, getting a project working quickly is important for your motivation and "fun factor." Get a minimum viable project going, then expand the complexity as you see fit. Remember, parts left out cost nothing and cause few maintenance problems.

On the notebook, I started the Arduino IDE with the following, from a terminal.

rob-notebook%  cd arduino-1.5.7
rob-notebook% ./arduino

The IDE then loads, and you can copy the code from Listing 1.

Listing 1

Arduino Yún Servo Control Code

01 // Arduino servo control code //
02 #include <Bridge.h>
03 #include <YunServer.h>
04 #include <YunClient.h>
05 #include <Console.h>
06 #include <Servo.h>
07 #define PORT 6666
08 Servo servo1;
09 Servo servo2;
10 YunServer server(PORT);
11 YunClient client;
13 void setup() {
14   Bridge.begin();
15   servo1.attach(9); //pwm pin 9
16   servo2.attach(11); //pwm pin 11
17   server.noListenOnLocalhost();
18   server.begin();
19   Console.begin();
20   Console.println("Console Connected");
21 }
23 void loop() {
24   static int v = 0;
25   char ch;
26   client = server.accept();
27   if(client.connected()){
28     Console.println("Client Connected");
29     while(client.connected()){
30       if(client.available()){
31         ch =;
33         switch(ch) {
34           case '0'...'9':
35             v = v * 10 + ch - '0';
36             break;
37           case 'a':
38             // send 'a' to control pan servo1
39             servo1.write(v);
40             Console.print(v);
41             Console.println("a");
42             v = 0;
43             break;
44           case 'b':
45             // send 'b' to control tilt servo2
46             servo2.write(v);
47             Console.print(v);
48             Console.println("b");
49             v = 0;
50             break;
51           }
52       }
53     }
54     client.stop();
55   }
56 }

Make sure the following libraries are present; otherwise, you won't be able to compile the code:

  • Bridge.h
  • YunServer.h
  • YunClient.h
  • Console.h
  • Servo.h

The code consists of the usual variable definitions and initializations, a setup section, and the main loop. I've included some "Console" lines to help with debugging and to let you see the data coming in from the Processing/Raspberry Pi code.

The logic of the Yún code is pretty straightforward. A client instance is opened, and while it's connected to the Raspberry Pi client code, it reads in characters and interprets the results.

If the character is a digit from 0 to 9, it stores the number. When either an a or b comes along, it directs the servo to the desired location. Because this is a basic "minimum viable" project, there's no error or range checking, failover, or security code baked into the program.

The program then just sits in a loop until the next set of characters come through. Be sure to upload the Yún code using the Arrow button, in the IDE. Check that you have the Yún board selected under the Tools | Board tab, if you have troubles uploading. You might also need to check the Tools | Port tab and make sure it's pointing to the IP address of the Yún and not the USB port.

A couple of things might trip you up in the code. To avoid trouble, make sure the IP address and PORT number in the code matches whatever you use in the Processing code on the Raspberry Pi. Also, make sure that your servo data connections go to the right connections on the Yún.

As far as the actual Yún hardware goes, I powered the servos from the 5V header on the board itself. Keep in mind that I was using tiny little nano-RC servos, so the current draw was pretty modest. Going with larger servos will require having their own dedicated power supply. The Yún won't be able to supply the current needed and will be unstable because of noise created by servo operation. They are electric motors, after all.

I used a breadboard to hook the servos to the Yún. Figure 1 shows the Yún/servo test rig I modded from a previous Steampunk Eye project (Figure 2), which ran an Arduino Duemilanove. The breadboard is easily eliminated with a little creative wiring harness design of your own.

Figure 1: Servo test rig.
Figure 2: Steampunk Eye project.

Other than that, wiring the servos is pretty basic. Take a look at Figure 3 for the layout.

Figure 3: Wiring layout.

Put Processing on the Pi

I already had the slider code (Listing 2) working on my Linux notebook, so most of the work porting it over involved installing Processing on the Pi. The controlP5 [3] library, which is used to display the sliders, also has to be installed. Finally, the slider code has to be moved over from the notebook.

Listing 2

Slider Control Processing Code

01 // Slider control Processing code //
02 /**
03  * ControlP5 Slider
04  * by andreas schlegel, 2010
05  *
06 **/
07 import*;
08 import controlP5.*;
09 Client c;
10 ControlP5 cp5;
11 int pan = 10;
12 int tilt = 10;
13 int ptmp = pan;
14 int ttmp = tilt;
16 void setup() {
17   size(500,500);
18   noStroke();
19   c = new Client(this, "", 6666);
21   cp5 = new ControlP5(this);
23   // add a horizontal slider for pan
24   cp5.addSlider("pan")
25      .setPosition(50,70)
26      .setSize(300, 30)
27      .setRange(0,180)
28      .setValue(58)
29      ;
31   // add a vertical slider for tilt
32   cp5.addSlider("tilt")
33      .setPosition(150,130)
34      .setSize(30, 300)
35      .setRange(180, 0)
36      .setValue(58)
37      ;
38 }
40  void draw() {
41  //Output the servo position (from 0 to 180)
42  // "a" corresponds to servo1
43  // "b" corresponds to servo2
44      if (pan != ptmp){
45         c.write(pan + "a");
46         // println(pan);
47         ptmp = pan;
48      }
49      if (tilt != ttmp){
50         c.write(tilt + "b");
51         // println(tilt);
52         ttmp = tilt;
53      }
54  }

Installing the Processing language on the Raspberry Pi only takes a few commands. My Pi is running Raspbian Linux version 2.2.1. From a terminal, type:

rob-pi%  cd ~
rob-pi%  sudo apt-get install processing

Next, apt-get will do its thing and after a few minutes, you can bring up the Processing IDE. While still in the terminal, check that Processing runs correctly by typing the following:

rob-pi%  cd processing-2.2.1
rob-pi%  ./processing

Because I developed the code on the Linux notebook, the easiest way to move the code was with rcp [4]. Just find the directory that houses your code and send it over to the Raspberry Pi. Here's the command line I used:

rob-pi%  rcp servo4_processing2.pde \

Enter your Rasp Pi's password, if needed. You might have to make adjustments if you stored the Processing code in a different directory. Also, you'll need to know the IP address of the Raspberry Pi. In a terminal on the Pi, use the ifconfig command:

rob-pi%  ifconfig

An IP address will appear on the inet addr: line in the eth0 section if the Rasp Pi is connected properly. If your Pi is connected via WiFi, the IP address will show up in the wlan0 section.

To be able to use the slider program on the Pi, the controlP5 contributed library must also be installed. Download it [3]; then, in a terminal, type the following:

rob-pi%  mv \
rob-pi%  cd sketchbook/libraries
rob-pi%  unzip

Make sure to change the IP address in the Processing code to match your Yún's setup. In my case, the Yún had an IP of and the Pi had My Linux notebook was set to Also, note that I used 6666 for the port number, which deviates from the standard port used in the ControlP5 examples.

Buy this article as PDF

Express-Checkout as PDF

Pages: 6

Price $2.95
(incl. VAT)

Buy Raspberry Pi Geek

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content