Problem with multiple Parallax PING))) Ultrasonic Sensors - c++

I'm trying to make an AGV(automated guided vehicle) which I wanna use 4 parallax ultrasonic sensors for but there is a problem when I'm using 1 of them its all okay and works perfectly fine, but when I add 1 or more my output on serial monitor says 0cm. I just can't figure it out
I have read lots of forums already but nothing works yet. Here is the code I'm using for 1:
// this constant won't change. It's the pin number of the sensor's output:
const int pingPin = 7;
void setup() {
// initialize serial communication:
Serial.begin(9600);
}
void loop() {
// establish variables for duration of the ping, and the distance result
// in inches and centimeters:
long duration, inches, cm;
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);
// The same pin is used to read the signal from the PING))): a HIGH pulse
// whose duration is the time (in microseconds) from the sending of the ping
// to the reception of its echo off of an object.
pinMode(pingPin, INPUT);
duration = pulseIn(pingPin, HIGH);
// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(100);
}
long microsecondsToInches(long microseconds) {
// According to Parallax's datasheet for the PING))), there are 73.746
// microseconds per inch (i.e. sound travels at 1130 feet per second).
// This gives the distance travelled by the ping, outbound and return,
// so we divide by 2 to get the distance of the obstacle.
// See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds) {
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the object we
// take half of the distance travelled.
return microseconds / 29 / 2;
}
And here when I use more than 1
// this constant won't change. It's the pin number of the sensor's output:
const int pingPin = 7;
const int pingPin2 = 6;
const int pingPin3 = 5;
const int pingPin4 = 4;
void setup() {
// initialize serial communication:
Serial.begin(9600);
}
void loop() {
// establish variables for duration of the ping, and the distance result
// in inches and centimeters:
long duration, inches, cm;
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
digitalWrite(pingPin2, LOW);
digitalWrite(pingPin3, LOW);
digitalWrite(pingPin4, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
digitalWrite(pingPin2, HIGH);
digitalWrite(pingPin3, HIGH);
digitalWrite(pingPin4, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);
digitalWrite(pingPin2, LOW);
digitalWrite(pingPin3, LOW);
digitalWrite(pingPin4, LOW);
// The same pin is used to read the signal from the PING))): a HIGH pulse
// whose duration is the time (in microseconds) from the sending of the ping
// to the reception of its echo off of an object.
pinMode(pingPin, INPUT);
pinMode(pingPin2, INPUT);
pinMode(pingPin3, INPUT);
pinMode(pingPin4, INPUT);
duration = pulseIn(pingPin, HIGH);
duration = pulseIn(pingPin2, HIGH);
duration = pulseIn(pingPin3, HIGH);
duration = pulseIn(pingPin4, HIGH);
// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(100);
}
long microsecondsToInches(long microseconds) {
// According to Parallax's datasheet for the PING))), there are 73.746
// microseconds per inch (i.e. sound travels at 1130 feet per second).
// This gives the distance travelled by the ping, outbound and return,
// so we divide by 2 to get the distance of the obstacle.
// See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds) {
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the object we
// take half of the distance travelled.
return microseconds / 29 / 2;
}
when I use 1 sensor it gives me the right values like expected and when I use 2 or more sensors the a value of 0cm

thanks i just copy paste the code for a single sensor 4 times after each other and made each of them for another sensor there is just a small delay in each sensor but thats alright. new code is as following:
// this constant won't change. It's the pin number of the sensor's output:
const int pingPin = 7;
const int pingPin2= 6;
const int pingPin3 = 5;
const int pingPin4 = 4;
void setup() {
// initialize serial communication:
Serial.begin(9600);
}
void loop() {
// establish variables for duration of the ping, and the distance result
// in inches and centimeters:
long duration, inches, cm;
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);
// The same pin is used to read the signal from the PING))): a HIGH pulse
// whose duration is the time (in microseconds) from the sending of the ping
// to the reception of its echo off of an object.
pinMode(pingPin, INPUT);
duration = pulseIn(pingPin, HIGH);
// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(400);
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(pingPin2, OUTPUT);
digitalWrite(pingPin2, LOW);
delayMicroseconds(2);
digitalWrite(pingPin2, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin2, LOW);
// The same pin is used to read the signal from the PING))): a HIGH pulse
// whose duration is the time (in microseconds) from the sending of the ping
// to the reception of its echo off of an object.
pinMode(pingPin2, INPUT);
duration = pulseIn(pingPin2, HIGH);
// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(400);
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(pingPin3, OUTPUT);
digitalWrite(pingPin3, LOW);
delayMicroseconds(2);
digitalWrite(pingPin3, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin3, LOW);
// The same pin is used to read the signal from the PING))): a HIGH pulse
// whose duration is the time (in microseconds) from the sending of the ping
// to the reception of its echo off of an object.
pinMode(pingPin3, INPUT);
duration = pulseIn(pingPin3, HIGH);
// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(400);
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(pingPin4, OUTPUT);
digitalWrite(pingPin4, LOW);
delayMicroseconds(2);
digitalWrite(pingPin4, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin4, LOW);
// The same pin is used to read the signal from the PING))): a HIGH pulse
// whose duration is the time (in microseconds) from the sending of the ping
// to the reception of its echo off of an object.
pinMode(pingPin4, INPUT);
duration = pulseIn(pingPin4, HIGH);
// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(400);
}
long microsecondsToInches(long microseconds) {
// According to Parallax's datasheet for the PING))), there are 73.746
// microseconds per inch (i.e. sound travels at 1130 feet per second).
// This gives the distance travelled by the ping, outbound and return,
// so we divide by 2 to get the distance of the obstacle.
// See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds) {
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the object we
// take half of the distance travelled.
return microseconds / 29 / 2;
}

Related

My pulse duration calculation is inaccurate. Why?

I'm studying arduino. I generated pulse waves using arduino analog PWM output.
Mega pin No.4 -> 980Hz output => approximately 1000Hz => 1ms duration/pulse => 1000us
I used 50% duty cycle, so 500us pulse output.
I connected PWM output to digital input No.10 pin.
And here is my code. (for HIGH pulse duration)
int aoPin = 4; // analog output pin
int diPin = 10; // digital input pin
void setup() {
Serial.begin(9600);
pinMode(aoPin, OUTPUT);
pinMode(diPin, INPUT);
}
void loop() {
unsigned long highPulse = 0; // Pulse length
unsigned long startMicros = micros();
analogWrite(aoPin, 128); // half duty cycle of 980Hz (arduino Mega pin No.4)
while (digitalRead(diPin)) // calculation method 1
{
}
highPulse = micros() - startMicros;
Serial.print("highPulse1 = ");
Serial.print(highPulse);
Serial.print(" / ");
highPulse = pulseIn(diPin, HIGH); // calculation method 2
Serial.print("highPulse2 = ");
Serial.println(highPulse);
delay(1000);
}
The result was 180 / 510 repeatedly.
The PulseIn function calculated accurate 500us, but my calculated duration was too short (180us).
Even PulseIn function was executed after my calculation function.
Why? Was My function start delayed?
Change where you call micros() the first time, so you know you do it at a rising edge:
unsigned long startMicros = 0;
analogWrite(aoPin, 128); // half duty cycle of 980Hz (arduino Mega pin No.4)
while (digitalRead(diPin)); // wait while input is high
while (!digitalRead(diPin)); // wait while input is low
startMicros = micros(); // Rising edge detected!
while (digitalRead(diPin)); // wait while input is high
// Falling edge detected, get time difference!
highPulse = micros() - startMicros;

How to make an event logger loop work with other loop for arduino uno?

I'm fairly new to this but I've been researching for a while now and no conclusive answer.
How do I make a loop that constantly outputs Serial.println of changes in digitalWrite.
Background info; I am making a traffic light with buttons and pedestrian lights too. I have a sequence for when one of the buttons is pressed but I need a separate loop that outputs changes in lights- which lights are on or which button is pressed. Essentially an event logger that loops throughout the entire script constantly.
**
Sorry, I should have specified; when the button is clicked it goes through a whole sequence, its blocking code. More specifically it's blocking the loop i have for the event logger. How do I work them side-by-side? Whatever I try, it's either the light sequence works or the event logger works but never together. My research indicated that I should use the millis function but I don't know how to implement it.
const int red = 8;
const int yellow = 2;
const int green = 3;
const int p_red = 5;
const int p_green = 6;
const int button1 = 4;
const int button2 = 7;
const int state1 = digitalRead(button1);
const int state2 = digitalRead(button2);
unsigned long waitTime = 500;
void setup() {
pinMode(8, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, INPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, INPUT);
Serial.begin(9600);
}
void loop() {
// turn on the default lights (traffic green and pedestrian red)
digitalWrite(green, HIGH);
digitalWrite(p_red, HIGH);
if(millis() >= waitTime) {
Serial.print("state: ");
Serial.println(state1);
//delay(1000);
}
if(state1 || state2 == HIGH) {
// State 1 // ID Sequence: 3, 5, 6, 1, 5, 2, 10,
digitalWrite(green, HIGH);
digitalWrite(p_red, HIGH);
delay(3000);
digitalWrite(green, LOW);
// State 2
digitalWrite(yellow, HIGH);
delay(5000);
digitalWrite(yellow, LOW);
// State 3
digitalWrite(red, HIGH);
delay(6000);
digitalWrite(p_red, LOW);
// State 4
digitalWrite(p_green, HIGH);
delay(1000);
digitalWrite(p_green, LOW);
// State 5 - Flashing red v 5 cycles (200ms)
for (int x=0+1; x<5; x++) {
digitalWrite(p_red, HIGH);
delay(200);
digitalWrite(p_red, LOW);
delay(200);
} // State 6
digitalWrite(red, HIGH);
digitalWrite(p_red, HIGH);
delay(2000);
// State 7
digitalWrite(red, LOW);
digitalWrite(green, HIGH);
digitalWrite(p_red, HIGH);
delay(10000);
// State 8
digitalWrite(green, HIGH);
digitalWrite(p_red, HIGH);
delay(8000);
}
}
the problem with this current code is the if statement for the lights not working

How to display "accident alert" on LCD display after timer times out

I'm making a simple program that that runs traffic lights in a loop and has an ultrasonic sensor and a 16x2 LCD. The concept is that if the ultrasonic reads a distance value equal to or below a preset value it is detecting obstruction in an intersection and it starts a timer. When that timer expires, the LCD display's an alert. But if the distance value goes above the preset value while the timer is active it stops. For the traffic light loop I'm using the standard Arduino "delay" function e.g. delay(3000);. The issue I'm having is the once the timer finishes the LCD does not display anything. For the alert timer in the program I'm using a library called millisDelay. This library allows the timer to run without stopping the program.
I have tried using the millisDelay library to run the traffic lights instead of the standard delay function. But that does not work as it puts the traffic lights in a constant loop.
Libraries used:
millisDelay.h and liquidCrystal.h
#include <millisDelay.h>
#include <LiquidCrystal.h>
int red = 22;
int yellow = 23;
int green = 24;
int red2 = 25;
int yellow2 = 26;
int green2 = 27;
const int pingPin = 7; // Trigger Pin of Ultrasonic Sensor
const int echoPin = 6; // Echo Pin of Ultrasonic Sensor
long duration, inches, cm;
millisDelay alertdelay;
millisDelay ledDelay;
const int rs = 36, en = 38, d4 = 40, d5 = 42, d6 = 44, d7 = 46;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
// put your setup code here, to run once:
pinMode(red, OUTPUT);
pinMode(yellow, OUTPUT);
pinMode(green, OUTPUT);
pinMode(red2, OUTPUT);
pinMode(yellow2, OUTPUT);
pinMode(green2, OUTPUT);
pinMode(pingPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600); // Starting Serial Terminal
}
void loop() {
lcd.clear();
lcd.begin(16,2);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(10);
digitalWrite(pingPin, LOW);
duration = pulseIn(echoPin, HIGH);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(100);
if (cm>=11){
lcd.setCursor(0,0);
lcd.print("Intersection");
lcd.setCursor(0, 1);
lcd.print("Clear");
}
else if (cm<7){
lcd.setCursor(0,0);
lcd.print("Intersection");
lcd.setCursor(0, 1);
lcd.print("Clear");
alertdelay.start(7000);
Serial.println("delay started");
}
if (alertdelay.isFinished()) {
Serial.println("There is a crash up ahead");
lcd.setCursor(0,0);
lcd.print("Crash Up Ahead");
lcd.setCursor(0,1);
lcd.print("Use Caution");
}
delay(1000);
//'2'refers to intersection number 2
//green off,red2 on, yellow on for 3 seconds
digitalWrite(red2, HIGH);
digitalWrite(green, LOW);
digitalWrite(yellow, HIGH);
delay(3000);
// turn off yellow1, then turn red on for 3 seconds
digitalWrite(yellow, LOW);
digitalWrite(red, HIGH);
delay(3000);
//after 3 seconds keep red 1 on and turn red2 off and green2 on,
//green2 stays on for 15 seconds to let traffic through
digitalWrite(red2, LOW);
digitalWrite(green2, HIGH);
delay(15000);
//after 15 seconds green2 turns off, yellow 2 turns on
//yellow2 turns on for 3 seconds,
digitalWrite(green2, LOW);
digitalWrite(yellow2, HIGH);
delay(3000);
//after 3 seconds, yellow2 turns off, and red 2 turns on
digitalWrite(yellow2, LOW);
digitalWrite(red2, HIGH);
delay(3000);
//3 seconds after red2 turns on, red 1 turns off and
//green 1 turns on for 3 seconds
//red2 stays on
digitalWrite(red, LOW);
digitalWrite(green, HIGH);
delay(14000);
}
long microsecondsToCentimeters(long microseconds) {
return microseconds / 29 / 2;
}
These are the issues with what you are doing.
1) The code that you have written takes 42 seconds to iterate through the loop. So you check if the alertDelay has finished once ever 42 seconds.
2) The second time around the code reaches the back to the start of the loop, you first end up setting the alertDelay again before checking if it is running or is finished, which resets it, as such, your code never reaches the part where it displays the crash.
This is how I would have done things
#include <LiquidCrystal.h>
int red = 22;
int yellow = 23;
int green = 24;
int red2 = 25;
int yellow2 = 26;
int green2 = 27;
const int pingPin = 7; // Trigger Pin of Ultrasonic Sensor
const int echoPin = 6; // Echo Pin of Ultrasonic Sensor
long duration, inches, cm;
long alertDisplayTime = millis(), nextLedSwitchTime = millis();
bool displayAlert = false;
int switch_number=-1;
const int rs = 36, en = 38, d4 = 40, d5 = 42, d6 = 44, d7 = 46;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
// put your setup code here, to run once:
pinMode(red, OUTPUT);
pinMode(yellow, OUTPUT);
pinMode(green, OUTPUT);
pinMode(red2, OUTPUT);
pinMode(yellow2, OUTPUT);
pinMode(green2, OUTPUT);
pinMode(pingPin, OUTPUT);
pinMode(echoPin, INPUT);
lcd.begin(16,2);
Serial.begin(9600); // Starting Serial Terminal
nextLedSwitchTime=1000+millis();
}
void loop() {
lcd.clear();
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(10);
digitalWrite(pingPin, LOW);
duration = pulseIn(echoPin, HIGH);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(100);
if (cm>=11){
lcd.setCursor(0,0);
lcd.print("Intersection");
lcd.setCursor(0, 1);
lcd.print("Clear");
displayAlert=false;
}
else if ((cm<7)&&(!displayAlert)){
lcd.setCursor(0,0);
lcd.print("Intersection");
lcd.setCursor(0, 1);
lcd.print("Clear");
alertDisplayTime = millis()+7000;
displayAlert=true;
Serial.println("delay started");
}
if ((displayAlert==true)&&(alertDisplayTime<millis())) {
Serial.println("There is a crash up ahead");
lcd.setCursor(0,0);
lcd.print("Crash Up Ahead");
lcd.setCursor(0,1);
lcd.print("Use Caution");
displayAlert=false;
}
if(nextLedSwitchTime>=millis()){
return;
}
long delay_time=0;
switch_number++;
switch(switch_number){
case 0:
//'2'refers to intersection number 2
//green off,red2 on, yellow on for 3 seconds
digitalWrite(red2, HIGH);
digitalWrite(green, LOW);
digitalWrite(yellow, HIGH);
delay_time=3000;
break;
case 1:
// turn off yellow1, then turn red on for 3 seconds
digitalWrite(yellow, LOW);
digitalWrite(red, HIGH);
delay_time=3000;
//after 3 seconds keep red 1 on and turn red2 off and green2 on,
break;
case 2:
//green2 stays on for 15 seconds to let traffic through
digitalWrite(red2, LOW);
digitalWrite(green2, HIGH);
//after 15 seconds green2 turns off, yellow 2 turns on
delay_time=15000;
break;
case 3:
//yellow2 turns on for 3 seconds,
digitalWrite(green2, LOW);
digitalWrite(yellow2, HIGH);
//after 3 seconds, yellow2 turns off, and red 2 turns on
delay_time=3000;
break;
case 4:
digitalWrite(yellow2, LOW);
digitalWrite(red2, HIGH);
//3 seconds after red2 turns on, red 1 turns off and
delay_time=3000;
break;
case 5:
//green 1 turns on for 3 seconds
//red2 stays on
digitalWrite(red, LOW);
digitalWrite(green, HIGH);
delay_time = 14000;
switch_number=-1;
}
nextLedSwitchTime = millis()+delay_time;
}
long microsecondsToCentimeters(long microseconds) {
return microseconds / 29 / 2;
}
What this code does is it never blocks the loop funciton, so your pusle in function is carried out almost every second along with the check for the crash.
Also, i have set a bit, which tells the code that the alert delay has already started, which ensures that your code does not reset it.

Arduino Sonar and Stepper Motor

I am trying to create an Arduino powered sonar / radar. I currently have a sonar sensor attached to a motor and working on the code. The issue is with the for loop below. The sensor will ping and the motor will then move, repeating the correct number of times. However the values that the sonar sensor returns are either 0 or 1 no matter what the distance is. Any help on identifying the issue would be very appreciated.
/*
Nathan Verdonk
3/15/2019
*/
#include <NewPing.h>
#include <Stepper.h>
const int stepsPerRevolution = 2048; // Steps per revolution
const int rotSpeed = 10; // Speed of rotation in RPM
const int triggerPin = 7; // Trigger pin on sonar sensor
const int echoPin = 6; // Echo pin on sonar sensor
const int maxDistance = 300; // Max distance expected from sensor in cm; do not exceed 400
int val;
Stepper stepper1(stepsPerRevolution, 8, 10, 9, 11); // initialize the stepper library on pins 8 through 11:
NewPing sonar1(triggerPin, echoPin, maxDistance); // initialize the new ping library with predefined values
void setup() {
stepper1.setSpeed(rotSpeed);
Serial.begin(115200);
}
void loop() {
for(int i = 0; i < 50; i++){
delay(50);
val = sonar1.ping_cm();
Serial.println(val);
stepper1.step(1);
}
delay(3000);
}
Problem is not with the code.
As it turns out, the sensor is picky about needing nearly exactly 5 V to run. With the servo and sensor using the same power source, the voltage would drop below 5 V when the servo was running.
Thank you to all who helped.
if you want to trap the distance you could do this process to validate your sensor has no problem (i suppose wiring is right):
// defines pins numbers
const int triggerPin = 7;
const int echoPin = 6;
// defines variables
long duration;
int distance;
void setup() {
pinMode(triggerPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
Serial.begin(115200); // Starts the serial communication
}
void loop() {
delay(50);
// Clears the triggerPin
digitalWrite(triggerPin, LOW);
delayMicroseconds(2);
// Sets the triggerPin on HIGH state for 10 micro seconds
digitalWrite(triggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(triggerPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance= duration*0.034/2;
// Prints the distance on the Serial Monitor
Serial.print("Distance: ");
Serial.println(distance);
}
In order to generate the ultrasound you need to set the Trig on a High State for 10 µs. That will send out an 8 cycle sonic burst which will travel at the speed sound and it will be received in the Echo pin. The Echo pin will output the time in microseconds the sound wave traveled.
the speed of the sound is 340 m/s or 0.034 cm/µs so you divide by 2 to trap the distance

Distance controlled led

I'm trying to create a distance controlled LED that turns off at a certain distance. I'm using an arduino Leonardo and a distance sensor. At the moment when I plug in my board the led stays on permanently and doesn't turn off when the distance reduces. Please can you tell me what needs changing in order for this to work?
const int TrigPin = 2;
const int EchoPin = 3;
float cm;
int ledPin = 12; //define ledPin12 is the output port of led’s level.
int val = 0; //define original of val.
void setup()
{
Serial.begin(9600);
pinMode(TrigPin, OUTPUT);
pinMode(EchoPin, INPUT);
pinMode(ledPin, OUTPUT); //set ledPin output
}
void loop()
{
digitalWrite(TrigPin, LOW); //Low-high-low level sent a short time pulse to TrigPin
delayMicroseconds(2);
digitalWrite(TrigPin, HIGH);
delayMicroseconds(10);
digitalWrite(TrigPin, LOW);
cm = pulseIn(EchoPin, HIGH) / 58.0; //Echo time converted into cm
cm = (int(cm * 100.0)) / 100.0; // retain two decimal places
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(1000);
val = analogRead(EchoPin); //get the value from sensor
if(val<=1)
{
//512=2.5V, if want the sensor be more sensitive, increase the number, or lese low the number.
digitalWrite(ledPin, HIGH); //when the value of val is less than 512(2.5V), light up led lamp
}
else
{
digitalWrite(ledPin, LOW);
}
}
I am guessing the sensor is similar to an SRF005. You should include that detail in your question.
The trigger looks okay, but there is no harm in pulsing a little longer, say 20 us, to make sure. The capturing of the echo looks right, except that that datasheet I found says to divide by 5.8, not 58.0, and the return value is an unsigned long, not float..
But you shouldn't be using analogRead() on the echo pin. It will be 0 at that point. Rather, you already have the distance in the cm variable.
(There are sensors which use pin voltage to indicate distance as well, but they don't have trigger and echo pins. Which kind are you actually using?)
void loop()
{
int cm = 0;
digitalWrite(TrigPin, LOW); //Low-high-low level sent a short time pulse to TrigPin
delayMicroseconds(2);
digitalWrite(TrigPin, HIGH);
delayMicroseconds(10); // <<<<<<<<<<<<<<<<<<<<<<<< Change to 20
digitalWrite(TrigPin, LOW);
cm = (int)(pulseIn(EchoPin, HIGH) * 10 / 58); //Echo time converted into cm <<<<<<<<< 5.8 ????
Serial.print(cm);
Serial.print("cm");
Serial.println();
if(cm < 50)
{
digitalWrite(ledPin, HIGH);
}
else
{
digitalWrite(ledPin, LOW);
}
delay(1000);
}