Go Down

Topic: Servo Jitter (Read 9294 times) previous topic - next topic

codlink

Aug 20, 2012, 09:16 pm Last Edit: Aug 20, 2012, 10:09 pm by codlink Reason: 1
I have a robotic head with eyelids and eyes that are controlled by servos.  Eyelids have one servo each and eyes move left-right by a servo as well as up-down by a servo.  The up-down, left-right is currently being controlled by a parallax joystick.  My problem is that if I comment out the portion of the code for the joystick, the jitter stops.  The jitter is pretty significant jumping.  Like the code is delaying for a second at a time.  But I have no delay.  Right now everything is on a breadboard, except for the servos.

I am teaching myself C programming and any advice if this jitter is code related would be most helpful.  

UPDATE:  Fixed the -80 that AWOL mentioned.

Code: [Select]
#include <Servo.h>

#define trigPin 8   //sets trigger pin on HC-SR04
#define echoPin 9   //sets Echo pin "
Servo righteyelid;  //sets name of Right Eye
Servo lefteyelid;   //sets name of Left Eye
int pos = 0;        

Servo EyeUpDown;  // create servo object to control a servo
Servo EyeLeftRight;  // create servo object to control a servo

int potpin = A1;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin
int potpin2 = A2;  // analog pin used to connect the potentiometer
int val2;    // variable to read the value from the analog pin

void setup() {
 Serial.begin (9600);
 EyeUpDown.attach(46);  // attaches the servo on pin to the servo object
 EyeLeftRight.attach(48);   // attaches the servo on pin to the servo object
 righteyelid.attach(50);// attaches servo on Right Eye Lid
 lefteyelid.attach(52); // attaches servo on Left Eye LID
 pinMode(trigPin,OUTPUT);
}

void loop() {
 int duration, distance;
 digitalWrite(trigPin, HIGH);
 //delayMicroseconds(1000);
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 distance = (duration/2) / 29.1;         //Calculates how far an object is
 
 //Open and close eye lids based on distance measurement from Sensor
 
 if (distance <= 10)                     //if distance is less than 10 cm, close eye lids
 {
   Serial.print(distance);
   Serial.println(" cm");
   righteyelid.write(60);                //Closed postion of Right Eye
   lefteyelid.write(135);                //Closed position of Left Eye
 }
 else
 {
   Serial.print(distance);
   Serial.println(" cm");
   righteyelid.write(95);               //open postion of Right Eye
   lefteyelid.write(96);                //open postion of Left Eye
 }
 {
   val = analogRead(potpin);              // reads the value of the potentiometer (value between 0 and 1023)
   val = map(val, 40, 1023, 40, 170);      // scale it to use it with the servo (value between 0 and 180)
   EyeUpDown.write(val);                    // sets the servo position according to the scaled value

   val2 = analogRead(potpin2);            // reads the value of the potentiometer (value between 0 and 1023)
   val2 = map(val2, 0, 1023, 40, 150);   // scale it to use it with the servo (value between 0 and 180)
   EyeLeftRight.write(val2);                  // sets the servo position according to the scaled value
 }
}


//LiNK

AWOL

-80 seems (is) a very unlikely value to be returned by an analogRead.
Why are you mapping it like that?

Meanwhile, how are the servos powered?
"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.
I speak for myself, not Arduino.

codlink

#2
Aug 20, 2012, 10:07 pm Last Edit: Aug 20, 2012, 10:10 pm by codlink Reason: 1
Sorry the -80 was an alignment problem.  Should have corrected that before I posted the code.  

Servos are powered by an adjustable bench power supply running at ~7v.  I tried changing the voltages from 5-9v, but doesn't make a difference.
//LiNK

PeterH



My problem is that if I comment out the portion of the code for the joystick, the jitter stops.



The jitter stopping is a problem? What jitter is this?

codlink

The jitter stops on all servos when the joystick portion is commented out.  Obviously, those servos don't work but the eyelid servos work perfectly.  So I believe it has something to do with the code for the joystick.  It maybe just noise.  I wanted to see if anyone had any comments about this code.
//LiNK

pito

..the joystick value could easily jump  +/-3 when using longer wires.. try to connect 100nF capacitors onto analog inputs (analog input--100nF--GND)..

PeterH


The jitter stops on all servos when the joystick portion is commented out.  Obviously, those servos don't work but the eyelid servos work perfectly.  So I believe it has something to do with the code for the joystick.  It maybe just noise.  I wanted to see if anyone had any comments about this code.


Which is the 'joystick portion' you refer to? I noticed there is a block of code around the call to analogRead(potpin) which is in a block for no apparent reason. Is this the code which provokes the problem?

codlink

Hmm..  I feel like an idiot.. I have my youngest child starting kindergarten today.

Anyway,  I had it backwards.  I can comment out the below code and the joystick portion works fine with NO jitters/jumps.    Is it the Serial.print that could be a problem?  Maybe the "calls(?)" to the HC-SR04 (Ultrasonic sensor)?

Code: [Select]
int duration, distance;
  digitalWrite(trigPin, HIGH);
  //delayMicroseconds(1000);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;         //Calculates how far an object is
 
  //Open and close eye lids based on distance measurement from Sensor
 
  if (distance <= 10)                     //if distance is less than 10 cm, close eye lids
  {
    Serial.print(distance);
    Serial.println(" cm");
    righteyelid.write(60);                //Closed postion of Right Eye
    lefteyelid.write(135);                //Closed position of Left Eye
  }
  else
  {
    Serial.print(distance);
    Serial.println(" cm");
    righteyelid.write(95);               //open postion of Right Eye
    lefteyelid.write(96);                //open postion of Left Eye
  }
//LiNK

AWOL

Could be time outs.
Have a look around for teckel's sonar library
"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.
I speak for myself, not Arduino.

codlink

Thanks AWOL, I will take a look. 

Thanks for the help!
//LiNK

codlink


..the joystick value could easily jump  +/-3 when using longer wires.. try to connect 100nF capacitors onto analog inputs (analog input--100nF--GND)..


Tried the Caps but no luck.  The wires right now are ~6in jumper wires on a breadboard.  It could be just noise as I have other things connected.  But nothing high voltage.


Could be time outs.
Have a look around for teckel's sonar library


Also implemented his library with no luck on getting the jitters out. 

Revised Code:

Code: [Select]
#include <Servo.h>
#include <NewPing.h>

#define TRIGGER_PIN  8  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     9  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

unsigned int pingSpeed = 50; // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
unsigned long pingTimer;     // Holds the next ping time.

Servo righteyelid;
Servo lefteyelid;     

Servo EyeUpDown;
Servo EyeLeftRight;

int potpin = A1;   // analog pin used to connect the potentiometer
int val;           // variable to read the value from the analog pin
int potpin2 = A5;  // analog pin used to connect the potentiometer
int val2;          // variable to read the value from the analog pin

void setup() {
  Serial.begin (115200);
  EyeUpDown.attach(46);
  EyeLeftRight.attach(48);
  righteyelid.attach(50);    // attaches servo on Right Eye Lid
  lefteyelid.attach(52);     // attaches servo on Left Eye Lid
}

void loop() {
  unsigned int uS = sonar.ping();     // Send ping, get ping time in microseconds (uS).
  Serial.print("Ping: ");
  Serial.print(uS / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside set distance range)
  Serial.println("cm");

  if (uS / US_ROUNDTRIP_CM <= 8 && uS / US_ROUNDTRIP_CM > 0)         //if distance is less than 8 cm, close eye lids
  {
    righteyelid.write(60);                //Closed postion of Right Eye
    lefteyelid.write(135);                //Closed position of Left Eye
  }
  else
  {
    righteyelid.write(95);                //open postion of Right Eye
    lefteyelid.write(96);                 //open postion of Left Eye
  }
  {
    val = analogRead(potpin);             // reads the value of the potentiometer (value between 0 and 1023)
    val = map(val, 0, 1023, 40, 170);     // scale it to use it with the servo (value between 0 and 180)
    EyeUpDown.write(val);                 // sets the servo position according to the scaled value

    val2 = analogRead(potpin2);            // reads the value of the potentiometer (value between 0 and 1023)
    val2 = map(val2, 0, 1023, 40, 150);    // scale it to use it with the servo (value between 0 and 180)
    EyeLeftRight.write(val2);              // sets the servo position according to the scaled value
  }
}
//LiNK

PeterH

Are you saying the jitter occurs when you read the ultrasonic sensor?

I don't know how you're accessing the sensor, but does it involve disabling interrupts? I think the Servo library relies on timer interrupts. If this is the problem, you could probably reproduce it by setting all the servos to a constant position and then just reading the sensor repeatedly. I don't know how you would resolve it, but one option might be to detach the servos while you take a reading.

codlink


Are you saying the jitter occurs when you read the ultrasonic sensor?

I don't know how you're accessing the sensor, but does it involve disabling interrupts? I think the Servo library relies on timer interrupts. If this is the problem, you could probably reproduce it by setting all the servos to a constant position and then just reading the sensor repeatedly. I don't know how you would resolve it, but one option might be to detach the servos while you take a reading.


I think you may have realized my problem.  I have read on this forum about the servo library and the ultrasonic sensor using Interrupts.  I do not know which Interrupt Servo library is using.  I just skimmed through the library and I know that my 4 servos are on one interrupt.  I just don't know which one..  I am using the Mega...  If I could get some hints on where to look in the library would be beneficial for my understanding.

If I can find out which interrupt the Mega is running the servos, I am sure I could find the NewPing library interrupts and see if I can change them.

I have attached the Servo library.
//LiNK

Go Up