Go Down

Topic: multiple servos and pots (Read 484 times) previous topic - next topic

brianmceng

I am trying to design a control system for a robot. I have 4 servos linked to 4 pots. my goal is to write the the position data of all pots to all servos simultaneously. i want each pot to make the set  of 4 servos attached to it behave slightly differently than the next pot. i am not familiar enough with the language to put the code together. i have attached a pic of the project and  the code. Any advise will be appreciated. thanks

// Controlling a  set of servos positioning using multiple potentiometers (variable resistor)
// by Brian McDonald modified from knob sketch.

#include <Servo.h>

Servo frontleft;  // create servo object to control a servo
Servo frontright;
Servo backright;
Servo backleft;

int collective = 0;// analog pin used to connect the potentiometer
int elevator = 1;
int alieron = 2;
int rudder = 3;

int collectivevar;    // variable to read the value from the analog pin pot
int elevatorvar;
int alieronvar;
int ruddervar;

void setup()
{
  frontleft.attach(9);  // attaches the servo on pin to the servo object
  frontright.attach(10);
  backleft.attach(11);
  backright.attach(12);

  Serial.begin(9600);
}

void loop()
{
  collectivevar = analogRead(collective);            // reads the value of the potentiometer (value between 0 and 1023)
  elevatorvar = analogRead(elevator); 
  alieronvar = analogRead(alieron);
  ruddervar = analogRead(rudder); 



  collectivevar = map(collectivevar, 0 ,1023, 0, 179);     // scale it to use it with the servo (value between 0 and 180)
  elevatorvar = map(elevatorvar, 0, 1023, 0, 179);       
  alieronvar = map(alieronvar, 0, 1023, 0, 179);
  ruddervar = map(ruddervar, 0 , 1023, 0, 179);

  frontleft.write(elevatorvar+collectivevar+alieronvar+ruddervar);                  // sets the servo position according to the scaled value
  frontright.write(elevatorvar+collectivevar+alieronvar+ruddervar);
  backleft.write(elevatorvar+collectivevar+alieronvar+ruddervar);
  backright.write(elevatorvar+collectivevar+alieronvar+ruddervar);   




  Serial.println(collectivevar);             // Gives pot reading 0-179

  delay(1);                           // waits for the servo to get there
}









zoomkat

Some test code made for servos and pots.

Code: [Select]

//zoomkat multi pot/servo test 3-23-13
//includes dead band for testing and limit servo hunting
//view output using the serial monitor

#include <Servo.h>
Servo myservo1;  //declare servos
Servo myservo2;
Servo myservo3;
Servo myservo4;
Servo myservo5;

int potpin1 = 0;  //analog input pin A0
int potpin2 = 1;
int potpin3 = 2;
int potpin4 = 3;
int potpin5 = 4;

int newval1, oldval1;  //pot input values
int newval2, oldval2;
int newval3, oldval3;
int newval4, oldval4;
int newval5, oldval5;

void setup()
{
  Serial.begin(9600); 
  myservo1.attach(2); 
  myservo2.attach(3);
  myservo3.attach(4);
  myservo4.attach(5);
  myservo5.attach(6);
  Serial.println("testing multi pot servo"); 
}

void loop()
{
  newval1 = analogRead(potpin1);           
  newval1 = map(newval1, 0, 1023, 0, 179);
  if (newval1 < (oldval1-2) || newval1 > (oldval1+2)){ //dead band
    myservo1.write(newval1); //position the servo
    Serial.print("1- ");
    Serial.println(newval1); //print the new value for testing
    oldval1=newval1; //set the current old value
  }

  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;
  }

  newval3 = analogRead(potpin3);           
  newval3 = map(newval3, 0, 1023, 0, 179);
  if (newval1 < (oldval1-2) || newval3 > (oldval3+2)){ 
    myservo1.write(newval3);
    Serial.print("3- ");
    Serial.println(newval3);
    oldval3=newval3;
  }

  newval4 = analogRead(potpin4);           
  newval4 = map(newval4, 0, 1023, 0, 179);
  if (newval1 < (oldval1-2) || newval4 > (oldval4+2)){ 
    myservo1.write(newval4);
    Serial.print("4- ");
    Serial.println(newval4);
    oldval4=newval4;
  }

  newval5 = analogRead(potpin5);           
  newval5 = map(newval5, 0, 1023, 0, 179);
  if (newval1 < (oldval5-2) || newval5 > (oldval5+2)){ 
    myservo1.write(newval5);
    Serial.print("5- ");
    Serial.println(newval5);
    oldval5=newval5;
  }
  delay(50);  //to slow loop for testing
}


Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   8)

Robin2

Something like this?

void loop() {
   for (byte n = 0; n < 4; n ++) {
       int potVal = analogRead(servoPin[n]);
       potVal = analogRead(servoPin[n]); // read twice and discard first value
       myServo[n].writeMicroseconds(potVal + 1011);
}

It assumes that myServo[] is an array of 4 Servo objects and  servoPin[] is an array of the pin values for the 4 servos.

...R

kwebersole

here is some code if you still want it worked for me should work for you if not let me know

#include <Servo.h>

Servo servo1;  // create servo object to control a servo
Servo servo2;  // create servo object to control a servo
Servo servo3;
Servo servo4;
int potpin1 = 0;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin
int potpin2 = 1;  // analog pin used to connect the potentiometer
int val2;    // variable to read the value from the analog pin
int potpin3 = 2;
int val3;
int potpin4 = 3;
int val4;

void setup()
{
  servo1.attach(9); 
  servo2.attach(10);
  servo3.attach(11);
  servo4.attach(12);
}

void loop()
{
  val = analogRead(potpin1);            // reads the value of the potentiometer (value between 0 and 1023)
  val = map(val, 0, 1023, 20, 160);     // scale it to use it with the servo (value between 0 and 180)
  servo1.write(val);                  // sets the servo position according to the scaled value
  delay(15);                           // waits for the servo to get there
 
  val2 = analogRead(potpin2);            // reads the value of the potentiometer (value between 0 and 1023)
  val2 = map(val2, 0, 1023, 20, 160);     // scale it to use it with the servo (value between 0 and 180)
  servo2.write(val2);                  // sets the servo position according to the scaled value
  delay(15);

  val3 = analogRead(potpin3);
  val3 = map(val3, 0, 1023, 20, 160);
  servo3.write(val3);
  delay(15);

  val4 = analogRead(potpin4);
  val4 = map(val4, 0, 1023, 20, 160);
  servo4.write(val4);
  delay(15); 
}

Robin2

It's definitely longer.   Is that an advantage?

...R

brianmceng

Tanks, my goal is to have all servos listen to all pots. But i'd like to control the direction of servos independently for each pot also. here is the new code:

// Controlling a servo position using a potentiometer (variable resistor)
// by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>

#include <Servo.h>

Servo frontleft;
Servo rearleft;
Servo frontright;
Servo rearright;// create servo object to control a servo

int collectivestick = 0;
int elevatorstick = 1;
int aileronstick = 2;
int rudderstick = 3;// analog pin used to connect the potentiometer

int val;    // variable to read the value from the analog pin
int val2;
int val3;
int val4;
int test;
int test2;
int test3;
int rudright;

void setup()
{
  frontleft.attach(9); // attaches the servo on pin 9 to the servo object
  frontright.attach(10);
  rearleft.attach(11);
  rearright.attach(12);
}

void loop()
{
  val = analogRead(collectivestick); // reads the value of the potentiometer (value between 0 and 1023)
  val2 = analogRead(aileronstick);
  val3 = analogRead(elevatorstick);
  val4 = analogRead(rudderstick);
  test = analogRead(collectivestick);
  test2 = analogRead(aileronstick);
  test3 = analogRead(elevatorstick);
  rudright = analogRead(rudderstick);
 

  test = map(test, 0, 1023, 179, 0);
  test2 = map(test2, 0, 1023, 179, 0);
  test3 = map(test3, 0, 1023, 179, 0);
  rudright = map(rudright, 0, 1023, 0, 89);
  val2 = map(val2, 0, 1023, 0, 179);
  val3 = map(val3, 0, 1023, 0, 179);
  val4 = map(val4, 0, 1023, 89, 179);// scale it to use it with the servo (value between 0 and 180)
  val = map(val, 0, 1023, 0, 179);
 

  int mapval[]={
    test,test2,test3,rudright,val2,val3,val4,val,
  };    //array of variables for servo mapping

  frontleft.write((val+val2+mapval[2])/3);
  rearleft.write((mapval[1]+mapval[0]+mapval[2]+mapval[3])/4);
  frontright.write((mapval[0]+val2+val3+mapval[3])/4);
  rearright.write((mapval[1]+val+val3)/3);  // sets the servo position according to the scaled value

  delay(50);                           // waits for the servo to get there
}


I'm having trouble with the servos twitching and resting center positions at extremes. maybe my voltage is inconsistent. 



zoomkat

Quote
maybe my voltage is inconsistent.


Inadequate external power supply for servos is a frequent issue.
Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   8)

Robin2


Tanks, my goal is to have all servos listen to all pots. But i'd like to control the direction of servos independently for each pot also.


Isn't that what my 5 lines of code in Reply #2 does?

...R

zoomkat



Tanks, my goal is to have all servos listen to all pots. But i'd like to control the direction of servos independently for each pot also.


Isn't that what my 5 lines of code in Reply #2 does?

...R


Your code appears to be weak as it probably will only work if the arduino pins being enumerated are in sequential order. 
Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   8)

Robin2

#9
Jul 04, 2014, 08:37 am Last Edit: Jul 04, 2014, 08:42 am by Robin2 Reason: 1

Your code appears to be weak as it probably will only work if the arduino pins being enumerated are in sequential order.  


You misunderstand ...

The array servoPin[] holds the numbers of the pins that the potentiometers for each servo are connected to.  You can connect the potentiometers to any pin.

And I probably should have called the array potPin[].

Maybe this is clearer

Code: [Select]
void loop() {
  for (byte servoNum = 0; servoNum < 4; servoNum ++) {
      int potVal = analogRead( potPin [servoNum] );
      potVal = analogRead( potPin [servoNum] ); // read twice and discard first value
      myServo[servoNum].writeMicroseconds( potVal + 1011 );
}


...R

Go Up