Page 1 of 1

Calculating distance

Posted: Wed Apr 16, 2008 12:23 pm
by Ondra
Good day all. I would like to get some help calculating distance using a ranging sensor module. Heres what I have.
I have 2 pins connected to a ranging sensor unit. Using tmr1 to count down, every 5sec a macro is called that outputs
a 1 to start the ranging unit and enables tmr0 which increments a variable. RB0 connected to the input from the
ranging module stops tmr0. I have the unit connected to hyperterminal. While moving an object back and forth I can see
that the numbers printed out are changing and consistant when object is moved. Heres my question. If the number in var
that's printed out is say 602 what is this number representative of and how do I use or what do I have to do to that number
in order to use it in this formular: - distance= time * speed of sound / by 2 for (sound travel at 73.746us per inch).
I am using a PIC18F258 with a 19.66MHZ crystal and a Prescaler of 1:8 (2400Hz). Hope you can help me with this.
Thanks in advance.


Ondra

Re: Calculating distance

Posted: Wed Apr 16, 2008 3:17 pm
by Steve
I know that someone here has done somehing similar with a distance sensor. I'll ask them to post their code here if it seems appropriate (they are out to lunch at the moment).

But the basics are as follows...

Once the distance sensor emits a pulse, you need to start some kind of timer. And when you receive the echoed response, the value of the timer represents your distance. And your formula is correct - distance = speed * time. But in this case, the distance that the ultrasound pulse travels is twice the distance you are trying to calculate, and the speed is the speed of sound. So, D = S * T / 2. The speed of sound is 344 m/s or 1130 ft/s or 13560 in/s

The value of the timer represents the value of T in the above formula, although you will need to convert this to milliseconds or similar.

I am assuming you have a timer interrupt that increments a number each time the interrupt is triggered, which is every 417us at 2400Hz. So a value of this variable of 100 would represent 100/2400 = 0.041666 seconds.

So, distance = 0.041666 * 13560 / 2 = 282.5 inches.

Does this sound right?

Of course, the math involved in the above is fairly horrible for an 8-bit micro, so you may be able to simplify it:

D = 13560 * (cnt/2400) / 2 = cnt * 113 / 40

I hope this helps. Be aware that I could have got the calculations wrong, so someone please tell me if I have.

Re: Calculating distance

Posted: Wed Apr 16, 2008 4:20 pm
by Sean
I have written a test program for a ranging sensor that uses Timer 0 with a prescaler of 1:32 to give an interrupt frequency of 600Hz.
MotionSensor2.fcf
(7 KiB) Downloaded 456 times
The timer and an interrupt counter are reset when the sensor is triggered. When an echo is received the interrupt counter represents the high byte of the result, and the timer register value is the low byte. It would be better to use a 16-bit timer if you have one available!

The 1:32 prescaler, with a 19.6608MHz Xtal and system division by 4 gives a timer clock pulse every 6.51us. Figures given for the speed of sound is quite variable (331m/s upto 350m/s). A figure of 338m/s allows 6.51us to represents approximately 2.2mm of travel, or 1.1mm of range due to the double path length.

Speed of sound = 338m/s = 0.338mm/us
Clock period = 6.51us
0.338mm/us * 6.51us = 2.2mm travel = 1.1mm range.

The 16-bit count value when the echo is received is made up of the two 8-bit values:

(interrupt count value * 256) + timer register value

The example program prints the 16-bit result directly to a 16 x 2 LCD. Multiplying the result by 9 and dividing by 10 will provide a more accurate result in mm.

Re: Calculating distance

Posted: Wed Apr 16, 2008 5:14 pm
by Ondra
Thanks Steve and Sean. Sean as per your suggestion I could use tmr1 which is a 16 bit timer, could you give me a modified version using tmr1?
I modified the fcd for the 18f258 so I could use tmr1 without writing c code.
Also I tried to change the target device to the 18F258 and it would not compile. Heres the error I got: -

C:\DOCUME~1\Ondra\LOCALS~1\Temp\MotionSensor2.c(402:2): error: unknown identifier 'tmr0'
C:\DOCUME~1\Ondra\LOCALS~1\Temp\MotionSensor2.c(402:2): error: invalid operand 'tmr0'
C:\DOCUME~1\Ondra\LOCALS~1\Temp\MotionSensor2.c(402:7): error: failed to generate expression
C:\DOCUME~1\Ondra\LOCALS~1\Temp\MotionSensor2.c(436:17): error: unknown identifier 'tmr0'
C:\DOCUME~1\Ondra\LOCALS~1\Temp\MotionSensor2.c(436:17): error: invalid operand 'tmr0'
C:\DOCUME~1\Ondra\LOCALS~1\Temp\MotionSensor2.c(436:15): error: failed to generate expression
MotionSensor2.c success

Thank again for all your help.

Ondra

Re: Calculating distance

Posted: Fri Apr 18, 2008 9:37 am
by Sean
TMR0 in the PIC18F258 is configurable for 8/16-bit operation so it has 2 timer registers: tmr0h and tmr0l.

The timer registers can be cleared using the C instructions:
tmr0h = 0;
tmr0l = 0;

The timer can be turned on in 16-bit mode, with a 1:32 prescaler, using the following C command:

t0con = 0x84;

The timer can be turned off using the following C command:

t0con = 0x00;

With a 16-bit timer there is no requirement for a timer interrupt. The available counter values will cover most practical ranges.
The timer should be turned off and cleared when not in use.
It should be enabled when the ranger trigger pulse is set, and disabled when the echo is received - causing the timer increments to stop and the 16-bit value to be retained until it can be read.
The tmr0h and tmr0l can then be read into a Flowcode int variable using the following C code before being cleared.

FCV_RANGE = (tmr0h << 8) + tmr0l;

tmr0h can be checked regularly. An excessively high value will indicate a failed response.

Note: It might be preferable to disable the timer when reading or writing the tmr0h and tmr0l registers to prevent the possibility of the individual 8-bit values changing while they are being accessed as a 16-bit register pair.

Re: Calculating distance

Posted: Fri Apr 18, 2008 9:42 am
by Sean
The last C command in the previous posting should have read:

FCV_RANGE = (tmr0h<<8) + tmr0l;

Re: Calculating distance

Posted: Sat Oct 25, 2008 6:17 pm
by khaled yasin
how did you find that each clock tick will need 6.51us??????
can you show me the calculations??

Re: Calculating distance

Posted: Sat Oct 25, 2008 6:30 pm
by khaled yasin
do i have to use pin C2 or i can use any other pin?????

Re: Calculating distance

Posted: Wed Oct 29, 2008 10:05 am
by Sean
The period of the clock cycle supplied to the timer module is calculated from the system clock frequency and the prescaler setting for the timer.
The example program uses our standard xtal frequency of 19660800Hz. Most of the internal components are supplied with a clock running at 1/4 this frequency - 4915200Hz. The prescaler settings for the timer apply an additional 32:1 reduction, resulting in a 153600Hz clock (6.51us).

Alternative port pins can be used. The ones selected in the example program are compatible with our EB-054 Pasco Sensor Board.

Re: Calculating distance

Posted: Wed Oct 29, 2008 6:53 pm
by khaled yasin
So i understand that i can change PIN C2 to any other PIN, i thought that i need PIN C2 because there is a C-Code FCV... and this code works with input capture PINS???so i can easily just change the pin C2....and the example will still work fine...

Re: Calculating distance

Posted: Thu Oct 30, 2008 9:25 am
by Sean
You will need to modify the I/O references in the program if you want to use alternative pins. The original selection was not based on the special properties of any of the pins (peripheral functions etc.) so you are free to choose from any that are available.