Help required- Servo Jitter

Hello!
Could you please help me with my issue?
I am using a PWM signal from a Radio controller and receiver that go into the arduino. The arduino then reads the code and tells the servo what to do. The servo jitters and is not smooth at all. I am thinking that it has something to do with the PWM waves not being perfectly consistent, but I don't honestly know.
Here is the Code, ignore some parts that are not related to the issue.
Also, general advice might be useful. I am trying to make a flying wing controlled by an arduino to hopefully eventually program it to be VTOL capable.

#include <Servo.h>

Servo ElavonLeft;
Servo ElavonRight;
Servo RightMotor;
Servo LeftMotor;

//ServoPositions
int ElavonLeftPos = 0;
int ElavonRightPos = 0;

//Interstage
int ElevatorInter = 0;
int AileronInter = 0;
int ThrottleInter = 0;
int RudderInter = 0;

//MotorPower
int LeftMotorPower = 0;
int RightMotorPower = 0;

//ServoPins
const int ElavonLeftPin = 12;
const int ElavonRightPin = 13;
const int LeftMotorPin = 2;
const int RightMotorPin = 7;
//PWM input from Rx
const int ElevatorPin = 6;
const int AileronPin = 9;
const int RudderPin = 5;
const int ThrottlePin = 11;
const int ModeSwitchPin = 3;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
ElavonLeft.attach(ElavonLeftPin);
ElavonRight.attach(ElavonRightPin);
LeftMotor.attach(LeftMotorPin);
RightMotor.attach(RightMotorPin);

}

void loop() {
// Read the Positions
int AuxStickPosition = pulseIn(ModeSwitchPin, HIGH, 25000);

if (AuxStickPosition < 1300) {

int ElevatorStickPosition = pulseIn(ElevatorPin, HIGH, 25000);
int RudderStickPosition = pulseIn(RudderPin, HIGH, 25000);
int AileronStickPosition = pulseIn(AileronPin, HIGH, 25000);
int ThrottleStickPosition = pulseIn(ThrottlePin, HIGH, 25000);
int AuxStickPosition = pulseIn(ModeSwitchPin, HIGH, 25000);

//Read and convert
RudderInter = map(RudderStickPosition, 1000, 2000, -100, 100);
AileronInter = map(AileronStickPosition, 1000, 2000, -100, 100);
ThrottleInter = map(ThrottleStickPosition, 1000, 2000, -100, 100);
ElevatorInter = map(ElevatorStickPosition, 1000, 2000, -100, 100);

//wut

ElavonLeftPos = map(AileronInter - ElevatorInter, -200, 200, 45, 135);
ElavonRightPos = map(AileronInter + ElevatorInter, -200, 200, 45, 135);
RightMotorPower = map(ThrottleInter + RudderInter, -200, 200, 0, 180);
LeftMotorPower = map(ThrottleInter - RudderInter, -200, 200, 0, 180);

//Constrain
ElavonLeftPos = constrain(ElavonLeftPos, 0, 180);
ElavonRightPos = constrain(ElavonLeftPos, 0, 180);
LeftMotorPower = constrain(LeftMotorPower, 0, 180);
RightMotorPower = constrain(RightMotorPower, 0, 180);

ElavonLeft.write(ElavonLeftPos);
ElavonRight.write(ElavonRightPos);
LeftMotor.write(LeftMotorPower);
RightMotor.write(RightMotorPower);

Serial.println(ElevatorStickPosition);
Serial.println(AileronStickPosition);

delay(5);

}

else {

int AuxStickPosition = pulseIn(ModeSwitchPin, HIGH, 25000);

LeftMotor.write(0);
RightMotor.write(0);

delay(1);

}
}

Why not put some Serial.prints in to see if your theory is right and the inputs from the RC receiver are jittering?

You could also add some more to check exactly what values you are writing to the servos.

BTW are they all servos or are LeftMotor/RightMotor connected to something else like ESCs driving motors? How is everything powered?

Steve

Use the forum Google search function in the upper right of this page to search for "Servo Jitter" and similar key words. You will probably find many previous project discussions on potential causes. Below is some simple servo test code you might use to test your servos for issues.

// zoomkat 7-30-10 serial servo test
// type servo position 0 to 180 in serial monitor
// for writeMicroseconds, use a value like 1500
// Powering a servo from the arduino usually *DOES NOT WORK*.

String readString;
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

void setup() {
  Serial.begin(9600);
  myservo.attach(9);
}

void loop() {

  while (Serial.available()) {

    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
      delay(3);
    } 
  }

  if (readString.length() >0) {
    Serial.println(readString);
    int n = readString.toInt();
    Serial.println(n);
    myservo.writeMicroseconds(n);
    //myservo.write(n);
    readString="";
  } 
}

You have several servos running and this can take a fair amount of power. If you're running this on USB power, then you can probably solve your jitters by plugging into your LiPo battery (my Arduino airplane jitters like crazy when I'm just uploading new code and have the transmitter on).

Two common causes of servo jitter:
The servo ground is connected only to the servo battery and not the Arduino ground.
Something (often SoftwareSerial) is turning off interrupts for more than a few microseconds.

So, I have used Serial.print to test my theory and first off, the signal is jittery from the RC transmitter. Also, the Motor servos are used to connect to ESC's. LIPO power does not help, I am powering servos through Receiver. Connecting the ground to the arduino ground does not change anything.
And to johnwasser, how do I stop softwareserial to turn off interrupts for more than a few microseconds?
Thanks to everyone who spent a little time to help me! :slight_smile:

If your input signal is jittering then the servos aren't doing anything wrong. They're just responding to the signals you're sending to them. What transmitter and receiver are you using and what exactly is powering the receiver? That may be part of the problem.

There are ways of smoothing the signals you send to the servos but they will all either reduce the precision of positioning or increase the reaction time.

Steve

slipstick:

I am using a DX6e Tx with an AR610 Rx.
The receiver is powered by a 5v input from a power distribution board.
However the shaky signal, I do not believe is the problem. The servos shudder every half second or so, seemingly at random. Every once in a while, they go to the 0 position and come back.
Here is the updated code:

#include <Servo.h>

Servo ElavonLeft;
Servo ElavonRight;
Servo RightMotor;
Servo LeftMotor;

//ServoPositions
int ElavonLeftPos = 0;
int ElavonRightPos = 0;

//Interstage
int ElevatorInter = 0;
int AileronInter = 0;
int ThrottleInter = 0;
int RudderInter = 0;

//MotorPower
int LeftMotorPower = 0;
int RightMotorPower = 0;

//ServoPins
const int ElavonLeftPin = 12;
const int ElavonRightPin = 13;
const int LeftMotorPin = 2;
const int RightMotorPin = 7;
//PWM input from Rx
const int ElevatorPin = 6;
const int AileronPin = 9;
const int RudderPin = 5;
const int ThrottlePin = 11;
const int ModeSwitchPin = 3;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  ElavonLeft.attach(ElavonLeftPin);
  ElavonRight.attach(ElavonRightPin);
  LeftMotor.attach(LeftMotorPin);
  RightMotor.attach(RightMotorPin);

}

void loop() {
  // Read the Positions
  int AuxStickPosition = pulseIn(ModeSwitchPin, HIGH, 25000);

  if (AuxStickPosition < 1300) {

  
  int ElevatorStickPosition = pulseIn(ElevatorPin, HIGH, 25000);
  int RudderStickPosition = pulseIn(RudderPin, HIGH, 25000);
  int AileronStickPosition = pulseIn(AileronPin, HIGH, 25000);
  int ThrottleStickPosition = pulseIn(ThrottlePin, HIGH, 25000);
  int AuxStickPosition = pulseIn(ModeSwitchPin, HIGH, 25000);


  //Read and convert
  RudderInter = RudderStickPosition;
  AileronInter = map(AileronStickPosition, 1000, 2000, -150, 150);
  ThrottleInter = ThrottleStickPosition;
  ElevatorInter = map(ElevatorStickPosition, 1000, 2000, -150, 150);




  //wut
 
  
  ElavonLeftPos = map(AileronInter - ElevatorInter, -310, 310, 0, 180);
  ElavonRightPos = map(AileronInter + ElevatorInter, -310, 310, 0, 180);
  RightMotorPower = map(ThrottleInter + RudderInter, 1000, 2000, 0, 180);
  LeftMotorPower = map(ThrottleInter - RudderInter, 1000, 2000, 0, 180);
  



  //Constrain
  ElavonLeftPos = constrain(ElavonLeftPos, 0, 180);
  ElavonRightPos = constrain(ElavonRightPos, 0, 180);
  LeftMotorPower = constrain(LeftMotorPower, 0, 180);
  RightMotorPower = constrain(RightMotorPower, 0, 180);

  ElavonLeft.write(ElavonLeftPos);
  ElavonRight.write(ElavonRightPos);
  LeftMotor.write(LeftMotorPower);
  RightMotor.write(RightMotorPower);
  

  Serial.println(ThrottleStickPosition);


  delay(2);
  
  
  }

  else {
 
  int AuxStickPosition = pulseIn(ModeSwitchPin, HIGH, 25000);


  LeftMotor.write(0);
  RightMotor.write(0);

  delay(1);
  
    }
}