Controlling Multiple Servos With RC using servo.h

Hi all,

I am trying to control multiple servos using inputs from a 3 channel RC remote using the Code below... I can successfully control 1 of the servos with the lines that I have commented out. My problem is when I try to control another servo with the lines uncommitted, it messes up everything. Does anyone have any advice for how I can go about controlling two different servos using an RC Transmitter/receiver? Thanks in Advance!!

#include <Servo.h>
Servo myservo;
//Servo myservo2;

int ch1;
int ch2;
int ch3;
int degree1;
//int degree2;

void setup() {

pinMode(7, INPUT);
//pinMode(6, INPUT);
myservo.attach(9);
//myservo2.attach(8);

Serial.begin(9600);

}

void loop() {

ch1 = pulseIn(7, HIGH, 25000);
//ch2 = pulseIn(6, HIGH, 25000);

degree1 = (ch1-30); //balancing to rest at zero
//degree2 = (ch2-30);//probably will need to change
Serial.print("Channel 1:");
//Serial.print("Channel 2:");

Serial.println(degree1);
//Serial.println(degree2);

myservo.write(degree1);
//myservo2.write(degree2);
delay(5);

}

"It messes up everything", what does that mean? My guess is that the servos don't get equally power. Switch things to check for bad connections or faulty servos etc.

How are you powering the servos? If they are connected to the Arduino 5V pin then that's your problem. Servos should be powered separately NOT through the Arduino. A circuit diagram would help us see what's going on.

If you think it's not that, try putting back in all of the code lines except the myservo2.write(). Does servo1 still work correctly? If it does put the lines back in one at a time from the bottom until it stops working then report back.

If that doesn't show anything perhaps you could give a more useful error report than "messes up everything". E.g. what actually happens or doesn't happen?

Steve

Thanks for the replies. What I mean by "messes up" is that the previously working servo is no longer able to be controlled by the RC remote. And I will try to debug the code line by line.

Do that!

the previously working servo is no longer able to be controlled by the RC remote

Careful with how you phrase your sentences! An end user thinks the servo is controlled by an RC remote. A coder (you!) thinks the program reads correctly the RC remote, the program handles the input data correctly, the program controls the servo accordingly. Divide your problem into at least those three steps.

collinfeight:
What I mean by "messes up" is that the previously working servo is no longer able to be controlled by the RC remote.

You still haven't said how you are powering the servos. And does "is no longer able to be controlled" mean that the servo never moves or it moves back and forward continually or it moves when the controller changes but not as expected. It's really hard work trying to help when you won't give any real details.

Steve

This made me thinking:

ch1 = pulseIn(7, HIGH, 25000);
ch2 = pulseIn(6, HIGH, 25000);

How often do the pulses come in? If I understand corectly, the program halts for measuring the pin 7 pulse. If no pulse for 25 ms, it returns zero and continues to tmeasuring the pulse at pin 6, halting again. Maybe you can deal with the waiting, but there's still some waiting going on. Could it cause the problems you are facing? If I'd write those routines from scratch, I'd use millis() or micros() and avoid the waiting.

Interesting point. What exactly is attached to pins 6 and 7? If it's a conventional RC receiver then it shouldn't be a problem as the servo pulse will continually repeat approx every 20ms...so very little waiting involved.

I've used that basic mechanism for 6 channels with no problems. But the pulses are roughly 1000 to 2000 microseconds. Subtracting 30 from 2000 isn't going to give you anything in degrees.

Steve

Your code:

  ch1 = pulseIn(7, HIGH, 25000);
  //ch2 = pulseIn(6, HIGH, 25000);
  
  degree1 = (ch1-30); //balancing to rest at zero
  //degree2 = (ch2-30);//probably will need to change
  Serial.print("Channel 1:");
  //Serial.print("Channel 2:");

  Serial.println(degree1);
  //Serial.println(degree2);

  myservo.write(degree1);

You seem to expect that pulseIn() returns a degree value, but it's not! As slipstick wrote, it probably returns a value between 1000 and 2000. My guess is that this is not your working code. A map function is missing.

It may be getting away with it because, confusingly, if you pass a high number (above 200 I think) to servo.write() it treats it as if you had used servo.writeMicroseconds() instead.

I really wish the Servo library didn't do that because it can make code really difficult to understand...like now.

Steve

I'd be ashamed if I had written a lib like that.