General Servo questions

Hello everybody, sorry if I mess up, I am new to Arduino!

So, for Science Olympiad in my school, we must build a robot that can move items and what not, and must be controlled without any wires to the robot.

Instead of using the kits that are left over from last year, I decided that I wanted to use an Arduino Uno microcontroller I had lying around to handle the servos. So, I am using Vex 2-wire servos, and Motor Controller 29 (an H-bridge) from Vex, and can't figure out the following:

  • How to change the speed it's rotating at
  • How to change direction

I have never played with a continuous servo before, so it's very confusing.
I am going to be using a nunchuk (this library: http://www.gabrielbianconi.com/arduinonunchuk/) to control it.
The robot will have 4 wheels, and it needs to be able to turn. A friend of mine kindly made me a table of what the robot should do at certain positions on the joystick.

The only thing I need to do now is fill in the blanks, so turn right I'd need to make the front right wheel go slightly faster depending on the joysticks position. Can anyone please give me some advice as where to start?

I would make a simple robot that can only go forwards and backwards first, but I can't figure out how to change direction or speed!

Here are the things I have to work with as of now:

I also had an idea that most likely would not work, but I was wondering how difficult it would be to drive all these servos through one of these signal splitters: http://www.vexrobotics.com/276-2217.html

Thank you for taking the time to read this, any help is greatly appreciated.

I have just tried this example: Servo - Arduino Reference

It says, "On a continuous rotation servo, this will set the speed of the servo (with 0 being full-speed in one direction, 180 being full speed in the other, and a value near 90 being no movement). ", but this is not the case for the Vex servo. 0, 90, 180, they all keep the motor still. Nothing will turn it unless it's a for loop inside of the loop method. What do I do?

Okay! Progress! I got this code, the servo changes speed and direction with the analog x from nunchuk!

#include <Wire.h>
#include <ArduinoNunchuk.h>

#define BAUDRATE 19200
ArduinoNunchuk nunchuk = ArduinoNunchuk();

#include <PWMServo.h> 
 
PWMServo myservo;  // create servo object to control a servo 

int val;    // variable to read the value from the analog pin 
 
void setup() 
{ 
  Serial.begin(BAUDRATE);
  nunchuk.init();
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
} 
 
void loop() 
{ 
  nunchuk.update();
  val = nunchuk.analogX;
  int scaled = map(val, 18, 199, 20, 140);
  Serial.println(scaled);

myservo.write(scaled);
  
  delay(15);                           // waits for the servo to get there 
}

Now I need some help with controlling 4 servos to make it work like a car.

Here is the chart my friend made for me, this is what the car should do when the joystick is at certain positions:

Soo… now I need some help with logic. I need to speed up certain servos and not others at different positions. Once again, thanks for reading!

Hi there

I have recently purchased an Arduino Uno board and have read as much as i can find on servo control. I have also added some files to my library with no success.

Does anyone have any code that will allow me to control 4 standard servo motors at different times. This is the ‘sweep’ servo control code below that came with the Uno…

// Sweep
// by BARRAGAN http://barraganstudio.com
// This example code is in the public domain.

#include <Servo.h>

Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created

int pos = 0; // variable to store the servo position

void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}

void loop()
{
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
}
}

Any advice that anyone can offer would be greatly appreciated as I am extremely green when it comes to code.

Kind regards

Steve

If you only want to move one servo at a time then you can use the blocking approach used in that example, where the sketch waits for each sequence of movements to complete for the current servo before it does anything else. This is a very limiting approach but might be sufficient for you.

If you need to be able to move multiple servos at the same time, or do anything else while you're moving a servo, you should consider using a non-blocking approach. This approach is demonstrated in the 'blink without delay' example sketch, but in this case instead of turning an LED on or off you'd be moving a servo.

There is no problem independently controlling each and every servo as you please, the servo library allows such. However the problem with your posted example if applied to a multi-servo project is the use of the delay() in the main flow of the sketch. Such a function is called a 'blocking' function and it would effect all servo commands as nothing else can be accomplished while the delay() function is 'counting time'.

You need to utilize the arduino build in timing functions millis() and micros() to allow program flow to continue even while a given servo is not yet ready to be commanded to a new position.

Lefty

Thanks Lefty and PeterH...I'll look into the servo coding a little more then attempt to wire up my first breadboard...servos arriving tomorrow...it's to make an animatronic eyes so think I will need 4 servos in total including eyeballs and lids.

This forum is great ! XD

Cheers guys

Hi guys...

As a truly 'green' arduino uno user i have a couple of questions if possible.

Q1) When wanting to run 4 servos using my Arduino Uno micro-controller board do i need to use a 'shield' (Link below) and power it seperately to have enough power to power the board and servos and will this limit the amount of servos i can run (heard it might be limited to 2)?

http://www.maplin.co.uk/arduino-motor-shield-r3-613016

Q2) Do i need or is it better to get a servo controller kit (link below) and if so will it run 4 servos or do i need 4 servo contollers ?

http://www.maplin.co.uk/servo-and-controller-board-kit-528801

I bought a breadboard, Arduino Uno and 4 servos and thought i could plug it straight in after watching some You Tube videos but think i am wrong after further research.

I found this instruction PDF below but it seems to contradict other information.....

OK ....so it's more like 10 questions crammed into two but you guys are the experts and i appreciate any advice and support you can offer.

Thanks again XD

Steve

I got what I needed done. Here is the code:

Though it is for a competition, so as the license says, if you're participating in the event... do not show up with this setup and this code.

Q1) You should be able to control up to 12 servos from your Uno without a shield, but you will need to power the servos with an external power supply similar to below.

Bottom is some servo test code you can see the differene between servo write and servo writeMicroseconds (which is better for use with continuous rotation servos).

// zoomkat 10-22-11 serial servo test
// type servo position 0 to 180 in serial monitor
// or for writeMicroseconds, use a value like 1500
// for IDE 0022 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.

String readString;
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

void setup() {
  Serial.begin(9600);
  myservo.writeMicroseconds(1500); //set initial servo position if desired
  myservo.attach(7, 500, 2500);  //the pin for the servo control, and range if desired
  Serial.println("servo-test-22-dual-input"); // so I can keep track of what is loaded
}

void loop() {
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string 
    int n = readString.toInt();  //convert readString into a number

    // auto select appropriate value, copied from someone elses code.
    if(n >= 500)
    {
      Serial.print("writing Microseconds: ");
      Serial.println(n);
      myservo.writeMicroseconds(n);
    }
    else
    {   
      Serial.print("writing Angle: ");
      Serial.println(n);
      myservo.write(n);
    }

    readString=""; //empty for next input
  } 
}

zoomkat:
Q1) You should be able to control up to 12 servos from your Uno without a shield, but you will need to power the servos with an external power supply similar to below.

Bottom is some servo test code you can see the differene between servo write and servo writeMicroseconds (which is better for use with continuous rotation servos).

// zoomkat 10-22-11 serial servo test

// type servo position 0 to 180 in serial monitor
// or for writeMicroseconds, use a value like 1500
// for IDE 0022 and later
// Powering a servo from the arduino usually DOES NOT WORK.

String readString;
#include <Servo.h>
Servo myservo;  // create servo object to control a servo

void setup() {
  Serial.begin(9600);
  myservo.writeMicroseconds(1500); //set initial servo position if desired
  myservo.attach(7, 500, 2500);  //the pin for the servo control, and range if desired
  Serial.println(“servo-test-22-dual-input”); // so I can keep track of what is loaded
}

void loop() {
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }

if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string
    int n = readString.toInt();  //convert readString into a number

// auto select appropriate value, copied from someone elses code.
    if(n >= 500)
    {
      Serial.print("writing Microseconds: ");
      Serial.println(n);
      myservo.writeMicroseconds(n);
    }
    else
    {   
      Serial.print("writing Angle: ");
      Serial.println(n);
      myservo.write(n);
    }

readString=""; //empty for next input
  }
}

Brilliant … thanks for the help…looking at attempting to wire everything up this weekend and your support with the advice and code is much appreciated to a complete beginner… :slight_smile: