This is a start guide for using distance sensors with Arduino and some Processing. We have used these sensors:
SHARP GP2Y0A21YK0F
Distance Measuring Sensor Unit
Composed of an integrated combination of PSD (position sensitive detector) , IRED (infrared emitting diode) and signal processing circuit
Measuring distance: 10 to 80 cm
Analog output type
Datasheet: http://www.sharpsma.com/webfm_send/1489 (Sharp, 09.10.14)
Sharp GP2Y0D810Z0F
Digital Distance Sensor
Measuring distance: 2 to 10 cm
Analog output type
Datasheet: http://www.pololu.com/file/0J154/GP2Y0D810Z0F.pdf (Sharp, 09.10.14)
LV-MaxSonar®-EZ1™
Sonar Range Finder
MaxSonar's top features is low cost, high quality ultrasonic distance sensors, no sensor dead zone, calibrated beam patterns, stable range readings and low power demands
Measuring distance: 0 to 645 cm
Analog Voltage, Serial, Pulse Width
Datasheet: http://www.maxbotix.com/documents/MB1010_Datashee... (Maxbotix, 09.10.14)
This video summarizes our experimentation and ideas.
Fritzing:
See the first image.
Code:
int i;<br>int val; int redpin=0; void setup() { pinMode(redpin,OUTPUT); Serial.begin(9600); } void loop() { i=analogRead(redpin); val=(6762/(i-9))-4; Serial.println(val); }
The code is from this comment field: https://www.sparkfun.com/products/242 (oscarvs, 09.10.14)
Fritzing:
See the second image.
Code:
By using this code, the sensor sends out a digital pulse for Arduino to messure the distance of an object. When using the analog pin, the sensor itself is calculating the distance, for us this way was very inaccurate. It was even more inaccurate when adding multiple sensors and an LCD screen to display the output. We recommend using the digital pin, if you decide to use the analoge pin make sure you have a steady voltage.
We changed the code so cm is the only output, the original code had inches and cm.
//Original author: Bruce Allen //Date: 23/07/09 //Changed by Marte and Runar 09/10/14, to only have cm as output<br>//Digital pin 7 for reading in the pulse width from the MaxSonar device. //This variable is a constant because the pin will not change throughout execution of this code. const int pwPin = 7; //variables needed to store values long pulse, inches, cm; int output; <br>void setup() {<br> //This opens up a serial connection to shoot the results back to the PC console Serial.begin(9600);<br>} <br>void loop() {<br>pinMode(pwPin, INPUT);<br>//Used to read in the pulse that is being sent by the MaxSonar device. //Pulse Width representation with a scale factor of 147 uS per Inch.<br>pulse = pulseIn(pwPin, HIGH); //147uS per inch inches = pulse/147; //change inches to centimetres cm = inches * 2.54;<br>// Serial.print(inches); // Serial.print("in, "); // Serial.print(cm); // Serial.print("cm"); // Serial.println(); output= map(cm,0,645);<br>Serial.println(output);<br>delay(1); }
We found the code here, under PW: http://playground.arduino.cc/Main/MaxSonar (Allen, 09.10.14)
You could see the analog code under Analog.
Other usefull links to stabilize the analouge read:
Random value drops: http://forum.arduino.cc/index.php/topic,20920.0.ht... (Arduino forum, 10.10.14)
New Ping: http://playground.arduino.cc/Code/NewPing (Arduino, 10.10.14)
We wanted to see how a graph would turn out when reading objects in a room. To make the read we had to physicaly move the MaxSonar. When placing Arduino and MaxSonar toward the floor it managed to make readings of the floor. So to make this work with the digital read you have to place it at least 30 cm above the floor. As you see on the image of the graph it somtimes have trouble measuring the distance.
Fritzing:
See the first image.
Processing code:
/* Processing code for this example<br> // Graphing sketch // This program takes ASCII-encoded strings // from the serial port at 9600 baud and graphs them. It expects values in the // range 0 to 1023, followed by a newline, or newline and carriage return // Created 20 Apr 2005 // Updated 18 Jan 2008 // by Tom Igoe // This example code is in the public domain. */ import processing.serial.*; Serial myPort; // The serial port int xPos = 1; // horizontal position of the graph void setup () { // set the window size: size(400, 300); // List all the available serial ports println(Serial.list()); // I know that the first port in the serial list on my mac // is always my Arduino, so I open Serial.list()[0]. // Open whatever port is the one you're using. myPort = new Serial(this, Serial.list()[5], 9600); // don't generate a serialEvent() unless you get a newline character: myPort.bufferUntil('\n'); // set inital background: background(0); } void draw () { // everything happens in the serialEvent() } void serialEvent (Serial myPort) { // get the ASCII string: String inString = myPort.readStringUntil('\n'); if (inString != null) { // trim off any whitespace: inString = trim(inString); // convert to an int and map to the screen height: float inByte = float(inString); inByte = map(inByte, 0, 1023, 0, height); // draw the line: stroke(127,34,255); line(xPos, height, xPos, height - inByte); // at the edge of the screen, go back to the beginning: if (xPos >= width) { xPos = 0; background(0); } else { // increment the horizontal position: xPos++; } } }
We found the code here: http://arduino.cc/en/Tutorial/Graph (Arduino, 09.10.14)
Arduino code:
//Original author: Bruce Allen<br>//Date: 23/07/09 //Changed by Marte and Runar 09/10/14, to only have cm as output and to fit the processing code for a graph //Digital pin 7 for reading in the pulse width from the MaxSonar device. //This variable is a constant because the pin will not change throughout execution of this code. const int pwPin = 7; //variables needed to store values long pulse, inches, cm; int output; void setup() { //This opens up a serial connection to shoot the results back to the PC console Serial.begin(9600); } void loop() { pinMode(pwPin, INPUT); //Used to read in the pulse that is being sent by the MaxSonar device. //Pulse Width representation with a scale factor of 147 uS per Inch. pulse = pulseIn(pwPin, HIGH); //147uS per inch inches = pulse/147; //change inches to centimetres cm = inches * 2.54; // Serial.print(inches); // Serial.print("in, "); // Serial.print(cm); // Serial.print("cm"); // Serial.println(); output= map(cm,0,645,0,1023); Serial.println(output); delay(1); }
We found the code here, under PW: http://playground.arduino.cc/Main/MaxSonar (Allen, 09.10.14)
The output is only cm (not cm and inches), and the output values are changed due to the values of the graph.
We used a ruler to test the accuracy of the sharp RF sensor. It was generaly up to 3 cm over or under the actual distance when moving an object between 5 to 40 cm. We added the LCD to show the read from the sensor.
Arduino code:
// include the library code:<br>#include <LiquidCrystal.h> // initialize the library with the numbers of the interface pins LiquidCrystal lcd(12, 11, 5, 4, 3, 2); int i; int val; int redpin=0; void setup() { pinMode(redpin,OUTPUT); Serial.begin(9600); // set up the LCD's number of columns and rows: lcd.begin(1, 1); // Print a message to the LCD. } void loop() { i=analogRead(redpin); val=(6762/(i-9))-4; Serial.println(val); lcd.print(val); delay(250); lcd.clear(); }
Other webpages to check out:
http://tutorial.cytron.com.my/2011/08/13/project-8... (Tutorials by Cytron Technologies, 09.10.14).
We did not find any useful code to make this project going. The concept is that the sensor measures the distance of a object at a given time, then does it again at another time. By calculating the difference between the given positions and time between arduino can calcurlate the speed of the object.
Speed = Distance/time Distance = Point A - Point B
Another way simpler way of toing this is to send a ping, wait for the sensor to receive it back, then measure old Distance A - minus new distance A. Then get the arduino to calculate the speed of a object between the two points. When this is done the code start over. So the first time the code is run through it does not have an old distance A, but the second time the code runs through it have the first measured distance as the old distance.
Since the arduino “knows“ when it sends out a ping it is not necessary to implement time (millies or delay) in the code. It is important to be aware on how delay works in a code, so that we don’t spend too much time making a broken code. When delay is used the whole code waits until the set time is reached.
By using a camara with low exposure we managed to capture the read of the sensors width in a single shot. This makes it easier to be aware of the width MaxSonic operats in.
Arduino code:
//Please be respectful by acknowledging the author in the code if you use or modify it.<br>//Author: Bruce Allen
//Edited By Runar and Marte 08.10.2014 //Date: 23/07/09 //Digital pin 7 for reading in the pulse width from the MaxSonar device. //This variable is a constant because the pin will not change throughout execution of this code. const int pwPin = 7; int led = 6; //variables needed to store values long pulse, inches, cm; void setup() { //This opens up a serial connection to shoot the results back to the PC console Serial.begin(9600); pinMode(led, OUTPUT); } void loop() { pinMode(pwPin, INPUT); //Used to read in the pulse that is being sent by the MaxSonar device. //Pulse Width representation with a scale factor of 147 uS per Inch. pulse = pulseIn(pwPin, HIGH); //147uS per inch inches = pulse/147; //change inches to centimetres cm = inches * 2.54; Serial.print(inches); Serial.print("in, "); Serial.print(cm); Serial.print("cm"); Serial.println(); delay(1); //If you don't want any distance limiter just remove the next 7 lines. if(cm<30){ digitalWrite(led,HIGH); } else{ digitalWrite(led,LOW); } }
We found the code here http://playground.arduino.cc/Main/MaxSonar added a LED and a distance limiter.
The goal here was to see the distance more figuratively than just a number on the screen. The objects size varies based on the distance MaxSonic reads of an object.
Processing code:
import processing.serial.*; Serial myPort; // The serial port, wont be able to connect if the seril monitor in arduino is open so make sure to close it String inBuffer = null; // stores one line of data from serial port int x, y, z; int lf = 10; // Linefeed in ASCII void setup() { size(640, 360, P3D); noStroke(); println(Serial.list()); myPort = new Serial(this, Serial.list()[5], 9600); // serial.list[1] for usb [0] for direct serial } void draw() { if(x<60){ x=40; } lights(); background(204); float cameraY = height/2.0; float fov =( x/float(width))+0.2 * PI/2; float cameraZ = cameraY / tan(fov / 2.0); float aspect = float(width)/float(height); if (mousePressed) { aspect = aspect / 2.0; } perspective(fov, aspect, cameraZ/10.0, cameraZ*10.0); fill(150,0,0); translate(width/2+30, height/2, 0); rotateX(-PI/6); rotateY(PI/3 + 7/8* PI); box(45); translate(0, 0, -50); box(30); } void serialEvent(Serial myPort) { inBuffer = myPort.readStringUntil(lf); // store serial port buffer in global var inBuffer (read string until linefeed (int lf = 10; // Linefeed in ASCII) etc if (inBuffer != null) { println("SERIAL:" + inBuffer); // print the linefrom then serial input try { float[] dat = float(split(inBuffer, ',')); // parse comma-separated number string into numbers array x= int (dat[0]); y= int (dat[1]); z= int (dat[2]); } catch (Exception e) { // if there is a non parsible string its declared null inBuffer=null; } println( x ); } }
We got this code from Nicholas Stevens.
Arduino code:
//Please be respectful by acknowledging the author in the code if you use or modify it.<br>//Author: Bruce Allen //Date: 23/07/09 //Digital pin 7 for reading in the pulse width from the MaxSonar device. //This variable is a constant because the pin will not change throughout execution of this code. const int pwPin = 7; //variables needed to store values long pulse, inches, cm; int output; void setup() { //This opens up a serial connection to shoot the results back to the PC console Serial.begin(9600); } void loop() {<br> pinMode(pwPin, INPUT);<br> //Used to read in the pulse that is being sent by the MaxSonar device. //Pulse Width representation with a scale factor of 147 uS per Inch.<br> pulse = pulseIn(pwPin, HIGH); //147uS per inch inches = pulse/147; //change inches to centimetres cm = inches * 2.54;<br>// Serial.print(inches); // Serial.print("in, "); // Serial.print(cm); // Serial.print("cm"); // Serial.println(); output= map(cm,0,645,0,1023);<br> Serial.println(output);<br> delay(1);<br>}
We found the code here, under PW: http://playground.arduino.cc/Main/MaxSonar (Allen, 09.10.14)
We changed the code, the output is only cm (not cm and inches).
Current use:
Projects:
Instructables: https://www.instructables.com/id/RC-LEGO-Coaster-D... (sath02, 09.10.14)
Instructables: https://www.instructables.com/id/Make-A-Robot-Ant/ (mikey77, 09.10.14)
Current use:
Parking sensors in cars (they also use electromagnetic sensors)
Medicine: making pictures of different parts of the body
Air detection: Safty of a patient
Industry: automated factories and process plants
Autonomous UAV navigation
Detect high-pressure gas or liquid leaks
Cleaning devices
(http://en.wikipedia.org/wiki/Parking_sensors and http://en.wikipedia.org/wiki/Ultrasonic_sensor)
Projects:
Simple parking sensor:
https://www.instructables.com/id/Simple-Parking-Sen...(zmachiah, 09.10.14)
Instructables: https://www.instructables.com/id/DR1-Discovery-Rove... (fxxxx, 09.10.14)
Instructables: https://www.instructables.com/id/Make-a-wall-avoidi... (brandon121233, 09.10.14)
Instructables: https://www.instructables.com/id/Autonomous-wireles... (Brad Powers, 09.10.14)
Instructables: https://www.instructables.com/id/Add-an-ultrasonic-... (revrekad, 09.10.14)
Our suggestions for both:
Control the motion of a servo
Lights change(change of colour or “dimmer”) due to distance
Change the size of an object in processing due to distance
Robot with distance sensor
Robot that follows you around
Robot that turns when detecting obstacles
Show the distance on a LCD
Sound combined with the sensor
Parking sensor increasing sound as objects detected comes closer
Hugging bear
Please feel free to comment or add any tips or ideas you may have.
- Runar Dahlsengen and Marte Frøyse Vidvei