Go Down

Topic: Controlling two servos through serial (Read 5 times) previous topic - next topic

n00b234

I'm trying to control two servos through serial to controll a nerf gun, and its gonna be awesome. im gonna put a camera on it and have it go to my ipod touch, and controll it all with OSCemote on my ipod touch. Does anyone have any good code like this, but for two servos instead of one:
/*
* 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
*/

/** Adjust these values for your servo and setup, if necessary **/
int servoPin     =  2;    // control pin for servo motor
int minPulse     =  600;  // minimum servo position
int maxPulse     =  2400; // 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
 }
}


AWOL

#1
May 27, 2009, 08:43 pm Last Edit: May 27, 2009, 08:53 pm by AWOL Reason: 1
Quote
Does anyone have any good code like this, but for two servos instead of one

Have you tried a search?

Code: [Select]
// 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; }

This section and comment just cracks me up.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

n00b234

ive searched for a while, and i havent found anything(that worked). Could someone who actualy knows what there doing edit this code and make it for two servos. u should probably assign them to other keys, like up be w, left be a, down be s, and right be d. im gonna put a fire button on it too, so could you make f be an I/O thing. the trigger is just a standard I/O switch, but i dont know how to control it with an arduino.

im a noob, so plz help

n00b234

I have figured some stuff out and i have some code, but it doesnt work quite rite yet can someone fix it? the left and right(a and d) work, but the up and down(w and s) are kinda funky. it tries to catch up to the other servo, and doesnt listen to the terminal commands i give it. here is my code:
Code: [Select]
#include <Servo.h>

Servo servo1;
Servo servo2;

/** Adjust these values for your servo and setup, if necessary **/
int servo1Pin     =  10;    // control pin for servo motor
int servo2Pin     =  11;    // control pin for servo motor
int minPulse     =  900;  // minimum servo position
int maxPulse     =  2100; // 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 moveServo1;           // raw user input
int moveServo2;           // raw user input
long lastPulse   = 0;    // recorded time (ms) of the last pulse


void setup() {
 pinMode(servo1Pin, OUTPUT);  // Set servo pin as an output pin
 pinMode(servo2Pin, 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:
   moveServo1 = Serial.read();
   moveServo2 = Serial.read();

   // ASCII 'a' is 44, ASCII 'd' is 46
   if (moveServo1 == 97) { pulseWidth = pulseWidth - turnRate; }
   if (moveServo1 == 100) { pulseWidth = pulseWidth + turnRate; }
   if (moveServo1 == 32) { pulseWidth = centerServo; }
 
   // ASCII 's' is 44, ASCII 'w' is 46
   if (moveServo2 == 115) { pulseWidth = pulseWidth - turnRate; }
   if (moveServo2 == 119) { pulseWidth = pulseWidth + turnRate; }
   if (moveServo2 == 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(servo1Pin, HIGH);   // start the pulse
   delayMicroseconds(pulseWidth);  // pulse width
   digitalWrite(servo1Pin, LOW);    // stop the pulse
   lastPulse = millis();           // save the time of the last pulse
 }
 if (millis() - lastPulse >= refreshTime) {
   digitalWrite(servo2Pin, HIGH);   // start the pulse
   delayMicroseconds(pulseWidth);  // pulse width
   digitalWrite(servo2Pin, LOW);    // stop the pulse
   lastPulse = millis();           // save the time of the last pulse
 }
}


AWOL

#4
May 28, 2009, 08:22 am Last Edit: May 28, 2009, 08:46 am by AWOL Reason: 1
Quote
it tries to catch up to the other servo, and doesnt listen to the terminal commands i give it. here is my code


How are you powering the servos?
From a separate supply, I hope.

Code: [Select]
if (moveServo1 == 97) { pulseWidth = pulseWidth - turnRate; }

Is easier to read if :
Code: [Select]
if (moveServo1 == 'a') { pulseWidth = pulseWidth - turnRate; }


Not sure why you've written this section as two separate clauses:
Code: [Select]
if (millis() - lastPulse >= refreshTime) {
   digitalWrite(servo1Pin, HIGH);   // start the pulse
   delayMicroseconds(pulseWidth);  // pulse width
   digitalWrite(servo1Pin, LOW);    // stop the pulse
   lastPulse = millis();           // save the time of the last pulse
 }
 if (millis() - lastPulse >= refreshTime) {
   digitalWrite(servo2Pin, HIGH);   // start the pulse
   delayMicroseconds(pulseWidth);  // pulse width
   digitalWrite(servo2Pin, LOW);    // stop the pulse
   lastPulse = millis();           // save the time of the last pulse
 }
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Go Up