Discussion in "8051 Discussion Forum" started by    shama3ey    Oct 26, 2009.
Fri Nov 06 2009, 06:33 pm
#11
Thank you for your great help
Tue Nov 10 2009, 10:16 pm
#12
Well I wrote the routine, and to test it I call my buzzer when the sonar detects stuff within the range of 100 cm (1 m) but its still strange it fires the buzzzer even for objects that are further than 1 m.. Whats wrong with my sonar function?

#include <reg51f.h>
#include <intrins.h>

sbit sonarO = 0xB2;//INT0 P3.2


extern unsigned char distance;

unsigned int temp;
unsigned char time;
unsigned int i;

void sonar()
{

sonarO = 0x00; //make it o/p pin and o/p low on P3.2
sonarO = 0xff; //
//10 uS or whatever u want to keep

for(i = 0; i< 10; i++)
{
_nop_();
}

sonarO = 0x00;// pulse complete L-H-L
//no delay required, prepare your controller for calculating time..
sonarO = 0xff;//make it i/p pin to read the pulse width
TMOD = 0x09; //Timer0, 16bit gate controlled(P3.2)
TR0 = 1;//Timer will only run when Pin becomes high.
while(sonarO==0x00);//wait till pin is low
while(sonarO==0xff);//wait for pulse to finish
//timer stopped automatically as soon as P3.2 goes low
TR0 = 0;//completely stop timer.
//the time is caputred in TH0 and TL0
//convert it to 16 bit in temp then multiply temp by 1.08uS to get the total time traveled
//divide it by 2 to get the time from sensor to object
//then convert it to distance
//unsigned char time;
temp = TH0;
temp = (temp<<8) | TL0;
time = temp * 0.00000108; // to get the total time traveled in s
time = temp / 2;
//Speed_of_Sound * Time_Passed / 2 = Distance_from_Object
//distance = 344 m/s * Time Passed in uS / 2

distance = 344 * time; // in meter
distance = 100 * distance; // distance in cm

}


Can you tell me how to modify my code to make it more eficient and accurate?

Much appreciated
Tue Nov 10 2009, 11:49 pm
#13
It is possible the software is OK but your test setup in causing problems.
Sonar systems often detect surfaces etc other than the target.

Can you arrange a display that gives the distance, so you can get some
idea of what the sonar is "seeing" ?

Wed Nov 11 2009, 01:32 am
#14
hmmm I don't have any idea of the way to display the result of the sonar... But I think you are right about surfaces, because the way I placed my sonar on the robot is about half a foot above the floor... But I don't know whats causing the problem here
Wed Nov 11 2009, 07:41 am
#15


hmmm I don't have any idea of the way to display the result of the sonar.

shama3ey


A serial link to a PC running Hyperterminal is the simplest way.
If you don't already have a serial link, you should add one now as it will be
very useful for testing and debugging.
Fri Nov 13 2009, 03:01 am
#16
I couldn't use a hyper terminal so I wrote a simple main code to test my sonar routine... it worked for distances less than 30 cm and did what I expected, but it get stucked there, and if I reset it and place it in a longer distance it still does the same thing :/

however i found a flaw in the code i posted in my prevous post... here is the modified code and the main code also... more tips are appreciated


#include <reg51f.h>
//
#include <intrins.h>
//

sbit sonarO = 0xB2;//INT0 P3.2


extern unsigned char distance;

unsigned char temp;
unsigned char time;
unsigned int i;

void sonar()
{

	sonarO = 0; //make it o/p pin and o/p low on P3.2
	sonarO = 1; //
	//10 uS or whatever u want to keep

	for(i = 0; i< 10; i++)
	{
	 	_nop_();
	}
	
	sonarO = 0;// pulse complete L-H-L
	//no delay required, prepare your controller for calculating time..
	sonarO = 1;//make it i/p pin to read the pulse width
	TMOD = 0x09; //Timer0, 16bit gate controlled(P3.2)
	TR0 = 1;//Timer will only run when Pin becomes high.
	while(!sonarO);//wait till pin is low
	while(sonarO);//wait for pulse to finish
	//timer stopped automatically as soon as P3.2 goes low
	TR0 = 0;//completely stop timer. 
	//the time is caputred in TH0 and TL0
	//convert it to 16 bit in temp then multiply temp by 1.08uS to get the total time traveled
	//divide it by 2 to get the time from sensor to object
	//then convert it to distance
	//unsigned char time;
	temp = TH0;
	temp = (temp<<8) | TL0;
	time = temp * 0.00000108; // to get the total time traveled in s
	time = time / 2; 
	//Speed_of_Sound * Time_Passed / 2 = Distance_from_Object
	//distance = 344 m/s * Time Passed in uS / 2

		distance = 343 * time * 100; // in centimeter
		//distance = 100 * distance; // distance in cm



		
}



#include <reg51f.h>
//

void delay(int t);
void forward();
//void backward();
void turnR();
//void turnL();
void stop();
void sensor(bit key);
void sonar();
//void buzzer(bit key);

unsigned char distance;
//unsigned int p;
void main()
{
	delay(1);
	distance = 0;
   	while(1)
   	{	  
		sonar();
		if(distance == 310)
		{
			forward();
			delay(1);
			delay(1);
			stop();
			delay(1);
			distance = 0;
			sonar();
		}
		if(distance < 50)
		{
			  turnR();
			  delay(1);
			  stop();
			  delay(1);
			  distance = 0;
			  sonar();
		}

		if(distance >
 50 && distance < 200)
		{
			
			  forward();
			  delay(1);
			  stop();
			  delay(1);
			  distance = 0;
			  sonar();
		}

	 }
  
}



it enters the if( distance < 50) and stays there forever :/


[ Edited Sat Nov 14 2009, 04:53 pm ]
Sat Nov 14 2009, 05:03 pm
#17
replace
for(i = 0; i< 10; i++)
{
_nop_();
}

with simple 10 _nop_() calls coz for loop is too much.
and review your code once coz i doubt the wrong use of variable data types. you are doing a floating point calculation in sonar() where are neither time nor temp are float. try if you can remove the floating point calculations.

Also distance is defined as unsigned char and you are checking for if(distance == 310) which can never be possible.
Sat Nov 14 2009, 10:25 pm
#18
so distance, time and temp all should be float type?

Also when I calculate the the timers values in temp, aren't they in hex? if so multiplying them by 1.08 micro which is a float number is not possible here right?

do i need to convert the value in temp to a decimal value or float value? or that is not needed?
Tue Nov 17 2009, 01:29 am
#19
every number wither float,long int or whatever does have their hex equivalent.

if you move 10 to a in a variable A controller still see it as 0x0A loaded to variable A.

keep them as int
now you wan to multiply by 1.08 then do this way

e.g. temp = (temp * 108)/100 so its same thing and no floats involved. if you want 2 decimal precision then do not divide by 100.
Tue Nov 17 2009, 12:23 pm
#20
well I tried what you have said and still didn't work... it messed up the functionality of my robot even more... so I consulted one of my friends which I found out he used Parallax Ping))) in his robot as well, so he gave me a different method of calculating the distance... I have tried it and it worked nicely, so I thought I'd share it with you guys so that those who will use it with their 8051 microcontrollers.

We first calculate the max distance can be detected by the sonar sensor:

max distance = (18.5ms * 340 m/s)/2 = 3.145 m

then we use a prescalar in the calculation of the distance we measure... 8 is a good prescalar for those who uses a crystal of 11.059 MHZ ...

x = 1 / [(prescalar * max distance)/(frequency * 18.5 ms)]

so distance = time / x ( the 16-bit time capatured from TH0 and TL0 no multiplication by 1.08 us needed)

this will give us the distance in meters so to get them in cm, we divide x by 100.

then in our code

we do

distance = (time / x) + 2 for error correction.

I did these calculations and it worked so nice and smooth... but still Thanks to Exp. and Ajay who helped me figure out how to send pulse to the sensor and capture the time the pulse takes to bounce back to the sensor



[ Edited Tue Nov 17 2009, 12:50 pm ]

Get Social

Information

Powered by e107 Forum System

Downloads

Comments

RodneyKnorb
Thu Apr 25 2024, 07:08 pm
Williamjef
Thu Apr 25 2024, 02:08 pm
SamuelSmise
Thu Apr 25 2024, 09:56 am
DustinErele
Thu Apr 25 2024, 08:44 am
ztaletpzca
Wed Apr 24 2024, 11:19 pm
IrardlPex
Wed Apr 24 2024, 08:42 pm
Charlestehed
Wed Apr 24 2024, 05:20 pm
Robertgurse
Wed Apr 24 2024, 02:43 pm