Sonar using Arduino

SUPPLIES AND COMPONENTS :

HC-SR04 Ultrasonic Sensor for Arduino UNO (Generic)

INTRODUCTION TO THE PROJECT :

Sensor readings for each degree moved by the servo values are delivered to the serial port, where Processing may take them up.

Server.ino

#include <Servo.h> 
 
#define TRIGGER_PIN  2   // Arduino pin 2 tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     3   // Arduino pin 3 tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 150 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
#define SERVO_PWM_PIN 9 //set servo to Arduino's pin 9
 
// means -angle .. angle
#define ANGLE_BOUNDS 80
#define ANGLE_STEP 1
 
int angle = 0;
 
// direction of servo movement 
// -1 = back, 1 = forward 
int dir = 1;
 
Servo myservo;
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); 
 
void setup() {
  Serial.begin(9600); // initialize the serial port:
  myservo.attach(SERVO_PWM_PIN); //set servo to Arduino's pin 9
}
 
void loop() {
 
  delay(50);
  // we must renormalize to positive values, because angle is from -ANGLE_BOUNDS .. ANGLE_BOUNDS
  // and servo value must be positive
  myservo.write(angle + ANGLE_BOUNDS);
  
  // read distance from sensor and send to serial
  getDistanceAndSend2Serial(angle);
  
  // calculate angle 
  if (angle >= ANGLE_BOUNDS || angle <= -ANGLE_BOUNDS) {
    dir = -dir;
  }
  angle += (dir * ANGLE_STEP);  
}
 
int getDistanceAndSend2Serial(int angle) {
  int cm = sonar.ping_cm();
  Serial.print(angle, DEC);
  Serial.print(",");
  Serial.println(cm, DEC);
  
}

From a top-down perspective, this map shows what the HC-SR04 views. Takes and displays two left-to-right and right-to-left readings. The average of the two measurements is displayed.

Processing.pde

import processing.serial.*;
 
int SIDE_LENGTH = 1000;
int ANGLE_BOUNDS = 80;
int ANGLE_STEP = 2;
int HISTORY_SIZE = 10;
int POINTS_HISTORY_SIZE = 500;
int MAX_DISTANCE = 50;
 
int angle;
int distance;

/ choose either color or background image /
color bgcolor = color (255,0,0);
PImage bgimage = loadImage("test.png");
 
int radius;
float x, y;
float leftAngleRad, rightAngleRad;
 
float[] historyX, historyY;
Point[] points;
 
int centerX, centerY;
 
String comPortString;
Serial myPort;
 
void setup() {
  size(SIDE_LENGTH, SIDE_LENGTH/2, P2D);
  noStroke();
  //smooth();
  rectMode(CENTER);
 
  radius = SIDE_LENGTH / 2;
  centerX = width / 2;
  centerY = height;
  angle = 0;
  leftAngleRad = radians(-ANGLE_BOUNDS) - HALF_PI;
  rightAngleRad = radians(ANGLE_BOUNDS) - HALF_PI;
 
  historyX = new float[HISTORY_SIZE];
  historyY = new float[HISTORY_SIZE];
  points = new Point[POINTS_HISTORY_SIZE];
 
  myPort = new Serial(this, "COM11", 9600);
  myPort.bufferUntil('\n'); // Trigger a SerialEvent on new line
}
 
 
void draw() {
 
/ choose either bgcolor or bgimage /
  
  background(bgimage);

  drawRadar();
  drawFoundObjects(angle, distance);
  drawRadarLine(angle);

 / draw the grid lines on the radar every 30 degrees and write their values 180, 210, 240 etc.. /
  for (int i = 0; i <= 6; i++) {
    strokeWeight(1);
    stroke(0,255,0);
    line(radius, radius, radius + cos(radians(180+(30*i)))*SIDE_LENGTH/2, radius + sin(radians(180+(30*i)))*SIDE_LENGTH/2);
    fill(255, 255, 255);
    noStroke();
    text(Integer.toString(0+(30*i)), radius + cos(radians(180+(30*i)))*SIDE_LENGTH/2, radius + sin(radians(180+(30*i)))*SIDE_LENGTH/2, 25, 50);
  }

/ Write information text and values. /
  noStroke();
  fill(0);
int Degrees=0;

if (angle>0 & angle <80)
{
  Degrees = angle+100;
}
else if (angle<0 & angle >-80)
{
  Degrees = angle+80;
}

  fill(0, 300, 0);
  text("Degrees: "+Integer.toString(Degrees), 100, 460, 100, 50);   text("degree", 200, 460, 100, 50);      // use Integet.toString to convert numeric to string as text() only outputs strings
  text("Subject Distance: "+Integer.toString(distance), 100, 480, 200, 30);  text("mm", 200, 490, 100, 50);       // text(string, x, y, width, height)
  text("Radar screen code at www.faweiz.com/radar", 900, 480, 250, 50);
  
  text("0", 620, 500, 250, 50);
  text("50 mm", 600, 420, 250, 50);

  text("100 mm", 600, 320, 250, 50);

  text("150 mm", 600, 220, 250, 50);
  
  text("200 mm", 600, 120, 250, 50);
  
  text("250 mm", 600, 040, 250, 50);
   
  noFill();
  rect(70,60,200,200);
  fill(0, 250, 0); 
  text("Screen Key:", 100, 50, 150, 50);
  fill(0,50,0);
  rect(30,53,10,10);
  text("Far", 115, 70, 150, 50);
  fill(0,110,0);
  rect(30,73,10,10);
  text("Near", 115, 90, 150, 50);
  fill(0,170,0);
  rect(30,93,10,10);
  text("Close", 115, 110, 150, 50);
}
 
void drawRadarLine(int angle) {
 
  float radian = radians(angle);
  x = radius * sin(radian);
  y = radius * cos(radian);
 
  float px = centerX + x;
  float py = centerY - y;
 
  historyX[0] = px;
  historyY[0] = py;
  
  int Degrees=0;
  if (angle>0 & angle <80)
  {
    Degrees = angle+100;
  }
  else if (angle<0 & angle >-80)
  {
    Degrees = angle+80;
  }
   
   //get rgb color from http://www.rapidtables.com/web/color/RGB_Color.htm
    fill(0, 153, 0); 
    
    float b = centerY;
    
    arc(centerX,centerY,SIDE_LENGTH, SIDE_LENGTH,radians(angle-100),radians(angle-90));
        
    shiftHistoryArray();
}
 
void drawFoundObjects(int angle, int distance) {
 
  if (distance > 0) {
    float radian = radians(angle);
    x = distance * sin(radian);
    y = distance * cos(radian);
 
    int px = (int)(centerX + x);
    int py = (int)(centerY - y);
 
    points[0] = new Point(px, py);
  }
  else {
    points[0] = new Point(0, 0);
  }
  for (int i=0;i<POINTS_HISTORY_SIZE;i++) {
 
    Point point = points[i];
  
    if (point != null) {
 
      int x = point.x;
      int y = point.y;
 
      if (x==0 && y==0) continue;
 
      int colorAlfa = (int)map(i, 0, POINTS_HISTORY_SIZE, 20, 0);
      int size = (int)map(i, 0, POINTS_HISTORY_SIZE, 30, 5);
 
      fill(0, 255, 0, colorAlfa);
      noStroke();
      ellipse(x, y, size, size);
    }
    
    fill(255, 0, 0);
  }
  
 shiftPointsArray();
  
}
 
void drawRadar() {
  stroke(0,255,0);
  noFill();
  // make 5 circle with 50mm each
  for (int i = 0; i <= (SIDE_LENGTH / 200); i++) {
    arc(centerX, centerY, 200  i, 200  i, leftAngleRad, rightAngleRad);
  }
}                              
 
void shiftHistoryArray() {
 
  for (int i = HISTORY_SIZE; i > 1; i--) {
 
    historyX[i-1] = historyX[i-2];
    historyY[i-1] = historyY[i-2];
  }
}
 
void shiftPointsArray() {
 
  for (int i = POINTS_HISTORY_SIZE; i > 1; i--) {
 
    Point oldPoint = points[i-2];
    if (oldPoint != null) {
 
      Point point = new Point(oldPoint.x, oldPoint.y);
      points[i-1] = point;
    }
  }
}
 
void serialEvent(Serial cPort) {
 
  comPortString = cPort.readStringUntil('\n');
  if (comPortString != null) {
 
    comPortString=trim(comPortString);
    String[] values = split(comPortString, ',');
    
    try {
    
      angle = Integer.parseInt(values[0]);
      distance = int(map(Integer.parseInt(values[1]), 1, MAX_DISTANCE, 1, radius));   
    } catch (Exception e) {}
  }
}
 
class Point {
  int x, y;
 
  Point(int xPos, int yPos) {
    x = xPos;
    y = yPos;
  }
 
  int getX() {
    return x;
  }
 
  int getY() {
    return y;
  }
}

CODE :

#include <NewPing.h>
#include <Servo.h> 
 
#define TRIGGER_PIN  2   // Arduino pin 2 tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     3   // Arduino pin 3 tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 150 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
#define SERVO_PWM_PIN 9 //set servo to Arduino's pin 9
 
// means -angle .. angle
#define ANGLE_BOUNDS 80
#define ANGLE_STEP 1
 
int angle = 0;
 
// direction of servo movement 
// -1 = back, 1 = forward 
int dir = 1;
 
Servo myservo;
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); 
 
void setup() {
  Serial.begin(9600); // initialize the serial port:
  myservo.attach(SERVO_PWM_PIN); //set servo to Arduino's pin 9
}
 
void loop() {
 
  delay(50);
  // we must renormalize to positive values, because angle is from -ANGLE_BOUNDS .. ANGLE_BOUNDS
  // and servo value must be positive
  myservo.write(angle + ANGLE_BOUNDS);
  
  // read distance from sensor and send to serial
  getDistanceAndSend2Serial(angle);
  
  // calculate angle 
  if (angle >= ANGLE_BOUNDS || angle <= -ANGLE_BOUNDS) {
    dir = -dir;
  }
  angle += (dir * ANGLE_STEP);  
}
 
int getDistanceAndSend2Serial(int angle) {
  int cm = sonar.ping_cm();
  Serial.print(angle, DEC);
  Serial.print(",");
  Serial.println(cm, DEC);
  
}

“Be the reason for someone else smile” – KP

Helping Hands.

About the author

pondabrothers

View all posts

1 Comment

Leave a Reply

Your email address will not be published.