My Piezo Buzzer Won't Cooperate With My Ping Ultrasonic Sensor and Servo

Hey guys and gals, I’m working on a simple robot project that will roll until it sees an obstacle 6 inches away, buzz a few times, then scans left and right (the Ping will be on the servo “neck”) to see which way it will go. Pretty simple concept, but I’m stuck on the beginning parts. Here’s the low-down:

  • The Ping and buzzer work together, although the Ping’s scans slow down a bit whilst buzzing. Not really a problem though.
  • The buzzer and the servo hate each other. When the servo works, the buzzer doesn’t even though it was working before hand.(I’ve found that this happens after I write “servoNeck.attach(6)” in the program. I’ve also found putting this line after the three beeps in "void setup() makes the buzzer work for those three beeps, but none of the others.)
  • When the servo is turning, the Ping stops scanning, which defeats the purpose of the neck servo in the first place.

I’m not working on motors and wheels yet, just this part. Here’s the code I have so far (sorry if it’s ugly, I’m kinda new at this):

  const int ledBoard = 13;
  const int pingPin = 7;
  int speakerOut = 10;
  #include <Servo.h>
  Servo servoNeck;
  
  void setup() {
    Serial.begin(9600);
    servoNeck.attach(6);
    servoNeck.write(90);
    pinMode(ledBoard, OUTPUT);
    pinMode(speakerOut, OUTPUT);
    beep(50);
    beep(50);
    beep(50);
    delay(1000);
  }
  
  void loop() {
    long duration, inches, cm;
    
    pinMode(pingPin, OUTPUT);
    digitalWrite(pingPin, LOW);
    delayMicroseconds(2);
    digitalWrite(pingPin, HIGH);
    delayMicroseconds(5);
    digitalWrite(pingPin, LOW);
    
    pinMode(pingPin, INPUT);
    duration = pulseIn(pingPin, HIGH);
    
    inches = microsecondsToInches(duration);
    cm = microsecondsToCentimeters(duration);
    
    Serial.print(inches);
    Serial.print("in, ");
    Serial.print(cm);
    Serial.print("cm");
    Serial.println();
  
    delay(100);
    
     if (inches <= 5) {
      digitalWrite(ledBoard, HIGH);
      
      beep(100);
      delay(1000);
      servoNeck.write(0);
      delay(500);
      servoNeck.write(90);
      delay(500);
      servoNeck.write(180);
      delay(500);
      servoNeck.write(90);
      delay(5000);
     }
    else {
     digitalWrite(ledBoard, LOW);
   }
} 

void beep (unsigned char delayms) {
  analogWrite(10, 20);
  delay(delayms);
  analogWrite(10, 0);
  delay(delayms);
}


long microsecondsToInches(long microseconds) {
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds) {
  return microseconds / 29 / 2;
}

I have been trying and trying to find a solution to this, and I know everything is hooked up correctly since it all works individually. I GREATLY appreciate ANY guidance you guys may have for a beginner roboticist like me. Thank you!

The most obvious recent for the devices working separately but not together, would be an inadequate power supply. You cannot drive a servo directly from the arduino.

Using the Servo library disables PWM output on pins 9 and 10 on boards other than the Mega. Guess which pin you are using for the speaker .....

Using the Servo library disables PWM output on pins 9 and 10 on boards other than the Mega. Guess which pin you are using for the speaker .....

I switched to PWM pin 11 and it works better now! It now beeps once when the servo activates, which leads me to believe....

michinyon: The most obvious recent for the devices working separately but not together, would be an inadequate power supply. You cannot drive a servo directly from the arduino.

That I need an extra battery just for the servo. Is this correct? The Ping still doesn't work with the servo turning, but I think it is the aforementioned battery problem. However, when I unplug the servo from the circuit, it still does this. Any more suggestions?

Whether or not it is causing problems presently it is important that you do not power the servo from the Arduino 5V and GND pins as its voltage regulator is only able to supply limited current and could easily be damaged.

  if (inches <= 5) {
    digitalWrite(ledBoard, HIGH);

    beep(100);
    delay(1000);
    servoNeck.write(0);
    delay(500);
    servoNeck.write(90);
    delay(500);
    servoNeck.write(180);
    delay(500);
    servoNeck.write(90);
    delay(5000);
  }

Whilst the servo is moving you are not doing any distance measurement. You need to change the scanning portion of the code. Move the servo a little bit, measure distance, move it again and so on. As it is at the moment all you do is move the servo and wait a bit. Move it, wait again and so on.