Arduino Forum

Forum 2005-2010 (read only) => Software => Troubleshooting => Topic started by: GaTechEE on Aug 06, 2010, 04:08 pm

Title: Servo problems
Post by: GaTechEE on Aug 06, 2010, 04:08 pm
I'm integrating an Arduino into a system that uses a Battle Switch relay that is used to control a solenoid. I was told from the manufacturer that the switch uses standard servo pulses for each of the following:
--Trip point: 1500us
--Hysteresis: 40us
Recommended Values:
 --Off: 1300us
 --On: 1700us

Unfortunately, this is my first time using servo commands, and I'm unsure how to control this switch. Below is the code I've used.
Code: [Select]
#include <Servo.h>

int Hservo = 5;        //PWM
int Vservo = 3;        //PWM
int pumpOut = 4;
int horizontal = 8;    //input from joystick
int vertical = 9;      //input from joystick
int i, threshold = 500, pulseDif = 35;
long vals, average, prevAverage;
//int pump = 1;

int Y, X;

Servo BattleSwitch;

void setup() {
 Serial.begin(9600);

 pinMode(Hservo, OUTPUT);
 pinMode(Vservo, OUTPUT);
 BattleSwitch.attach(pumpOut);
 
 BattleSwitch.writeMicroseconds(1700);
}

void loop() {
 X = analogRead(horizontal);
 Y = analogRead(vertical);
 X = map(X, 0, 1023, 125, 254);
 Y = map(Y, 0, 1023, 125, 254);
 analogWrite(Hservo, X);
 analogWrite(Vservo, Y);

 //  if ((millis() % 5000) == 0) {
 //    if (pump == 1) {
 //      pump = 0;
 //    }
 //    else {
 //      pump = 1;
 //    }
 //  }

 //Turn on solenoid
//  if ((millis() % 5000) == 0) {
//    if (pump == 1) {
//      BattleSwitch.writeMicroseconds(1700);
//    }
//    else if (pump == 0) {
//      BattleSwitch.writeMicroseconds(1300);
//    }
//  }

 //Reading FSRs
 for (i=0; i<500; i++) {
   vals += analogRead(9);
   if (i == 499) {
     average = vals/500;
     if (((average - pulseDif) > prevAverage) && (average < threshold)) {
       Serial.print("          ");
       Serial.println(average);
     }
     else{
       Serial.println(average);
     }
     prevAverage = average;
     vals = 0;
     delay(250);
   }
 }
 delay(50);
}

The commented out parts were other approaches I tried. With all methods, the battle switch worked fine for a few seconds, and then the system started "twitching". As you can see from the code, I have two PWM outputs to control a horizontal and vertical servo (I found that method from trial and error). Anyway, what I mean by twitching is that the horizontal and vertical servos started moving without any changing input from the joystick controlling them.

Any suggestions? Like I said, I've never used servo code before, so I don't know how to use it, so any comments would be much appreciated.
Title: Re: Servo problems
Post by: GaTechEE on Aug 06, 2010, 04:09 pm
Also, if someone could explain what Hysteresis and trip point mean, I'd be grateful!
Title: Re: Servo problems
Post by: AWOL on Aug 06, 2010, 05:01 pm
Quote
the switch uses standard servo pulses


So why are you using PWM instead of the servo libraries?
Title: Re: Servo problems
Post by: GaTechEE on Aug 06, 2010, 05:09 pm
The battle switch specifically states that it uses servo pulses. A couple of weeks ago, through trials and measurements, I found that the servos used in vertical and horizontal movement operated when sent a PWM signal. Certain values correspond to certain positions.
Title: Re: Servo problems
Post by: AWOL on Aug 06, 2010, 07:10 pm
Quote
The battle switch specifically states that it uses servo pulses


Standard servo pulses have a repetition rate of 50Hz, and a typical duty-cycle of less than 10%.
Arduino PWM runs closer to 500Hz.
At this rate, your maximum pulse length is a shade under 2ms.

How are you powering all this?
Can you provide a link to the spec of the device?
Title: Re: Servo problems
Post by: GaTechEE on Aug 06, 2010, 08:17 pm
The horizontal and vertical servos: http://www.servocity.com/html/heavy_duty_linear_servo__25__l.html
The battle switch: http://www.dimensionengineering.com/BattleSwitch.htm
As far as powering the system, I'm using 2 18V Makita batteries and a DC to DC converter.

After reading the information about servo pulses and PWM frequency discrepancies, I went ahead and altered my code controlling the horiz. and vert. servos based on the values given on the website:
Code: [Select]
 X = analogRead(horizontal);
 Y = analogRead(vertical);
 X = map(X, 0, 1023, 2000, 1000);
 Y = map(Y, 0, 1023, 2000, 1000);
 HServo.writeMicroseconds(X);
 VServo.writeMicroseconds(Y);

Now, my biggest problem is the twitching/temporary freezing of the system. How often am I supposed to call the .writeMicroseconds()?
Title: Re: Servo problems
Post by: AWOL on Aug 06, 2010, 08:52 pm
Quote
How often am I supposed to call the .writeMicroseconds()?

It shouldn't matter - the update rate will be limited by the frame rate of the library.
Title: Re: Servo problems
Post by: GaTechEE on Aug 06, 2010, 09:03 pm
Do you have any ideas as to why the board might freeze while doing this? I guess the board might not actually be frozen, but the joystick is temporarily disabled and none of the servos work and the Battle Switch opens.
Title: Re: Servo problems
Post by: AWOL on Aug 06, 2010, 09:10 pm
No idea, without seeing a circuit.
Make sure you've got adequate decoupling and debug prints.

This:
Code: [Select]
for (i=0; i<500; i++) {
   vals += analogRead(9);
   if (i == 499) {

strikes me as an odd construction - why not just wait for the end of the loop?
Title: Re: Servo problems
Post by: GaTechEE on Aug 06, 2010, 10:41 pm
Well, I've done serial prints after everything, and traced the output and it all seems to be fine. The sketch I just tested was:
Code: [Select]
#include <Servo.h>

int Hservo = 5;        //PWM
int Vservo = 3;        //PWM
int pumpOut = 4;
int horizontal = 8;    //input from joystick
int vertical = 9;      //input from joystick
int FSR_R = 12;        //input from FSR in right leg
int i, threshold = 500, pulseDif = 35;
long vals, average, prevAverage;
int pump = 1;

int Y, X;

Servo HServo, VServo;
Servo BattleSwitch;

void setup() {
 Serial.begin(9600);

 pinMode(Hservo, OUTPUT);
 pinMode(Vservo, OUTPUT);
 BattleSwitch.attach(pumpOut);
 Serial.println("Battle Switch setup complete");
 HServo.attach(Hservo);
 Serial.println("HServo setup complete");
 VServo.attach(Vservo);
 Serial.println("VServo setup complete");
 
}

void loop() {
 X = analogRead(horizontal);
 Serial.println("X reading complete");
 Y = analogRead(vertical);
 Serial.println("Y reading complete");
 X = map(X, 0, 1023, 2000, 1000);
 Serial.println("X mapping complete");
 Y = map(Y, 0, 1023, 2000, 1000);
 Serial.println("Y mapping complete");
 HServo.writeMicroseconds(X);
 Serial.println("HServo write complete");
 VServo.writeMicroseconds(Y);
 Serial.println("VServo write complete");
 BattleSwitch.writeMicroseconds(1700);
 Serial.println("Battle Switch write complete");
}

What do you mean by decoupling?