View previous topic :: View next topic |
Author |
Message |
lan ahmad
Joined: 23 Jul 2012 Posts: 13
|
combine 2 HC-SR04 coding |
Posted: Fri Mar 22, 2013 9:57 am |
|
|
can anyone help how to make programming to combine 2 or more HC-SR04 ultrasonic sensor?
Code: | #include <16F877a.h>
#FUSES NOWDT, HS, NOPUT, PROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#use delay(clock=20000000)
void beeping(long int dly);
int16 distance, time; // Defining variables
// Defining the pins
#define trig pin_b0
#define echo pin_b1
#define echos pin_b2
void main()
{
delay_ms(300); // Boot-up delay, for troubleshooting
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); // initiating timer
while(true)
{
output_high(trig); // ping the sonar
delay_us(10); // sending 20us pulse
output_low(trig);
//sensor 1//
while(!input(ECHO1)) // wait for high state of echo pin
{}
set_timer1(0); // setting timer zero
while(input(ECHO1)) // Wait for high state of echo pin
{}
time=get_timer1(); // Getting the time
//sensor 2//
while(!input(ECHO2)) // wait for high state of echo pin
{}
set_timer1(0); // setting timer zero
while(input(ECHO2)) // Wait for high state of echo pin
{}
time=get_timer1(); // Getting the time
distance=time*0.028 + 1.093 ; // Calculating the distance
if (distance>=0 && distance<=20)
{ beeping(50);}
if (distance>20 && distance<=40)
{ beeping(100);}
if (distance>40 && distance<=60)
{ beeping(200);}
if (distance>60 && distance<=80)
{ beeping(400);}
if (distance>80)
{ beeping(600);}
}
}
void beeping(long int dly)
{
output_high(pin_b6);
delay_ms(dly);
output_low(pin_b6);
delay_ms(dly);
} |
|
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Fri Mar 22, 2013 10:40 am |
|
|
It's not clear to me what you are trying to do.
Are you wanting:-
1) To use one sound source only and detect echo on all sensors?
OR
2) To use each sensor unit completely independantly?
What do you intend doing with the several distance measurements?
How are you arranging the separate modules?
Mike |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Fri Mar 22, 2013 10:59 am |
|
|
The big problem with any use of more than one ultrasonic, is that each will receive the pulse from the other, and either may reply first. You really can only do this reliably by working sequentially. Trigger unit1, handle it's return, then trigger unit2, and handle it's return. You can't trigger both at once and 'know' which is going to react first, and since the pulses will not be completely synchronised, the returns may well be invalid.
Best Wishes |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Fri Mar 22, 2013 1:17 pm |
|
|
Your should also recognize, that because the frequency discriminator in these is low cost, and broadband, that even a single unit can be quite susceptible to environmental 'chirps' and interference, not just from a brother or sister unit.
They work best in a QUIET environment with a flat reflective target.
for large surfaces, that are relatively near - ( under a meter or two )
you can get a strong clear echo, but on irregular or absorptive surfaces , not so good. |
|
|
lan ahmad
Joined: 23 Jul 2012 Posts: 13
|
|
Posted: Sun Mar 24, 2013 9:46 am |
|
|
Mike Walne wrote: | It's not clear to me what you are trying to do.
Are you wanting:-
1) To use one sound source only and detect echo on all sensors?
OR
2) To use each sensor unit completely independantly?
What do you intend doing with the several distance measurements?
How are you arranging the separate modules?
Mike |
I want to use each sensor unit completely independantly.
I want to make a simple robot with 3 HC-SR04 sensor to detect obstacle front and side. The measurement that I did is only to test the ultrasonic sensor.
3 different sensor connect to 6 pin on PIC.
Code: |
//front sensor
#define trig1 pin_b0
#define echo1 pin_b1
//right sensor
#define trig2 pin_b2
#define echo2 pin_b3
//left sensor
#define trig3 pin_b4
#define echo3 pin_b5
|
|
|
|
languer
Joined: 09 Jan 2004 Posts: 144 Location: USA
|
|
Posted: Sun Mar 24, 2013 10:46 am |
|
|
You could do something like a round-robin style. As an example; test sensor1, once complete, test sensor 2, once complete test sensor 3; and repeat. For this, I would use a timer and start the timer every time a new sensor is polled. Oh yes, and simple polling is probably ok.
Example:
Code: | pseudo code
setup timer1 for 40-50ms timeout
sensor1:
pulse sensor1
wait for sensor1 return pulse start condition (i.e. going high transition)
clear timer1
clear timer1 interrupt flag
wait for sensor1 return pulse completion (i.e. going low transition) or timer1 flag
if timer1 flag, then sensor1 timed-out
otherwise, read timer1 and calculate distance based
repeat for sensor2
repeat for sensor3
|
If you want to do all three sensors at once, you likely need to use interrupts on the each RX pin from the sensor (i.e RX1, RX2, RX3). But more importantly you need to shield each sensor so the only return it can listen to is from the one direction it is pointing to (i.e. you have to make the sensor more directional). This is possible, but your still want to then "filter" the responses so errant readings are filtered out (e.g. use multiple readings and throw out outliers). This is definitely more complex. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Sun Mar 24, 2013 11:00 am |
|
|
OK.
Forget about three sensors. Program one.
setup timer1 as you do in your existing program.
output_low all three trigger pins.
then call a subroutine to get one range:
Code: |
int16 get_range(int16 trigger,int16 echo)
{
int16 count=0;
while(input(echo)); //This will wait if the unit is still
//seeing a trigger from the last scan
output_high(trigger);
delay_us(10);
output_low(trigger); //10uSec trigger pulse
set_timer1(0);
while ((input(echo)==0) && ((count=get_timer1())<15000)) ;
//It is the time to the start of the return that defines distance
if (count>=15000)
return 420;
//at your clock rate, timer1/8, counts every 1.6uSec
//distance in cm is then approx count/36
return count/36;
}
//So in your main:
distance1=get_range(trig1,echo1);
distance2=get_range(trig2,echo2);
distance3=get_range(trig3,echo3);
|
This gives approximately distance in cm as an int16 from 0 to 416. Returns 420, if an echo is not received in sensible time. Then do your maths, and loop.
Best Wishes |
|
|
languer
Joined: 09 Jan 2004 Posts: 144 Location: USA
|
|
Posted: Sun Mar 24, 2013 9:19 pm |
|
|
I am pretty sure the pulse width contains the distance information. So I believe you need the following change:
from...
Code: | set_timer1(0);
while ((input(echo)==0) && ((count=get_timer1())<15000)) ;
//It is the time to the start of the return that defines distance
if (count>=15000)
return 420; |
to...
Code: | while ((input(echo)==0); //wait for distance/time pulse to be raised
set_timer1(0); //initiate timer once the distance/time pulse starts
while ((input(echo)==1) && ((count=get_timer1())<15000)) ;
//It is the positive pulse width of the return signal that defines distance
if (count>=15000)
return 420; |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Mon Mar 25, 2013 12:36 am |
|
|
The maths is different if you use the pulse width.
You can use either.
Quote:
"You can calculate the range through the time interval between sending trigger signal and receiving echo signal. Formula: uS / 58 = centimeters"
To use pulse width, the formula changes to:
range = high level time(seconds) * 170m
Using the pulse start is quicker than waiting for the pulse to finish. It is also easier to do the 'nothing received' detection.
Best Wishes |
|
|
|