Manual Control of a Servo on the Arduino for the Zipwhip TextSpresso Machine


Control a servo without using the Arduino servo library.

The Arduino has a great servo library, but we found while making our TextSpresso machine that the servo library wouldn’t play nice with our stepper motors. We happily connected our stepper motors up to pins 2 through 9 because we were using a stepper motor shield. Then we connected the servos to much higher pin numbers like 26 and 27. To our dismay whenever we sent commands to the steppers, it would cause massive gyrations on the servos.

This had us investigate what was going on and to do that we had to dig under the covers of the servo library. Not many newbies know about the timer capabilities of the Arduino. The servo library hides us from the gory details. Well, it turns out that the servo library relies on a timer callback to get the precision control of the servos. This callback means the Arduino can’t be processing any other code at the exact moment the callback occurs. If the Arduino is busy, then all hell breaks lose on the exact timing of pulses being sent to the servo.

Servos expect a 20 millisecond (ms) pulse. To set the servo at 0 degrees, you send it a high voltage for the 1st ms of the 20 ms pulse. To set the servo at 180 degrees, you send it a high voltage for the 1st 2 ms of the 20 ms pulse. Pretty easy actually. Anywhere in between 1.0 ms and and 2.0 ms gives you different degrees between 0 and 180.

We wrote the sample code below to help you manually control your servo. It just takes a millisecond value and sends it to the servo and then pauses for the remainder of the pulse. I’m actually not sure why the Arduino IDE doesn’t give a manual example like this because it’s so easy to do. We couldn’t find any sample code on the Internet either for “manual servo control on the Arduino”. We hope you find this helpful.

// Manual servo control 
// Copyright 2012 by Zipwhip. 
// You are free to use and modify this code in your own software.

#define SERVO_PIN         39  // Any pin on the Arduino or Mega will work.

void setup()
{
  pinMode(SERVO_PIN, OUTPUT);

}

int lenMicroSecondsOfPeriod = 20 * 1000; // 20 milliseconds (ms)
int lenMicroSecondsOfPulse = 1.8 * 1000; // 1.0 ms is 0 degrees

void loop()
{

 // Servos work by sending a 20 ms pulse.  
 // 1.0 ms at the start of the pulse will turn the servo to the 0 degree position
 // 1.5 ms at the start of the pulse will turn the servo to the 90 degree position 
 // 2.0 ms at the start of the pulse will turn the servo to the 180 degree position 
 // Turn voltage high to start the period and pulse
 digitalWrite(SERVO_PIN, HIGH);

 // Delay for the length of the pulse
 delayMicroseconds(lenMicroSecondsOfPulse);

 // Turn the voltage low for the remainder of the pulse
 digitalWrite(SERVO_PIN, LOW);

 // Delay this loop for the remainder of the period so we don't
 // send the next signal too soon or too late
 delayMicroseconds(lenMicroSecondsOfPeriod - lenMicroSecondsOfPulse); 

}

Manually Sweeping the Servo from 0 to 180 Degrees

Taking the example above further and trying to mimic the Arduino sample sweep code for a servo we produced the test code below. This let us fully test our manual control of the servo. We found that for our HiTec HS-422 servo that the 0 degree position was at about a 0.5 ms pulse and that the full 180 degrees was around a 2.2 ms pulse. You may find something different for your servo but you can adjust the control variables in the code below until you’re happy.

We also found that a pulse length of about 25 ms worked better for our servo. The standard is 20 ms so I’m not surprised we found something a bit longer than the expected pulse worked better. When we went shorter on the pulse like 18 ms we found the servo acted really weird. That’s probably because the voltage was getting applied prior to the servo finishing it’s measurements and that would throw off pulse lengths overall.

// Manually Sweeping the Servo from 0 to 180 Degrees
// Copyright 2012 by Zipwhip.
// You are free to use and modify this code in your own software.

#define SERVO_PIN         39  // 26 or 39. Any pin on the Arduino or Mega will work.

int lenMicroSecondsOfPeriod = 25 * 1000;       // 25 milliseconds (ms). found much better smoothness at 25, not 20 ms.
int lenMicroSecondsOfPulse = 0;                // used in the while loop below
int lenMicroSecondsOfPulseStart = 0.5 * 1000;  // 0 degrees
int lenMicroSecondsOfPulseEnd = 2.2 * 1000;    // 180 degrees
int lenMicroSecondsOfPulseStep = 0.01 * 1000;   // .1 millisecond. That's 200 increments b/w 1.0 and 2.0

void setup()
{
  pinMode(SERVO_PIN, OUTPUT);

  // Setup our start point for our main loop
  lenMicroSecondsOfPulse = lenMicroSecondsOfPulseStart + lenMicroSecondsOfPulseStep;

}

void loop()
{

 // Servos work by sending a 20 ms pulse.
 // 1.0 ms at the start of the pulse will turn the servo to the 0 degree position
 // 1.5 ms at the start of the pulse will turn the servo to the 90 degree position
 // 2.0 ms at the start of the pulse will turn the servo to the 180 degree position

 // Do a while loop starting at our start pulse and incrementing each time thru the loop
 // Stop when we reach our final end point
 while (lenMicroSecondsOfPulse = lenMicroSecondsOfPulseStart)
 {
   // Turn voltage high to start the period and pulse
   digitalWrite(SERVO_PIN, HIGH);

   // Delay for the length of the pulse
   delayMicroseconds(lenMicroSecondsOfPulse);

   // Turn the voltage low for the remainder of the pulse
   digitalWrite(SERVO_PIN, LOW);

   // Delay this loop for the remainder of the period so we don't
   // send the next signal too soon or too late
   delayMicroseconds(lenMicroSecondsOfPeriod - lenMicroSecondsOfPulse); 

   // Increment our pulse
   lenMicroSecondsOfPulse += lenMicroSecondsOfPulseStep;

 }

 // Now reverse the step so we go in the opposite direction
 lenMicroSecondsOfPulseStep = lenMicroSecondsOfPulseStep * -1;
 lenMicroSecondsOfPulse += lenMicroSecondsOfPulseStep;

 // delay for a few seconds and do it all again
 delay(2 * 1000);

}

19 Responses to Manual Control of a Servo on the Arduino for the Zipwhip TextSpresso Machine

  1. raster says:

    Does this remove that spastic movement when the servo first gets power and swings one direction at full speed? If so, I’ll definitely dig into this!

  2. Pingback: Espresso machine can print text messages on coffee foam with edible ink | Jason Penna

  3. Pingback: ‘Textspresso’ machine prints texts on your espresso foam | Cheap Samsung Phones 2012

  4. Pingback: ‘Textspresso’ device prints texts on your coffee foam | Best HTC Phones 2012

  5. Pingback: ‘Textspresso’ machine prints texts on your coffee foam | hptouchpadbestbuy99

  6. Pingback: ‘Textspresso’ machine prints texts on your coffee foam | buytasergun

  7. Pingback: ‘Textspresso’ machine prints texts on your coffee foam | directbuy

  8. Pingback: ‘Textspresso’ machine prints texts on your coffee foam | buycar

  9. Pingback: ‘Textspresso’ machine prints texts on your coffee foam | buyjessicasimpsonhairextensions

  10. Pingback: ‘Textspresso’ machine prints texts on your coffee foam

  11. Pingback: ‘Textspresso’ machine prints texts on your coffee foam : Pillalu.com

  12. Pingback: Zipwhip’s Textpresso can print texts and numbers on espresso foam

  13. Pingback: 'Textspresso' machine prints texts on your coffee foam

  14. Pingback: New video for Textspresso coffee machine | Coffee Machine Reviews

  15. Pingback: 'Textspresso' machine prints texts on your coffee foam

  16. Pingback: The world’s first coffee machine that takes orders by text – Simply Zesty - Simply Zesty

  17. Pingback: The world’s first coffee machine that takes orders by text « sifabie

  18. Pingback: Café Coqueto

  19. a3 says:

    Thanks for this, I was looking for something like this as arduino Servo library wasn’t cutting it.

    Not all servos are built alike.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.