Go Down

Topic: Simple project, willing to pay $$$ for basic coding - 4 Servos + Ping))) (Read 4 times) previous topic - next topic


Hello everyone! I'm a bit of a novice to Arduino programming as this is only my second project ;).

Basically, I have four servos connected to an Arduino, and I would like their speed to be regulated by a Ping ultrasonic proximity sensor.

At the moment, my code enables me to control all Servos manually by inputing values for speed. Pretty much I would like to move the servo, measure a distance, change speed, move the servo, measure a distance, change speed etc. That way if I move close to the servo's they gradually move to a halt, and as I step away they gradually build up speed. 

Can this be done? Would anyone be willing to modify my code to implement the Ping changing Servo speed for a negotiable amount of $?

Please email me at fathersonholyghostarts@gmail.com with any bids or questions.

I would post my code below but I don't know how to post seperate tabs of code in the forum.

Thanks in advance...



Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.


Nope that was someone else. Similar project though--- I'm using Servo's rather than stepper motors, and mine has nothing to do with optics etc.


do you actually mean Servos, generally these are thought of as the thing that is used in RC projects and their speed is not normally controlled but their position is with PWM and is maintained using an internal closed loop feedback in the servo itself.

I can help, what is your budget.

Cheers Pete.
EmbeddedAT .. From Concept to Prototype to Production

Electronics and firmware design and project mentoring


Yes I do indeed mean servos.  Lame old cheap 180 degree servos. I know they are not the most precise, or in any way the most reliable motors out there - at the moment I'm really just out to build a proof of concept but I can't adjust the code accordingly. 

I'm not entirely sure how but I am definitely able to adjust the speed of the servos...Maybe it has to do with altering the frequency of the internal loop?

It would probably make more sense if I showed you the code I already have:

1st Tab:
Code: [Select]
// Controlling a servo position using a potentiometer (variable resistor)
// by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>

#include <Servo.h>

#define roll  0
#define pitch 1
#define yaw   2
#define Boo   3

#define UP    1
#define DOWN  0
#define HOLD  2

Servo servo[4];  // create servo object to control a servo

int direct[4] = {0,0,0,0};
int steps[4];
int pos[4] = {0,0,0,0};
int target[4];
int hold[4];
int maxCount[4];
int minCount[4];

long servoMin[4];
long servoMax[4];
long servoPauseMin[4];
long servoPauseMax[4];
long servoSpeed[4];

long previousMillis[4] = {0,0,0,0};        // will store last time LED was updated
unsigned long currentMillis[4];
long interval = 4000;           // interval at which to blink (milliseconds)

2nd Tab - Drive: 
Code: [Select]
void drive(int servos, int minTarget, int maxTarget,int minHold, int maxHold, int speeds) {
  if(direct[servos] == UP){
     if (pos[servos] < maxTarget){
        pos[servos] = pos[servos] + speeds ;
     else if (pos[servos] >= maxTarget){
        if(maxCount[servos] >= maxHold){
           maxCount[servos] = 0;
           direct[servos] = DOWN;
  if(direct[servos] == DOWN){
      if(pos[servos] > minTarget){
            pos[servos] = pos[servos] - speeds ;
      else if (pos[servos] <= minTarget){
        if(minCount[servos] >= minHold){
           minCount[servos] = 0;
           direct[servos] = UP;
           Serial.print("........................................................" );
  Serial.print("\t servo" );                       
  Serial.print(" = ");
  Serial.print(" ");
  Serial.print(" ");
   Serial.print("\t direction = " );                       
  //if(servos == 2) Serial.println();

3rd Tab - Loop:
Code: [Select]
void loop() {    //(servo, its minimum target, maximum target, pause at the min position, pause at max position, its speed)
       // servo[pitch].write(80);    //pitch range = 20 - 80
       //servo[roll].write(120);    //roll range = 100 - 130
        servoMin[roll] = 0;
        servoMax[roll]= 180;
        servoPauseMin[roll] = 0;
        servoPauseMax[roll] = 0;
        servoSpeed[roll]= 1;
        servoMin[pitch]= 0;
        servoMax[pitch] = 180;
        servoPauseMin[pitch]= 0;
        servoPauseMax[pitch]= 0;
        servoSpeed[pitch]= 2;
        servoMin[yaw]= 0;
        servoMax[yaw] = 180;
        servoPauseMin[yaw]= 0;
        servoPauseMax[yaw]= 0;
        servoSpeed[yaw]= 2;
        servoMin[Boo]= 0;
        servoMax[Boo] = 180 ;
        servoPauseMin[Boo]= 0;
        servoPauseMax[Boo]= 0;
        servoSpeed[Boo]=  1;
        servoMin[roll] = random(0, 100);
        servoMax[roll]= random(servoMin[roll], 180);
        servoPauseMin[roll] = random(0, 2000);
        servoPauseMax[roll] = random(0, 2000);
        servoSpeed[roll]= random(0, 5);
        servoMin[pitch]= random(0, 100);
        servoMax[pitch] = random(servoMin[pitch], 180);
        servoPauseMin[pitch]= random(0, 2000);
        servoPauseMax[pitch]= random(0, 2000);
        servoSpeed[pitch]= random(0, 5); 
        servoMin[yaw]= random(0, 100);
        servoMax[yaw] = random(servoMin[yaw], 180);
        servoPauseMin[yaw]= random(0, 1000);
        servoPauseMax[yaw]= random(0, 1000);
        servoSpeed[yaw]= random(0, 5);
      drive(roll,servoMin[roll],servoMax[roll],servoPauseMin[roll], servoPauseMax[roll],servoSpeed[roll]);
      drive(pitch, servoMin[pitch],servoMax[pitch],servoPauseMin[pitch],servoPauseMax[pitch],servoSpeed[pitch]);
    // drive(pitch,180,0,1000,1000,4);

4th Tab - Setup:
Code: [Select]
void setup() {
  servo[roll].attach(2);  // attaches the servo on pin 9 to the servo object
  servo[pitch].attach(3);  // attaches the servo on pin 9 to the servo object
  servo[yaw].attach(4);  // attaches the servo on pin 9 to the servo object
  servo[Boo].attach(5);  // attaches the servo on pin 9 to the servo object
  pos[roll] = 90;
  pos[pitch] = 90;
  pos[yaw] = 90;
  pos[Boo] = 90;


And as for the budget, I really wouldn't know - I can't really gauge how difficult a task this would be for someone to code....  I also don't know what people usually ask for in these kind of scenarios.... :smiley-red:

Any advice?


     OK so it sounds like you have already answered your own question.

      If you can vary the speed of the servos by altering a delay in between the setting of the Pulse width that sets the position of the servo just link this delay to the results from your ultrasound sensor.

     You can use the map function to map an input range from the sensor to an output range that fits in with how fast/slow you want to move the servo.

Cheers Pete.
EmbeddedAT .. From Concept to Prototype to Production

Electronics and firmware design and project mentoring


Thanks for your reply Pete!

What I need to do makes sense in my mind (mapping a range from the sensor, working out an input range for the speed of the servo, and linking the two together) - the issue is I don't know how to modify the code in order to do that. 

Any suggestions would be really helpful....

- I know I need to define the sensor (aka assign it a name).

- Link it to pin, and set it as an input pin.

- Work out the input range of the sensor and map that to an output range for the servo speed.

- Link the two values somehow in the code.....

How could I modify my code to do those tasks?

Thank you!



OK so first off what Ultrasound ranger are you using.

have you actually got it wired up to the arduino.

Cheers Pete.

EmbeddedAT .. From Concept to Prototype to Production

Electronics and firmware design and project mentoring


I'm using the Ping ultrasound reader from Parallax.  I have hooked it up to the Arduino using the sample code they provided and it works fine (outputting distance values to the serial monitor).


OK so post the code you have to control the speed of the servos and the code for the ultrasonic ranger and i can look at knitting them together for you  in the way i described before.

Cheers Pete.
EmbeddedAT .. From Concept to Prototype to Production

Electronics and firmware design and project mentoring


Thank you so much for all your help Pete!

I posted the code I have for controlling the speed of the servos a few posts back. The portion of the code where I physically input a value for speed is in the 3rd tab "loop", where I can change the 'servoSpeed[roll]= 1;' section.

The code I have for the sensor is listed below:

Code: [Select]
const int pingPin = 11;
unsigned int duration, inches;

void setup() {

void loop() {
  pinMode(pingPin, OUTPUT);          // Set pin to OUTPUT
  digitalWrite(pingPin, LOW);        // Ensure pin is low
  digitalWrite(pingPin, HIGH);       // Start ranging
  delayMicroseconds(5);              //   with 5 microsecond burst
  digitalWrite(pingPin, LOW);        // End ranging
  pinMode(pingPin, INPUT);           // Set pin to INPUT
  duration = pulseIn(pingPin, HIGH); // Read echo pulse
  inches = duration / 74 / 2;        // Convert to inches
  Serial.println(inches);            // Display result
  delay(200);              // Short delay

I hope thats all you need, let me know if I didn't express myself specifically enough at any stage  ;)

Thanks again,


Is inches a global variable? If so, how does that relate to roll, pitch, yaw, or Boo?

Which servo's speed is supposed to be controlled by inches, and how?


Inches is indeed a global variable. I would like the speed of all the servo's (roll, pitch, yaw, & boo) to be equally affected by the change in distance (defined in inches).

For example, if I'm 10 inches away from the sensor, I would like the speed of all the servos to be 1 ( servoSpeed[roll]= 1, servoSpeed[yaw]= 1 etc.)  If I increase that distance to 20 inches, all the servo's speed would change to 2.

To summarize it:       

-All the servos are moving at equal speeds.

-The value for speed is directly proportional to the distance in inches from the sensor.

I hope that answers your question. Thanks for posting!


-The value for speed is directly proportional to the distance in inches from the sensor.

So, in loop(), change:
Code: [Select]
        servoSpeed[roll]= 1;
        servoSpeed[pitch]= 2;
        servoSpeed[yaw]= 2;
        servoSpeed[Boo]=  1;

Code: [Select]
        servoSpeed[roll]= inches/10;
        servoSpeed[pitch]= 2 * inches/10;
        servoSpeed[yaw]= 2 * inches/10;
        servoSpeed[Boo]=  inches/10;

Go Up