Servo Library and NewPing Interrput Conflict?

I have a Mega2560 with a HC-SR04 Ping sensor with a few servos. I have set up so that if the ping is under a curtain distance, the servo activates. Unfortunately, I have other servos that are not controlled by the Ping sensor and I believe that they are running on the same interrupt. This is making the servos "jump" around. I am not %100 sure that this is an interrupt conflict but I cannot find anything else that is causing the servos to jump.

The other servos are being controlled by a joystick. The joystick isn't permanent because I will eventually have them operating with face recognition. I am just doing one step at a time..

The project is a robotic "head" with eyes and eyelids being controlled by servos. The Ping sensor is for the eyelids. If an object gets to close to the face, the eyelids close.

I do not know much about interrupts and I am currently researching this, but figured if anyone would be willing to help out in anyway, it would be greatful.

I am attaching the libraries.

#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
  }
}

NewPing.cpp (10.2 KB)

NewPing.h (8.73 KB)

Servo.cpp (12.2 KB)

Servo.h (5.53 KB)

You do not mention how you are powering all of this hardware which is the first question ?

Duane B

Here is the thread that started this line of thinking: http://arduino.cc/forum/index.php/topic,119408.0.html

Servos are powered by a bench supply running at 7v. Arduino is powered by USB. All of common ground. Tried decoupling caps but with no change.

In a few days, they will all be battery powered. Waiting for the large rechargeable battery to be shipped.

Servos, commanded using the Servo library are sent new position data based on timers. There are limited number of timers available. Those same timers are responsible for PWM on the PWM pins. Using a pin for a servo effectively removes the ability to perform PWM on some pins. Which ones depends on which timers has been usurped for the Servo libraries use. Which timer is usurped depends on the pin the servo is connected to.

Timers trigger interrupts when the timer ticks. How that would affect the pulseIn() is unclear.

Ping sensors do not return a value to an analog pin. Some other kinds of ultrasonic sensors do. You realyl would need to tell us what kind of sensor you really have.

You include the NewPing header file, but never instance the NewPing class. Including the NewPing header file is, therefore, useless. Why do you do it?

PaulS:
Servos, commanded using the Servo library are sent new position data based on timers. There are limited number of timers available. Those same timers are responsible for PWM on the PWM pins. Using a pin for a servo effectively removes the ability to perform PWM on some pins. Which ones depends on which timers has been usurped for the Servo libraries use. Which timer is usurped depends on the pin the servo is connected to.

Is it possible to change servo pins to correct this?

PaulS:
Ping sensors do not return a value to an analog pin. Some other kinds of ultrasonic sensors do. You realyl would need to tell us what kind of sensor you really have.

I have a HC-SR04. Datasheet

PaulS:
You include the NewPing header file, but never instance the NewPing class. Including the NewPing header file is, therefore, useless. Why do you do it?

I used the example code from the NewPing library. Not entirely sure what you are referring to here..

// ---------------------------------------------------------------------------
// Example NewPing library sketch that does a ping about 20 times per second.
// ---------------------------------------------------------------------------

#include <NewPing.h>

#define TRIGGER_PIN  12  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     11  // 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.

void setup() {
  Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
}

void loop() {
  delay(50);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  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");
}

Is it possible to change servo pins to correct this?

Of course. That's why I mentioned it.

Not entirely sure what you are referring to here..

Upon re-reading your code, I was wrong. I missed the bit where you actually read the ping sensor, and say the part where you are reading the potentiometer, and thought that that was trying to read something from the ping sensor. Sorry about that.

The ping sensor does nothing with PWM. The Servo library doesn't either. However, the Servo library does use timers, which interferes with the ability to use PWM on certain pins, depending on which pins the servos are connected to. I'd try, if possible, to not use PWM pins for the ping sensor. The analog pins can be used as digital pins, if you are low on/out of digital-only pins.

I actually did rearrange the pins last night after you reply. It did help in a way. The servos that are controlled by the Ping sensor stop jittering with the other servos. But the servos connected to the joystick are still jittering. I am thinking that the joystick is getting some kind of noise from somewhere. Since the joystick is not going to be the permanent solution for those servos, I will not worry about those for now. I may stick my O-scope on them just out of curiosity.

Just for information if anyone else is having similar problems, here is a spreadsheet that states what pins are on what timers. https://spreadsheets.google.com/pub?key=rtHw_R6eVL140KS9_G8GPkA&gid=0

Thanks for the help Paul.