5

I've hooked up two ultrasonic sensors to my breadboard and I also got a 5 V motor installed. I also got the diode installed and the usual set up. I can easily control the motor with one sensor.

I want the motor to run at let's say 100 once I start it up:

  • The first sensor should be used to slowly slow down the motor when an object is placed in front of it
  • The second sensor should be used to slowly speed up the motor when an object is placed in front of it

I do not want the speed to return to 100 once the object is removed. It should remain at the same speed according to which sensor was used.

Tell me if I have to clarify anything in the comments.

Code

int motorPin = 9;
int trigPin = 13;
int echoPin = 12;
int trigPin2 = 5;
int echoPin2 = 4;

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, INPUT);
  pinMode(motorPin, OUTPUT);
}

void loop() {
  int duration, distance;
  digitalWrite (trigPin, HIGH);
  delayMicroseconds (1000);
  digitalWrite (trigPin, LOW);
  duration = pulseIn (echoPin, HIGH);
  distance = (duration/2) / 29.1;
  if (distance < 20) {  // Distance from sensor
    analogWrite (motorPin, 50);
  } else {
    int duration, distance;
    digitalWrite (trigPin2, HIGH);
    delayMicroseconds (1000);
    digitalWrite (trigPin2, LOW);
    duration = pulseIn (echoPin2, HIGH);
    distance = (duration/2) / 29.1;
    if (distance > 20) {  // Distance from sensor
      analogWrite (motorPin, 150);
    }
    if  (distance > 20) {  // Distance from sensor
      Serial.println("Out of range");
    } else {
      Serial.print(distance);
     Serial.println(" cm");
    }
    delay(500);
  }
}
5
  • Is "100" half speed? Commented Apr 13, 2014 at 20:30
  • uhm the max is 225, so I assume that the half speed should be around 112. but yeah, in my concept it's half speed Commented Apr 13, 2014 at 20:31
  • What do you want to happen if the two objects were both kept at the same time infront and at the back of the robot? This problem can be solved if you wrote down all possible combinations which is as far as i see it 4 combinations.
    – Adel Bibi
    Commented Apr 13, 2014 at 21:18
  • Well what I want when two objects were both kept at the same time is that the speed turns to normal (default) as in 100 Commented Apr 13, 2014 at 21:34
  • Is there anyway to the same thing but with a raspberry Pi and a PWM extension/driver HAT from adafruit? Same ultrasonic sensor and a single motor. What I'm trying to do is increase the speed of the motor when there's something close to the motor (also reverse direction) and keep the motor running forward as normal if the object is far away Commented Sep 17, 2017 at 18:52

1 Answer 1

1

This is very simple using the map() instruction. Here's the code you would use (feel free to modify values:

int speed = 112 + map(distance, 0, 20, 0, 112) - map(distance2, 0, 20, 0, 112);

So if both sensors gave equal values, they would offset each other. To make it still work if an object is removed, you could just use the last distance/distance_2 value and update the other.


One issue with this approach is, if the line of transformation of the object is not perpendicular to the line of the pings, the value will go:

10 → 11 → 12 → 13 → 14 → 15 → 16 → 17 → 18 → 19 → 20 → [Out of range]

I've added some pretty animations to show you what I mean:

Perpendicular:

Collinear:


As I understand, this is what you want:

int motorPin = 9;
int trigPin = 13;
int echoPin = 12;
int trigPin2 = 5;
int echoPin2 = 4;
int postdist = 112;
int postdist2 = 112;

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, INPUT);
  pinMode(motorPin, OUTPUT);
}

void loop() {
  //First Read
  int duration, distance;
  digitalWrite (trigPin, HIGH);
  delayMicroseconds (1000);
  digitalWrite (trigPin, LOW);
  duration = pulseIn (echoPin, HIGH);
  distance = (duration/2) / 29.1;
  int ltol = postdist - 5;
  int htol = postdist + 5;
  if (distance > 20 || !(distance > ltol && distance < htol)) {  // Distance from sensor
    Serial.println("Out of range");
    distance = postdist;
  }
  //Second Read
  int duration2, distance2;
  digitalWrite (trigPin2, HIGH);
  delayMicroseconds (1000);
  digitalWrite (trigPin2, LOW);
  duration2 = pulseIn (echoPin2, HIGH);
  distance2 = (duration2/2) / 29.1;
  int ltol2 = postdist2 - 5;
  int htol2 = postdist2 + 5;
  if (distance2 > 20 || !(distance2 > ltol2 && distance2 < htol2)) {  // Distance from sensor
    Serial.println("Out of range");
    distance2 = postdist2;
  }
  //Math:
  Serial.print("Distances-1: ");
  Serial.print(distance);
  Serial.print(" cm 2: ");
  Serial.print("Distances-1: ");
  Serial.print(distance2);
  Serial.println(" cm");
  postdist = distance;
  postdist2 = distance2;
  int speed = 112 + map(distance, 0, 20, 0, 112) - map(distance2, 0, 20, 0, 112); 
  if(speed < 60) {speed = 60;} //Modify 60 to meet your needs for minimum threshold
  analogWrite (motorPin, speed);
  Serial.print("Motor Speed: ");
  Serial.println(speed);
  delay(500);
}

Changelog: forgot to edit postdist/postdist2 at end of cycle, added minimum threshold, prevent very small changes in voltage to keep voltage stable and prevent noise.

4
  • Thank you for the help. Whenever I try to do it according to what you've posted above, the motor kinda acts weird. Weird as in, it just stops working all of a sudden and then starts working again. Commented Apr 14, 2014 at 9:39
  • Can you confirm that you use a transistor to drive your motor (don't connect it directly to an Arduino pin)? Also, you should use a flyback diode in parallel with it.
    – jfpoilpret
    Commented Apr 15, 2014 at 4:58
  • Yes I am using a transistor and a diode. Commented Apr 19, 2014 at 14:29
  • Chatroom created Commented Apr 19, 2014 at 16:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.