Author Topic: Axon Code for SRF05 - Sonar Range Finder  (Read 9317 times)

0 Members and 1 Guest are viewing this topic.

Offline VOneTopic starter

  • Jr. Member
  • **
  • Posts: 14
  • Helpful? 0
Axon Code for SRF05 - Sonar Range Finder
« on: November 26, 2008, 05:06:16 PM »
Hello Forum,

I have taken so much from this forum, that I thought I would give something back to it, even if its just this small thread.  So here is my quick tutorial on how I implemented the Devantech Ultrasonic Range Finder (SRF05) with the Axon.

SRF05 Technical:
I Used Mode 1:

I decided to use the SRF05's Mode 1, which uses two IO pins, one for the ping, and one for the Echo listener.  The SRF05 can also operate using only one pin, but I have a lot of left over IO right now, so I used the easier Mode with two IO pins.

So I connected port F6 to the Trigger Input of the SRF05, and the 5V power of F6 to the SRF05's 5Volt, and the Ground from F6 to the SRF05's Ground.  Then I connected F5 on the Axon to the Echo Output of the SRF05.  *It should be noted here that I originally got the SRF05's Input and Output backwards assuming it meant Output of the Axon; when it really means, of course, its own output - Too Much solder in the air over here.

SoR_Utils.h Port F configuration code:
Code: [Select]
DDRF = 0b01000011;  //configure all F ports for input
//       ||||||||
//       |||||||\___0: IRPD Output Left
//       ||||||\____1: IRPD Output Right
//       |||||\_____2: IRPD Input Source
//       ||||\______3: Left Input Bumper Switch
//       |||\_______4: Right Input Bumper
//       ||\________5: SONAR Green Wire Input - for timer echo
//       |\_________6: SONAR Purple Wire Output - for Ping
//       \__________7: Input (nothing yet)

I use the 16 bit Timer3 to time the SRF05's echo time.  So in the main program call the Timer Initializer:
Code: [Select]
timer3Init(); //Initialize 16 Bit Timer 3
The 16 bit timer will count up to 64,000ish  (2^16) CPU cycles before it overflows, which is plenty long enough for the SRF05's max echo length.

So, now I just had to code it up, here is the pseudo code:
Code: [Select]
Send a ping on Port F6 for 12uS
Wait for Pin 5 to go high (this happens around 100uS after the ping according to the datasheet)
Reset the timer to start counting
Wait for Pin5 to go low
Read the timer
Calculate the Distance using a Constant (C)
Return the distance

And here is my real code in a Function called SonarPing:
Code: [Select]
int SonarPing(void) {
//F5: SONAR Purple Input - Echo Timer (output of the SRF05)
  //F6: SONAR Green Output - Ping Trigger (input of the SRF05)
//Speed_of_Sound * Time_Passed / 2 = Distance_from_Object
//343 m/s * .03 s / 2 = 5.145 m

int Distance=0;  //Distance in estimate centimeters to be returned from this function
PORT_ON(PORTF,6);//Ping F6 - Sends a ping out from the Robot
delay_us(12); //uS delay, should be 12uS - from the data sheet, length of ping
PORT_OFF(PORTF,6);//Stop Ping - Ends the ping sound

while(bit_is_clear(PINF,5)); //Wait for F5 to go high
reset_timer_3(); //Start timer at 0
while((!bit_is_clear(PINF,5))&&(TCNT3<6000))//Wait for P6 to go low - 6000 is 4 Meters, the max range
Distance = TCNT3/15; //Returns the time divided my magic constant 15 for centimeters
return Distance;

To call this I just call it from my main program like:
Code: [Select]
int SonarDistance=0;
SonarDistance = SonarPing();  //Returns distance in centimeters

To calculate my Constant (C) I did a lot of math ...
   Speed_of_Sound * Time_Passed / 2 = Distance_from_Object
   343 m/s * .03 s / 2 = 5.145 m
I calculated, using my 16Mhz clock cycle and the speed of sound to get a Constant (C) of 9.33 - WHICH WAS WAY OFF!

So I cheated and created a quick excel matrix.  I created a quick program that would show me the counter time every time I pushed a bumper switch, then moved an object to exact distances away from the sonar, at 30cm, 45cm, 60cm, and 100cm.  And I used those exact measurements to estimate a more real world constant (C).

And a nice rounded estimate appeared to be 15, which works great for me.

I then mounted a servo in the top of VOne, and used mbateman's tutorial: PWM on Axon ...

... to drive the servo.  I put the servo on H3, which uses Timer4, and I removed all of the code for E345 which uses Timer3, since I am using that for the sonar timer.  Thanks mbateman!  That saved me a lot of time and the servo is really precise now.

My robot now uses the sonar to adjust its max speed, when it can see 3 meters ahead, it will go Full speed.  Also, when VOne finds a dark corner it will spin and check the sonar range - it will then lay in wait for something to appear closer (cross its path), then jump out and run around. 

I hope this helps some people.  The SRF05 is 30USD from robotshop.ca:
« Last Edit: November 26, 2008, 10:55:12 PM by VOne »

Offline airman00

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 3,653
  • Helpful? 21
  • narobo.com
Re: Axon Code for SRF05 - Sonar Range Finder
« Reply #1 on: November 26, 2008, 10:21:47 PM »
do you mind if I add it in to here  http://www.societyofrobots.com/member_tutorials/node/115
I would of course give you all the credit
Check out the Roboduino, Arduino-compatible board!

Link: http://curiousinventor.com/kits/roboduino


Offline VOneTopic starter

  • Jr. Member
  • **
  • Posts: 14
  • Helpful? 0
Re: Axon Code for SRF05 - Sonar Range Finder
« Reply #2 on: November 26, 2008, 11:00:06 PM »
Yes, please use it anyway you'd like.

**Please note that I had to edit my code:  Where I had
that should have read

For Micro Seconds instead of Milli seconds.

Offline Admin

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,632
  • Helpful? 169
    • Society of Robots
Re: Axon Code for SRF05 - Sonar Range Finder
« Reply #3 on: December 02, 2008, 02:55:43 AM »
Cool! I just added this post to the Axon documentation and example pages.


Get Your Ad Here