Controlling speed of a pre-programmed servo sequence!

Hi everyone,

I'm pretty new with microcontrollers, etc..but I've had this idea for a very long time and am trying to figure out if it's feasible.

I'd like to program a continuous servo to move backwards, forwards, etc according to my liking. The part I'm not sure will work is that I want to make a foot type of pedal (similar to a wah or expression pedal with guitar effect pedals) that will allow me to control the speed of the servo's programmed movements with a potentiometer in the pedal. Is this possible? MY first thought would be to have the potentiometer control the voltage, but I'm sure that's a bad idea / will fry things. So essentially, I would like to program the servo to do a sequence of movements or rotations, and then use the foot pedal to make those pre-programmed movements gradually faster, or slower. I have figured out how to use the continuous servo with a potentiometer using the knob tutorial / i can make it go fast or slow or whatever, and i understand how to program certain sequences, but what I am wondering is how to combine the two functions.

The big picture for this project would be to make a looping sound sculpture that I can control with my foot while playing guitar. Don't know how to figure it out. Any help would be very much appreciated.

Any help would be very, very much appreciated.

With a continuous rotation servo the value in Servo.write(val) determines the speed. 90 is stopped, 0 is full speed one way and 180 is full speed the other way. All values approximate as individual servos vary.

You just need to use the pedal to vary that number.

You could have an array with a stored sequence of speed values and time-periods (for each speed) and you could use the value from the pedal to add or subtract a bit. Something like

myServo.write(sequenceValue[sequenceNumber] + pedalValue);

...R

I have figured out how to use the continuous servo with a potentiometer using the knob tutorial / i can make it go fast or slow or whatever, and i understand how to program certain sequences, but what I am wondering is how to combine the two functions.

You might use the analog output value of the pot to determine which pre programmed loop is entered and executed.

Thanks everyone. I think what Robin2 said was very helpful. Now I am just having trouble integrating that command (myServo.write(sequenceValue[sequenceNumber] + pedalValue):wink:

with something like this:

servoSequencePoint slow[] = {{100,20},{20,20},{60,50}};

Think I really need to work on my coding...

yorhombus:
Think I really need to work on my coding...

If you want help you need to post your complete program. And please use the code button </> so your code looks like this and is easy to copy to a text editor

...R

OK, this is really embarassing and is a complete hodgepodge of different codes that I have changed the values of willy-nilly...I basically dont even care about the second sequence (twitchy) but when I take it out I get errors..I basically would love to know how to eliminate the twitchy command so that I have more of an idea what is going on. Total apologies for this mess, completely understand if it is impossible to decipher.

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

modified 8 Nov 2013
by Scott Fitzgerald
http://arduino.cc/en/Tutorial/Sweep

modified 28 Sept. 2015
by Jed Koch
*/
#include <VarSpeedServo.h>



int potpin = 0;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin 
VarSpeedServo myservo;  // create servo object to control a servo 
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position 
servoSequencePoint slow[] = {{100,20},{20,70},{60,20}}; // go to position 100 at speed of 20, position 20 speed 20, position 60, speed 50
servoSequencePoint twitchy[] = {{100,40},{20,40},{60,40}};

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

void loop() 
{ 

 for(pos = 0; pos <= 180; pos += 4){
   myservo.sequencePlay(slow+pos,4); // play sequence "slowHalf" that has 3 positions, loop and start at first position
 }  // goes from 0 degrees to 180 degrees 
 {     // in steps of 4 degree 
   checkPot();
   myservo.write(pos);              // tell servo to go to position in variable 'pos' 
   delayMicroseconds(val);                       // waits 15ms for the servo to reach the position 
 } 
 for(pos = 3600; pos>=0; pos-=1)     // goes from 180 degrees to 0 degrees 
 {                                
   checkPot();
   myservo.write(pos);              // tell servo to go to position in variable 'pos' 
   delayMicroseconds(val);                       // waits 15ms for the servo to reach the position 
 } 
 } 


void checkPot(){
 val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023) 
 val = map(val, 0, 1023, 10, 3600);     // scale it to use it with the servo (value between 0 and 180) 
}

Sorry, I don't know the VarSpeedServo library. In my earlier advice I was assuming you were using the regular Servo library.

As far as I know you the purpose of the purpose of the VarSpeedServo library is to avoid the need for the Servo sweep type of code.

...R

I'd like to program a continuous servo to move backwards, forwards, etc according to my liking.

The typical continuous rotation servo has a variable speed control range between 1400us and 1600us. You probably should bap between those ranges like below. Bottom is some servo test code you might use to get a better idea of how your servo works. Note that for best operation the servo should have an external power supply.

void checkPot(){
 val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
 val = map(val, 0, 1023, 1400, 1600);     // scale it to use it with the servo (value between 0 and 180)
}
// zoomkat 3-28-14 serial servo incremental test code
// using serial monitor type a character (s to increase or a 
// to decrease) and enter to change servo position 
// (two hands required, one for letter entry and one for enter key)
// use strings like 90x or 1500x for new servo position 
// for IDE 1.0.5 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.

#include<Servo.h>
String readString;
Servo myservo;
int pos=1500; //~neutral value for continous rotation servo
//int pos=90;

void setup()
{
  myservo.attach(7, 400, 2600); //servo control pin, and range if desired
  Serial.begin(9600);
  Serial.println("serial servo incremental test code");
  Serial.println("type a character (s to increase or a to decrease)");
  Serial.println("and enter to change servo position");
  Serial.println("use strings like 90x or 1500x for new servo position");
  Serial.println();
}

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) {
    if(readString.indexOf('x') >0) { 
      pos = readString.toInt();
    }

    if(readString =="a"){
      (pos=pos-1); //use larger numbers for larger increments
      if(pos<0) (pos=0); //prevent negative number
    }
    if (readString =="s"){
      (pos=pos+1);
    }

    if(pos >= 400) //determine servo write method
    {
      Serial.println(pos);
      myservo.writeMicroseconds(pos);
    }
    else
    {   
      Serial.println(pos);
      myservo.write(pos); 
    }
  }
  readString=""; //empty for next input
}

OK, so I have made a lot of progress, and have figured out how to control the speed of a pre-programmed sequence with a potentiometer. Now I am trying to make it so that multiple servos are hooked up to the arduino and are controlled asynchronously with their own potentiometers. I know that this is possible with the VarSpeedServo library, but what is happening is that one potentiometer ends up controlling the speed of both servos, instead of each pot controlling its own servo.

This is my code: any help as always, very much appreciated.

#include <VarSpeedServo.h>

VarSpeedServo myServo;
VarSpeedServo myServo2;

// area where you can change values (pattern and motor speed)///////////////
 

/////////////////////////////////////////////////////////////////////////////
 

const int L       = -1;
const int R       =  1;
const int potpin  =  A0;
const int potpin2 =  A4;
const int servoPin1 = 9; // the digital pin used for the first servo
const int servoPin2 = 10; // the digital pin used for the second servo
 
const int patternLen = 5; //nb of elements in the pattern. Length of list
const int patternLen2 = 5; //nb of elements in the pattern. Length of list
const int myScore[patternLen]  = {L, L, R, L, R}; //The pattern
const int myScore2[patternLen2]  = {R, R, R, L, R}; //The pattern

int mSpeed      = 5; // motor speed between 0 and 90;
int mSpeed2      = 5; // motor speed between 0 and 90;

int stepTime    = 500; //milliseconds. Changed by the pot value
int stepTime2    = 500; //milliseconds. Changed by the pot value
int stepPos     = 0;  //position in the sequence
int stepPos2     = 0;  //position in the sequence

int servoValue;
int servoValue2;


void setup() {

myServo.attach(servoPin1);
myServo.write(0,255,false);
myServo2.attach(servoPin2);
myServo2.write(0,255,true);
}

void loop() {
 
 
  servoValue = 92 + myScore[stepPos] * mSpeed;
  myServo.write(servoValue);
  stepTime = map( analogRead(potpin), 0, 1023, 50, 1000);
  delay(stepTime);
  stepPos = (stepPos + 1) % patternLen ;

      
   {servoValue2 = 92 + myScore2[stepPos2] * mSpeed2;
  myServo2.write(servoValue2);
  stepTime2 = map( analogRead(potpin2), 0, 1023, 50, 1000);
  delay(stepTime2);
  stepPos2 = (stepPos + 1) % patternLen2 ;

}

Should this line

stepPos2 = (stepPos + 1) % patternLen2 ;

be

stepPos2 = (stepPos2 + 1) % patternLen2 ;

...R

Hmm, still isn't changing anything. One potentiometer still controls both servos. :o

I think I see the problem.

The way your code is written both servos are affected by both potentiometers

If you want each servo to operate separately you will need to reorganize the code.

Rather than using delay() which prevents the Arduino from doing anything else, you need to use millis() to manage the timing as that will allow you to have separate timing for each servo.

The way millis() is used is illustrated in Several Things at a Time.

It includes a servo function and I think for your purpose you would just need to have two functions like that - obviously each with its own variables.

...R