Multi Servo Control from Computer

In response to a request, I have created a program which allows for multi servo control through Processing. Connect two servo’s to pins 9 and 10 of your Arduino, as shown in my previous blog post, wich has got much more information on using potentiometers: Servo_control_via_potentiometer. You will also need to ensure you have the Servo library for Arduino (again more is detailed in my last blog post).

To control servo’s using your computer, you will need to use Processing. This is an incredibly useful java based programming language, wich makes it really easy to communicate with the Arduino. You can find out more at processing.org .

Connecting your Arduino to a computer is as simple as plugging it in to a USB port. Then, when you load the processing file below, look in the black box at the bottom of the screen to see a list of ports available on your computer, and which one the Arduino is using, then change the number in Serial.list()[0] to match whatever port is being used.

 

import processing.serial.*;

Serial myPort;  // Create object from Serial class

PFont f;

void setup() {
  size(640, 130);
  
  println(Serial.list());
  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 9600);
  
     f = createFont("Times New Roman",16,true);
     
}

void draw() { 
  fill(95);
  textFont(f, 16);
  text("Control Two Servo, switch between then using the number 1 and 2 keys on your keyboard", 10, 30);
  text("Use the L key to rotate the servo 90' left, and the R key to rotate it 90' Right", 10, 60);
  text("Use the S key to return to the center", 10, 90);
}

void keyPressed() {
  
  switch (key) {
    case 'a':
      println("A pressed");
      myPort.write('l'); //turns left
      break;
    case 's':
      println("S pressed");
      myPort.write('s'); //stops turning
      break; 
    case 'd':
      println("D pressed");
      myPort.write('r'); //turns right
      break;     
    case '1':
      println("Using servo 1");
      myPort.write('1'); //controlling servo 1
      break;
    case '2':
      println("Using servo 2");
      myPort.write('2'); //controlling servo 2
      break;
    default:  
      break;
  }
}

 

It is then time to upload the Arduino code. Ensure that you are not running the Processing file whilst uploading the code, or the upload may fail, as the Arduino can only communicate with one srial device at a time. After uploading, quit the Arduino IDE before starting the Processing file.
 

// Controlling two servo positions using a processing file
//Created by Jacob Unwin - http://www.jacob-unwin.com

#include <Servo.h>
 
Servo myservo_one;  // create servo object to control a servo
Servo myservo_two;
 
char val;
 
void setup()
{
  myservo_one.attach(9);  // attaches the servo on pin 9 to the servo object
  myservo_two.attach(10); //attaches the 2nd servo on pin 10
 
  myservo_one.write(90); //sets both servo's at 90 degrees
  myservo_two.write(90); 
 
  Serial.begin(9600); //start serial output at 9600
}
 
void loop()
{
  
  if(Serial.available()){
    val = Serial.read();
    
    if (val == '1'){ //if 1 has been pressed, current servo is 1
      currentServo == 1;
    } else if (val == '2'){ //else if 2 has been pressed, current servo is 2
      currentServo == 2;
    }
    
    if (val == 'l') { //if the last key press was l, rotates to 0 degrees
       if (currentServo == 1){
         myservo_one.write(0);
       } else {
         myservo_two.write(0);
       }
    }
    
    if (val == 'r') { //if the last key press was r, rotates to 180'
      if (currentServo == 1){
         myservo_one.write(180);
       } else {
         myservo_two.write(180);
       }
    }
    
    if (val == 's') { //if the last key press was s, returns to the center
      if (currentServo == 1){
         myservo_one.write(180);
       } else {
         myservo_two.write(180);
       }
    }
  
 
}

 

To control the servo, first select wether you want to control servo one or two by pressing the 1 or 2 keys on your keyboard. Then you can rotate the servo left (to 0 degrees) using the L key, to the center (90 degreed) using the S key, and to the right (180 degrees) using the D key. This code could be further modified to add more servo’s, and create a more accurate rotation, i.e. with each key press moving the servo by only 1 degree.

Servo Control via Potentiometer

This tutorial explains how to directly interface with a servo via a potentiometer, using an Arduino. It ensures that the input and output are calibrated correctly, so that the servo and potentiometer remain in sync, and allows you to view readings through a serial viewer. When writing this code, I used extracts from the calibrate example in the Arduino library, and code from the Michal Rinott tutorial on the arduino.cc site.

In case you didn’t know, a potentiometer is a variable resistor, which can be used to adjust a power output according to how far open / closed it is. With the Arduino you can read this change as an analog input, allowing for high control over inputs. I used a potentiometer from spark fun. It is actually called a Trimpot, but this is basically just a really small potentiometer. You could use a bigger one if you prefer.  On the potentiometer you should have three pins, to wire it up, connect the left hand pin to the 3.3v power supply on the Arduino. Then connect the centre pin to analog pin 1 (A1) on your Arduino, and the right hand pin to the ground pin on the Arduino (place a 330 ohm resistor in-between the right hand pin and the ground pin).

Using this code, you should be able to read the analog output of the potentiometer in a serial viewer.

//Reading the value of a potentiometer and displaying it on a serial output
//Created by Jacob Unwin, using code from Michal Rinott tutorial

int sensorValue = 0;         // the sensor valueint sensorMin = 1023;        // minimum sensor value
int sensorMax = 0;           // maximum sensor value
int sensor = 1;  // analog pin used to connect the potentiometer

void setup()
{

  Serial.begin(9600); //start serial output

}

void loop()
{
  sensorValue = analogRead(sensor);            // reads the value of the potentiometer (value between 0 and 1023)
  Serial.print(sensorValue);  //print the servo value in degrees in the serial monitor
  Serial.println();

}

Now its time to wire up the servo. This is more complicated, as it needs an external power supply to ensure you don’t burn out your Arduino. You will need a switch, a 6v power pack (a set of 4 aa batteries in a holder will do), and a smallish servo. Plug the battery back into the switch, so that you can use it to turn the battery pack on and off. Alternatively you could just unplug the battery pack each time you wan’t to turn off the Arduino. You will find 3 coloured wires coming out of the servo. Connect the red one to the power packs positive wire (probably red), and connect the black wire to the ground strip on your breadboard. To the same ground strip connect a ground wire to the Arduino, and another to the power pack. Whilst you are doing this, make sure the power pack is turned off. Finally, connect the white or yellow wire on the servo to pin 9 on the Arduino. This is the control wire, which we will use to control the rotation of the servo.

 

 

I also connected an additional momentary push button to my Arduino, which allows for the device to be re-calibrated whilst in use. You’d don’t need to do this, it is just personal preference. Connect the left hand pin to the 3.3v power supply,and the right hand pin of the button to pin 7 on the Arduino and to the Arduino’s ground pin (via a 330 ohm resistor).

To use this code, you will need to download and install the Servo library.

If it is wired up correctly, plug in the Arduino, turn on the power pack, and then upload the code. The servo should move in sync with the potentiometer.

 
// Controlling a servo position using a potentiometer (variable resistor)
// Added callibration function to ensure accurate control of servo
// Written by Jacob Unwin, code used from Michal Rinott tutorial

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int sensorValue = 0;         // the sensor value
int sensorMin = 1023;        // minimum sensor value
int sensorMax = 0;           // maximum sensor value

int sensor = 1;  // analog pin used to connect the potentiometer
int button = 7;

int buttonVal = 0; // sets the value
int state = 0; //sets the state
int old_val = 0; //stores the previous value

void setup()
{
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  pinMode(button, INPUT); //sets the button as an input

  myservo.write(180);

  // calibrate during the first five seconds
  while (millis() < 5000) { //for the first five seconds
    sensorValue = analogRead(sensor);

    // record the maximum sensor value
    if (sensorValue > sensorMax) {
      sensorMax = sensorValue;
    }

    // record the minimum sensor value
    if (sensorValue < sensorMin) {
      sensorMin = sensorValue;
    }
  }

  // signal the end of the calibration period
  myservo.write(0);

  Serial.begin(9600); //start serial output
}

void loop()
{
  buttonVal = digitalRead(button);
  sensorValue = analogRead(sensor);            // reads the value of the potentiometer (value between 0 and 1023)
  sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 179);     // scale it to use it with the servo (value between 0 and 180)
  myservo.write(sensorValue);                  // sets the servo position according to the scaled value
  sensorValue = constrain(sensorValue, 0, 179); //in case the sensor value is outside the range seen in callibration
  delay(15);                           // waits for the servo to get there

  Serial.print("servo = " );
  Serial.print(sensorValue);  //print the servo value in degrees in the serial monitor
  Serial.println();

  if((buttonVal==HIGH) && (old_val==LOW)){ //checks if there was a transition between old and new val
  state = 1 - state; //sets the state
  delay(10); //sets a delay of 10
}

old_val = buttonVal; //stores the new value as the old value

if (state==1) {

  calibrate();
}

}

void calibrate(){

  myservo.write(180);

  // calibrate during the first five seconds

    sensorValue = analogRead(sensor);

    // record the maximum sensor value
    if (sensorValue > sensorMax) {
      sensorMax = sensorValue;
    }

    // record the minimum sensor value
    if (sensorValue < sensorMin) {
      sensorMin = sensorValue;
    }

  // signal the end of the calibration period
  myservo.write(0);

  delay (2000);

}