Odd Servo Control Problem

I am having trouble interfacing Pololu’s BCM servo to my ATMega328P, using the Arduino development environment.

The Arduino standard Servo Library caused the servo to jarr right up against one end of its range. The motion also seemed jittery.

Thinking the servo might be non standard I hunted for other control software that might offer more control. I found some code that didn’t cause the servo to hit one end of its range, however the results were still terrible…please see the attached video. In the video, the ATMega is transmitting a constant, mid-range pulse on a digital pin i.e. the servo arm should be held still.

Here is the code:

   /* 
    * NewSerialServo 
    * -------------- 
    * Servo control from the Serial port 
    * 
    * Alteration of the control interface to use < and > keys 
    * to slew the servo horn left and right.  Works best with 
    * the Linux/Mac terminal "screen" program. 
    * 
    * Created 10 December 2007 
    * copyleft 2007 Brian D. Wendt 
    * http://principialabs.com/ 
    * 
    * Adapted from code by Tom Igoe 
    * http://itp.nyu.edu/physcomp/Labs/Servo 
    */  
     
  /** Adjust these values for your servo and setup, if necessary **/  
   int servoPin     =  8;    // control pin for servo motor  
   int minPulse     =  1000;  // minimum servo position  
   int maxPulse     =  2000; // maximum servo position  
   int turnRate     =  100;  // servo turn rate increment (larger value, faster rate)  
   int refreshTime  =  20;   // time (ms) between pulses (50Hz)  
     
   /** The Arduino will calculate these values for you **/  
   int centerServo;         // center servo position  
   int pulseWidth;          // servo pulse width  
   int moveServo;           // raw user input  
   long lastPulse   = 0;    // recorded time (ms) of the last pulse  
     
    
   void setup() {  
     pinMode(servoPin, OUTPUT);  // Set servo pin as an output pin  
     centerServo = maxPulse - ((maxPulse - minPulse)/2);  
     pulseWidth = centerServo;   // Give the servo a starting point (or it floats)  
     Serial.begin(9600);  
     Serial.println("      Arduino Serial Servo Control");  
     Serial.println("Press < or > to move, spacebar to center");  
     Serial.println();  
   }  
     
   void loop() {  
     // wait for serial input  
     if (Serial.available() > 0) {  
       // read the incoming byte:  
       moveServo = Serial.read();  
     
       // ASCII '<' is 44, ASCII '>' is 46 (comma and period, really)  
       if (moveServo == 44) { pulseWidth = pulseWidth - turnRate; }  
       if (moveServo == 46) { pulseWidth = pulseWidth + turnRate; }  
       if (moveServo == 32) { pulseWidth = centerServo; }  
     
       // stop servo pulse at min and max  
       if (pulseWidth > maxPulse) { pulseWidth = maxPulse; }  
       if (pulseWidth < minPulse) { pulseWidth = minPulse; }  
     
       // print pulseWidth back to the Serial Monitor (uncomment to debug)  
      // Serial.print("Pulse Width: ");  
      // Serial.print(pulseWidth);  
      // Serial.println("us");   // microseconds  
    }  
    
    // pulse the servo every 20 ms (refreshTime) with current pulseWidth  
    // this will hold the servo's position if unchanged, or move it if changed  
    if (millis() - lastPulse >= refreshTime) {  
      digitalWrite(servoPin, HIGH);   // start the pulse  
      delayMicroseconds(pulseWidth);  // pulse width  
      digitalWrite(servoPin, LOW);    // stop the pulse  
      lastPulse = millis();           // save the time of the last pulse  
    }  
  }

I have tried various pulse widths including quite out-of-range ones, but none seem to have any effect at all.

My best guess is that this servo uses a non standard refresh rate so it is getting completely garbled pulses… head of one, tail end of another etc. Has anyone seem this behaviour before or can shed any light? I have tried to hunt for a data-sheet for this servo but neither Pololu nor Joinmax seem to offer one.

The Pololu website says this isn’t a digital servo, but I have read that this doesn’t affect the PWM control method. Note to Pololu: I have seen another post on this forum stating that they had trouble with controlling a Joinmax Servo, so I have to ask; has anyone at Pololu successfully controlled one of these servos?

Of course, the problem may be obvious to someone else as I’m a newbie to servos. Preparing to take the full force of someones clue bat :wink:

Thanks,
Chris
BCM Servo Behaviour.zip (749 KB)

Hello.

The behavior you are describing could be caused by bad code, a bad power setup, or a bad servo. Do you have either another servo with which your code works or another servo control source (e.g. an RC receiver) with which you can try the BCM servo? What is your power supply?

By the way, sending pulses that cause a servo to try to go past its mechanical limit is an easy way to destroy servos. There’s nothing special about these servos from a control perspective, and like most servos, they can handle a pretty wide range of update frequencies.

We tested all of the BCM servos as we got them, so your unit worked at one point.

- Jan

Problem solved! It was a bad power setup.

I had originally run the microcontroller and servo on one power supply, but it was not powerful enough and caused the microcontroller to reset when the servo moved.

So, I switched to using two independant 5v supplies, one for the servo and one for the microcontroller. That is when I was getting the odd behaviour as described (but at least the servo was being powered, I thought).

Switching the whole setup back to a single, more powerful 5v supply solved the problem and the code I posted now works. The servo works brilliantly.

As a follow up question; I assume that a difference in the power of the supplies was causing the voltage to be pulled high or low on the servo control pin, causing the control signal to be weakened. Should I wish to go back to a two-supply setup, I am guessing I could use a transistor with the base at the microcontroller output pin, and the collector and emitter between the +ve of the servo supply circuit, and the servo control pin… does this sound reasonable?

Thank you for your advice Jan, I appreciate Pololus support.

- Chris

PS I’m pleased to say the servo seems to have survived its mechanical torture: I did wince and rush to disconnect it each time, not a nice sound…

I’m happy you have things working. You’re way off with that transistor talk, though. I’m not sure what exactly you’re trying to achieve with it, but you can power the servo (its plus and minus wires) with its own source, power your controller with another source, and then connect the grounds between the two and connect the control wire between the two. You might want to put something like a 220 ohm resistor in that line to prevent too much current flowing through that control line if the voltages are very different.

- Jan