Using servo with ultrasonic distance measurer, LED and buzzer

Hi there, I'm trying to create an alarm system using a basic servo motor, buzzer, LED and ultrasonic distance measurer. The idea is that the ultrasonic is attached to the servo, which is sweeping back and forth between 0-180 degrees. WHen the ultrasonic detects a foreign object at 10cm or less, the servo will stop, and the LED and buzzer turn on and off repeatedly.

My issue with the code is that the servo doesnt stop turning, and the LED+buzzer dont turn on until the servo has done a full 180 degrees back and forth and returns to 0 degrees. i want it to stop wherever it detects the object.

Would love some help !


#include <Servo.h>
Servo myservo; 
int pos = 0; 

const int trigPin = 9;  
const int echoPin = 8;
const int buzzer = 11; 
const int ledPin = 13; 

// defines variables
long duration; 
int distance; 
int safetyDistance; 


void setup() {
pinMode(trigPin, OUTPUT); 
pinMode(echoPin, INPUT); 
pinMode(buzzer, OUTPUT); 
pinMode(ledPin, OUTPUT); 
Serial.begin(9600); on
digitalWrite(buzzer,LOW); 
myservo.attach(12);

}


void loop() {
// Clears the trigPin (trigger pin), setting it to Low (off) to begin for 2 microseconds. 
digitalWrite(trigPin, LOW);
delayMicroseconds(2); 

// Sets the trigPin on HIGH state (on) for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);

distance= duration*0.034/2; 

safetyDistance = distance;

if (safetyDistance <=10){ //If safety distance (or less) to foreign object is reached, buzzer and light turns on. Servo detaches. 
delay (10);
  digitalWrite(buzzer, HIGH); 
  digitalWrite(ledPin, HIGH);
  delay(100); //delay one second 
  digitalWrite(buzzer, LOW);
  digitalWrite(ledPin, LOW);
  delay(100);
  myservo.detach(); 
}

else{  // otherwise, if safety distance not reached, buzzer and light off.
  digitalWrite(buzzer, LOW);
  digitalWrite(ledPin, LOW);
  delay(0); //delay one second 
  myservo.attach(12);
  
  for (pos = 0; pos <=180; pos += 1) { // servo, sweeping between 0-180 degrees in steps of 1 degree
    myservo.write(pos);                 
    delay(20);                         
  }
  for (pos = 180; pos >= 0; pos -= 1) { 
    myservo.write(pos);                
    delay(20);                        
  }

  }

Welcome to the forum

Firstly, the sketch that you posted does not compile, possibly because you did not copy all of it, but thank you for using code tags in your first post

As written the servo will always do a full sweep either way before testing the distance. This is because of the for loops. You need to take advantage of the loop() function by moving the servo a little, testing the distance and acting based on it, moving the servo a little, testing the distance and acting upon it and so on

thank You, here is the code, this should hopefully compile

#include <Servo.h>
Servo myservo; 
int pos = 0; 

const int trigPin = 9;  
const int echoPin = 8; 
const int buzzer = 11; 
const int ledPin = 13; 

// defines variables
long duration; 
int distance; 
int safetyDistance; 


void setup() {
pinMode(trigPin, OUTPUT); 
pinMode(echoPin, INPUT);
pinMode(buzzer, OUTPUT); 
pinMode(ledPin, OUTPUT); 
Serial.begin(9600); 
digitalWrite(buzzer,LOW); 
myservo.attach(12);
}


void loop() {
// Clears the trigPin (trigger pin), setting it to Low (off) to begin for 2 microseconds. 
digitalWrite(trigPin, LOW);
delayMicroseconds(2); 

// Sets the trigPin on HIGH state (on) for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);

distance= duration*0.034/2; 


safetyDistance = distance;

if (safetyDistance <=10){ //If safety distance (or less) to foreign object is reached, buzzer and light turns on. 
delay (10);
  myservo.detach(); 
  digitalWrite(buzzer, HIGH); 
  digitalWrite(ledPin, HIGH);
  delay(100); //delay one second 
  digitalWrite(buzzer, LOW);
  digitalWrite(ledPin, LOW);
  delay(100);

}

else{  // otherwise, if safety distance not reached, buzzer and light off.
  digitalWrite(buzzer, LOW);
  digitalWrite(ledPin, LOW);
  delay(0); //delay one second 
  myservo.attach(12);

    for (pos = 0; pos <=180; pos += 1) { // in steps of 1 degree
    myservo.write(pos);                 
    delay(20);                         
  }
  for (pos = 180; pos >= 0; pos -= 1) { 
    myservo.write(pos);                
    delay(20);                        
  }
}
  }

This is the sort of thing that I had in mind (untested)

#include <Servo.h>
Servo myservo;

const int trigPin = 9;
const int echoPin = 8;
const int buzzer = 11;
const int ledPin = 13;

// defines variables
long duration;
int distance;
int safetyDistance;


void setup()
{
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  digitalWrite(buzzer, LOW);
  myservo.attach(12);
}

void loop()
{
  static int increment = 1;
  static int pos = 0;
  myservo.write(pos);
  pos = pos + increment;
  if (pos < 1 || pos > 179)
  {
    increment = increment * -1;
  }
  delay(20);
  checkDistance();
}

void checkDistance()
{
  // Clears the trigPin (trigger pin), setting it to Low (off) to begin for 2 microseconds.
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin on HIGH state (on) for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  distance = duration * 0.034 / 2;
  safetyDistance = distance;
  if (safetyDistance <= 10) //If safety distance (or less) to foreign object is reached, buzzer and light turns on.
  {
    delay (10);
    digitalWrite(buzzer, HIGH);
    digitalWrite(ledPin, HIGH);
    delay(100); //delay one second
    digitalWrite(buzzer, LOW);
    digitalWrite(ledPin, LOW);
    delay(100);
  }
  else   // otherwise, if safety distance not reached, buzzer and light off.
  {
    digitalWrite(buzzer, LOW);
    digitalWrite(ledPin, LOW);
  }
}

This worked, thank you !!

Do you understand how it works ?
Can you improve it ?

i understand most of it, im unfamiliar with the checkdistance function, but I assume its just checking continuously if the distance has been reached.

the only problem at the moment is the servo path is a bit jittery, im thinking it might be because the voltage is too low for everything thats running, but it still works

It is a direct copy of the code in your original sketch but in a function instead of as inline code

Look where it is called from. It checks the distance every time the servo moves

How is the servo powered ?

What sensor are you using to measure the distance?
Does it measure distances of 10 cm?

The servo is powered from 5V. and so is the buzzer and LED.

Sensor is measuring 10cm but can also measure up to 4m. Its an ultrasonic distance measurer

Where is the 5V coming from ?

Is it an external source or is it the Arduino 5V pin ?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.