Servo motor with a ultrasonic sensor

I'm fairly new to Arduino's and C++ coding and have been given a few projects to help me learn the ropes.
One of them is to use a servo motor with a ultrasonic sensor where depending on where the sensor picks up the distance the motor moves. Right now I have found a line of code online as a base but it only has 2 movements 0 and 180. I want for it to be where the servo motor moves depending on where the sensor picks it up from all the numbers from 0 to 180 degrees on the motor not just 0 and 180. Any tips on what to change and do to fix would be greatly appreciated.

#include <Servo.h>

// constants won't change
const int TRIG_PIN  = 6;  // Arduino pin connected to Ultrasonic Sensor's TRIG pin
const int ECHO_PIN  = 7;  // Arduino pin connected to Ultrasonic Sensor's ECHO pin
const int SERVO_PIN = 9; // Arduino pin connected to Servo Motor's pin
const int DISTANCE_THRESHOLD = 50; // centimeters

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

// variables will change:
float duration_us, distance_cm;

void setup() {
  Serial.begin (9600);       // initialize serial port
  pinMode(TRIG_PIN, OUTPUT); // set arduino pin to output mode
  pinMode(ECHO_PIN, INPUT);  // set arduino pin to input mode
  servo.attach(SERVO_PIN);   // attaches the servo on pin 9 to the servo object
  servo.write(0);
}

void loop() {
  // generate 10-microsecond pulse to TRIG pin
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  // measure duration of pulse from ECHO pin
  duration_us = pulseIn(ECHO_PIN, HIGH);
  // calculate the distance
  distance_cm = 0.017 * duration_us;

  if (distance_cm < DISTANCE_THRESHOLD)
    servo.write(180); // rotate servo motor to 90 degree
  else
    servo.write(0);  // rotate servo motor to 0 degree

  // print the value to Serial Monitor
  Serial.print("distance: ");
  Serial.print(distance_cm);
  Serial.println(" cm");

  delay(500);
}

I do not know what you mean there and the code does not give me a clue. Please explain, in detail, how the servo should react to the distance measured by the rangefinder. Should the servo indicate the range like a needle on a gauge? What are the extremes (closest, farthest) to measure and indicate?

Use the map function to convert distance to an angle, a servo position. Check Arduino/reference for mapping.

1 Like

Convert the interesting values of distance_cm (whatever they are) into an angle suitable for writing to the servo (0-180). Then just write that to the servo. The map() function will probably help.

Steve

It sounds to me like you want the servo to move the ultrasonci rangefinder from side to side and note the direction to the (nearest?) object.

To do that you need the File->Examples->Servo->Sweep for a start (that sweeps the servo side to side) and you need, at each position, to measure the distance and see if the measures distance is less than the previous nearest distance. If it is, store the servo angle and store the current distance as the previous nearest distance.

Note: Because you will be measuring the distance in both the left-to-right and right-to-left sweeps it would be good to write a function to do the measurement instead of putting all the code in both places.

@ superspeedyy

Other post/duplicate DELETED
Please do NOT cross post / duplicate as it wastes peoples time and efforts to have more than one post for a single topic.

Continued cross posting could result in a time out from the forum.

Could you also take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

I have a servo and ultrasonic sensor and want to map the ultrasonic cm readings to the servo motor. currently the ultrasonic reads on the serial monitor but the servo motor doesn't respond and only twitches and only goes a few degrees and stops. I'm fairly new to coding and everything so sorry in advanced for the sloppy coding.

#include <Servo.h>
int trig = 6;
int echo = A0;
int servo = 9;
Servo myServo;
float duration_us, distance_cm;

void setup() {
  Serial.begin(9600);
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  myServo.attach(9); 
  myServo.write(0);
}

void loop(){
  distance_cm = analogRead(A0);
  duration_us = map(distance_cm, 0, 1023, 0, 255);
  myServo.write(distance_cm);
  digitalWrite(trig,  HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  duration_us = pulseIn(echo, HIGH);
  distance_cm = 0.017 * duration_us;
  Serial.print("distance");
  Serial.print(distance_cm);
  Serial.println("cm");

  delay(500);
}

Code is not complete and will not compile. Also it makes no sense. You read a value from analog pin A0 into distance_cm. Then you map that into duration_us. Then you write distance_cm to the servo. And only then do you check the ultrasonic sensor.

Steve

Ok I went ahead and changed what you suggested thanks for the reply it seems to fixed some stuff and now the servo motor rotates all 180 degrees but not following any set number from the sensor would it have something to do with the mapping numbers being to large of numbers? and this is the new void loop section

void loop(){
  digitalWrite(trig,  HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  duration_us = pulseIn(echo, HIGH);
  distance_cm = 0.017 * duration_us;  
  Serial.print("distance");
  Serial.print(distance_cm);
  Serial.println("cm");
  distance_cm = analogRead(A0);
  distance_cm = map(duration_us, 0, 1023, 0, 255);
  myServo.write(distance_cm);

You probably mean

distance_cm = duration_us  / 4;

Insert a print as shown to monitor the value of duration_us. Servos usually only go to 180°. Trying to run it beyond 180° can cause damage.

What is connected to A0? That is the only reading that you use, the rangefinder output is ignored.
You print the rangefinder output, but use A0.

if your asking what is connected to the A0 pin it is the echo pin on the ultrasonic sensor and then if you have the serial print for the distance and duration would I get rid of the other prints I have?

First let us find out what rangefinder that you are using. Is it a HC SR 04 type? I am going to assume so.

I am not sure that you know how a rangefinder works. The range is not reported through A0 as an analog value. The echo signal will be HIGH or LOW (255 or 0). If it is HIGH the map will make distance_cm 255 which is beyond what the servo can do. Using analogRead on the echo pin is pointless. The distance is calculated from the duration returned by the pulseIn() function.

You need to remove the analogRead line. Then you need to know what values you are actually getting in distance_cm. Your Serial.prints will tell you that. When you have the minimum and maximum values THOSE are what you put in the first part of the map() command. The second part should be 0, 180 because that is the range of values that servo.write() takes.

Steve

@superspeedyy
You were warned in reply #6 about duplicate questions. I've merged your 2 questions on the same subject and given you a break from posting until Friday.

Thank you.