Go Down

Topic: Varying Servo Rotation Limit (Read 1 time) previous topic - next topic

kelvin8

Code: [Select]
This is the code

[code#include <Servo.h>
Servo myservo;

int potpin1 = 0;    //analog input pin A0
int potpin2 = 1;    //analog input pin A1

int minPos;          //variable to store servo minimum position
int maxPos;          //variable to store servo maximum position
int pos1 = 0;

void setup()
{
  Serial.begin(9600);
  myservo.attach(9);
  Serial.println("testing position variable servo");
}

void loop()
{
  minPos = map(analogRead(potpin1), 0, 1023, 0, 180);
  maxPos = map(analogRead(potpin2), 0, 1023, 0, 180);
  pos1 = minPos;

  for(pos1 = minPos; pos1 <= maxPos; pos1 += 1)    // goes from 0 degrees to 180 degrees
  {                                      // in steps of 1 degree
    myservo.write(pos1);                // tell servo to go to position in variable pos1
    delay(15);
    maxPos = map(analogRead(potpin2), 0, 1023, 0, 180);
  }
  maxPos = map(analogRead(potpin2), 0, 1023, 0, 180);
  pos1 = maxPos;
  for(pos1 = maxPos; pos1 >= minPos; pos1 -= 1)    // goes from 180 degrees to 0 degrees
  {
    myservo.write (pos1);                // tell servo to go to position in variable pos2
    delay(15);
    minPos = map(analogRead(potpin1), 0, 1023, 0, 180);
  }
}


I think the issue might be the analog mapping

zoomkat

Have you tried something like below? Also, you probably should print the servo commands to the serial monitor to see what the code output is.

Code: [Select]

int minPos;          //variable to store servo minimum position
int maxPos;          //variable to store servo maximum position
int pos1 = 90;

void setup()
{
  Serial.begin(9600);
  myservo.attach(9);
  Serial.println("testing position variable servo");
}

void loop()
{
  minPos = map(analogRead(potpin1), 0, 1023, 0, 90);
  maxPos = map(analogRead(potpin2), 0, 1023, 90, 180);
  //pos1 = minPos;
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

kelvin8

Hi yes i was able to try that idea but the servo still acts as if the potentiometers are running the knob control code.

I tried using the serial print and got the values of the potentiometer correctly but i'm still not able to understand why the servo does not sweep between both angles.

JimboZA

I don't think you posted a schematic of your setup... might be time to do that so we can see exactly how it hangs together.
Repeal Ohm's Law

No PMs for help please

zoomkat

Modified sweep test code to set the upper and lower servo positions (big delay and 5 deg. changes for testing). I don't have a servo to test this with, so YMMV. Use the serial monitor to see the position output.

Code: [Select]

// zoomkat modified sweep 11-04-13

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
int pos = 90; // servo start position between up and dn
int dn = 40; // servo lower limit
int up = 140; // servo upper limit

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


void loop()
{
  for(pos > dn; pos < up; pos += 5)  // dn and up set servo limits
  {                                   
    Serial.println(pos);  // for serial monitor viewing
    myservo.write(pos);   // tell servo to go to position in variable 'pos'
    delay(150);           // waits 150ms for the servo to reach the position
  }
  for(pos < up; pos >dn; pos-=5)     // dn and up set servo limits
  {                               
    Serial.println(pos);
    myservo.write(pos);     // tell servo to go to position in variable 'pos'
    delay(150);             // waits 150ms for the servo to reach the position
  }
}

Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

kelvin8

Thanks that seems like it might work but how would you be able to increase or decrease the servo limits using the potentiometer. I am referring to the code below:

Code: [Select]
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
int pos = 90; // servo start position between up and dn
int dn = 40; // servo lower limit
int up = 140; // servo upper limit

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


void loop()
{
  for(pos > dn; pos < up; pos += 5)  // dn and up set servo limits
  {                                   
    Serial.println(pos);  // for serial monitor viewing
    myservo.write(pos);   // tell servo to go to position in variable 'pos'
    delay(150);           // waits 150ms for the servo to reach the position
  }
  for(pos < up; pos >dn; pos-=5)     // dn and up set servo limits
  {                               
    Serial.println(pos);
    myservo.write(pos);     // tell servo to go to position in variable 'pos'
    delay(150);             // waits 150ms for the servo to reach the position
  }
}
/code]


kelvin8

Hi Everyone, I tried rewriting a new code for this same problem but have not been able to test it yet. It will be really helpful if someone could look through it and tell me if they think its correct.

Code: [Select]
#include <Servo.h>
Servo myservo;

int potpin1 = 0;            //analog input pin A0
int potpin2 = 1;            //analog input pin A1

int minPos;                  //variable to store servo minimum position
int maxPos;                  //variable to store servo maximum position
int pos1 = 0;

void setup()
{
 Serial.begin(9600);
 myservo.attach(9);
 Serial.println("testing position variable servo");
}

void loop()
{
 minPos = map(analogRead(potpin1), 0, 1023, 0, 90);
 maxPos = map(analogRead(potpin2), 0, 1023, 90, 180);
 pos1 = minPos;
 
 for(pos1 >= minPos; pos1 < maxPos; pos1 += 1)    //limit from 90 degrees
 {
   Serial.println(pos1);
   myservo.write(pos1);
   delay(15);
 }
 pos1 = maxPos;
 for(pos1 <= maxPos; pos1 > minPos; pos1 -= 1)     //limit from 180 degrees
 {
   Serial.println(pos1);
   myservo.write(pos1);
   delay(15);
 }
}
/code]






kelvin8

Update: If this doesn't work i had another idea i was thinking about but not completely sure how to go about it.

The servo starts sweeping from 0 to 180 degrees
The user puts on a switch on and it changes to 20 to 160 degrees and when it's off it goes back to the original sweep
The user puts on another switch and it changes to 40 to 140 degrees and it does the same as above.

Basically the switches increase or decrease the limits for rotation.

These are the angles i want to use:

0 to 180 degrees (original sweep)
20 to 160 degrees (switch 1)
40 to 140 degrees (switch 2)
60 to 120 degrees (switch 3)
80 to 100 degrees (switch 4)

so maybe an if statement starts a new sweep function. Thanks

PaulS

Code: [Select]
  for(pos1 >= minPos; pos1 < maxPos; pos1 += 1)    //limit from 90 degrees
The first clause of a for statement is an initialization section. I can't see that pos1 >= minPos makes a good initialization statement. The result of the operator is true or false.


enanthate

So, use the buttons to change maxPos and minPos.
You are allowed to use your head! You know enough to figure this out on your own ;)
Trust yourself.

kelvin8


Code: [Select]
  for(pos1 >= minPos; pos1 < maxPos; pos1 += 1)    //limit from 90 degrees
The first clause of a for statement is an initialization section. I can't see that pos1 >= minPos makes a good initialization statement. The result of the operator is true or false.




Could you explain further please

kelvin8

I tried using switches to change  the limit of rotation. It compiles well. Tell me what you think. My aim is to add some more switches to create different levels of rotation. Thanks
Code: [Select]
#include <Servo.h>

Servo myservo;

int pos = 0;
int myswitch = 0;

void setup ()
{
  myservo.attach(9);
}

void loop ()
{
  int switchvalue = digitalRead(myswitch);
 
  if ( switchvalue = 1) {
    for (pos = 60; pos < 120; pos +=1)
   {
    myservo.write (pos);
   delay (15);
   }
  for (pos = 120; pos >= 60; pos -=1)
{
  myservo.write(pos);
delay (15);
}
  }
  else {
   for (pos = 0; pos < 180; pos +=1)
   {
     myservo.write (pos);
     delay (15);
   }
   for (pos = 180; pos >=1; pos -=1)
   {
     myservo.write (pos);
     delay (15);
   }
}
}/code]

enanthate


I tried using switches to change  the limit of rotation. It compiles well. Tell me what you think. My aim is to add some more switches to create different levels of rotation. Thanks


Good job.
You can make the code a little easier like the one below.
The idea is to only use one for-loop(one up and one down), and change the values of it instead. I'm sure there is a better way to do it, but here goes:

Code: [Select]

int switchvalue = digitalRead(myswitch);
if(switchvalue == 1) {
  minPos = 60;
  maxPos = 120;
}
for(pos = minPos; pos < maxPos; pos++) {
  myservo.write(pos);
  delay(15);
}


Remember that the for-loop says for(pos = minPos.....), so pos have to be equal to minPos before the loop.
Hope this makes sense, it's still early over here.

PaulS

Quote
Could you explain further please

Can you take a C class? Can you perform some basic research on you own? The Arduino site has a page on the for loop. It explains what all three clauses do.

Bumbling along changing dozens of things at once is NOT the way to learn. Your issues have nothing to do with hardware at this point. They have way more to do with impatience.

Create a sketch that reads a potentiometer. Write the value to the serial port. DO NOTHING ELSE IN THE SKETCH.

When that works, add a for loop that goes from 0 (the INITIAL value) to the value of the pot, printing the index to the serial port.

Then, add another pot, and use that to define the INITIAL value for the for loop. Keep printing the value of the loop index.

Turn the pots to see how the lower limit and upper limit affect the numbers printed.

Then, think about making the servo move to the index position, instead of printing the index to the serial port.

zoomkat

I think I'd try merging a modified vewsion of this pot mapping code with the code I previously posted. Use the below (or similar code) to convert the pot input to the dn and up variables in the first part of the main loop, then the variables are used in the second part of the main loop.

Code: [Select]

//zoomkat dual pot/servo test 12-29-12
//view output using the serial monitor

#include <Servo.h>
Servo myservo1;
Servo myservo2;

int potpin1 = 0;  //analog input pin A0
int potpin2 = 1;

int newval1, oldval1;
int newval2, oldval2;

void setup()
{
  Serial.begin(9600); 
  myservo1.attach(2); 
  myservo2.attach(3);
  Serial.println("testing dual pot servo"); 
}

void loop()
{
  newval1 = analogRead(potpin1);           
  newval1 = map(newval1, 0, 1023, 0, 179);
  if (newval1 < (oldval1-2) || newval1 > (oldval1+2)){ 
    myservo1.write(newval1);
    Serial.print("1- ");
    Serial.println(newval1);
    oldval1=newval1;
  }

  newval2 = analogRead(potpin2);
  newval2 = map(newval2, 0, 1023, 0, 179);
  if (newval2 < (oldval2-2) || newval2 > (oldval2+2)){ 
    myservo2.write(newval2);
    Serial.print("2- ");   
    Serial.println(newval2);
    oldval2=newval2;
  }
  delay(50);
}


Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

Go Up