EmbeddedRelated.com
Forums
Memfault Beyond the Launch

SRF08 Ultrasonic Ranger: odd echoes

Started by arhodes19044 November 18, 2005
Has anyone had good luck with the SRF08?

I have mine working, and I am pretty sure it is working properly. I
get a decent reading for the first echo, the the subsequent echoes do
not seem to represent real objects.

Essentially I get echoes every 25 inches no matter what it is aimed
at. I can hold it in the corner of the room aiming into nothing for 5
feet down, 5 feet up, and 15 feet ahead. I still get these echoes.

Any ideas?

-Tony


I had mine working and on my desk for weeks. While the readings in
terms of actual inches were not really as accurate as I would like,
they would measure. Mostly every measure would change.

Since you are getting a consistent reading, I suspect that your
software code has of bug [or that the unit is in someway broken].

I assume that you are averaging several samples in order to smooth
the jumping around of measurements and have it in a loop that updates
at a reasonalble rate [let's say once a second].

I suspect your problem in either in the smoothing algorhythm or the
updating loop or both.

If you really have no clue, you might post that code for us to all
look at.
--- In basicx@basi..., "arhodes19044" <spamiam@c...> wrote:
>
> Has anyone had good luck with the SRF08?

> Essentially I get echoes every 25 inches no matter what it is aimed
> at. I can hold it in the corner of the room aiming into nothing
for 5
> feet down, 5 feet up, and 15 feet ahead. I still get these
echoes.
>
> Any ideas?
>
> -Tony
>


Sorry for the late reply. I was away.

Anyway, I am not doing any averaging. The numbers are pretty
consistent and do not jump apround much.

I do not always get the SAME distances, but I after the first echo,
wherever it may be, then the next echoes come regular intervals
afterward. Sort of like echoes of echoes. This may be exactly the
correct phenomenon.

As far as I can tell, the code is good. I used canned code and I
also used customized stuff and get the same phenomenon.

So, I do not think the code is the culprit, I think it is a
physical/ranger hardware issue.

I take it you have not experienced the same?

Here is my code:

This is the main:

' "SRF08_Test.bas"
' Devantech SRF08 Ultrasonic Detector Example
' Reads Ultrasonic Range, Light, and Software Revision
' Modified Devantech example originally written by Gerald Coe
' Thomas B. Handley / 05 Oct 2004
' Notes: Requires my "I2C.bas" Module
' : Requires my "SRF08.bas" Module
' : Requires Pullup Resistors on SDA and SCL Pins (1.8K
Recommended)
' : See "SRF08.bas" for Defining Range Mode (inches, cm, or
uSecs)
' Modified further by Anthony Rhodes 11/05

Sub Main()

Const ADDR As Byte = &HE0 ' SRF08 Default I2C
Address
Const ECHO1 As Byte = &H02 ' Echo 1 Range Register
(Read)

Dim Range As New UnsignedInteger ' Range Sensor Value
Dim Light As Byte ' Light Sensor Value
Dim Rev As Byte ' Software Revision
Dim Index as Byte
Dim Ranges (1 to 17) as New UnsignedInteger 'all the
range registers!

Call PutPin(SDA, 2) ' Set SDA to High
via Pullup
Call PutPin(SCL, 2) ' Set SCL to High
via Pullup

Do

Call Start_SRF08_Ranging(ADDR) ' Start Ranging
Delay(0.07) ' 70mS Ranging Delay

' Range = Get_SRF08_Range(ADDR, ECHO1) ' Get Range
Call Get_SRF08_AllRanges(ADDR, Ranges) 'get all 17
ranges

'Light = Get_SRF08_Light(ADDR) ' Get Light Sensor Value

'Rev = Get_SRF08_Rev(ADDR) ' Get Software Revision

'Debug.Print "Range = "; CStr(Range); " Inches"; ", Light = ";
CStr(Light); ", Rev = "; CStr(Rev)
For Index = 1 to 17
Debug.print CStr(Ranges(Index));" ";
Next
Debug.print
Delay(1.0)

Loop

End Sub

---
---

Here is the driver for the ranger:

' MODULE "SRF08.bas"
' Devantech SRF08 Ultrasonic Range Finder routines
' Inspired by Gerald Coe
' Thomas B. Handley / 05 Oct 2004 / v1.00
' This Software is Public Domain. If you Modify it, Please Remove my
Name...
' Notes: Requires my "I2C.bas" Module
' : Requires Pullup Resistors on SDA and SCL Pins (1.8K
Recommended)
' : I2C Address Must be Defined in External Calling Routines
' : These Routines Do Not Handle Slave ACK Status...
' : Feel Free to Delete Unused Routines to Save Code Space...
' Modified further by Anthony Rhodes

' Define Range Mode: 80 = inches, 81 = cm, 82 = uSecs. Change Mode
here
Private Const RANGE_MODE As Byte = 80 ' Set Range Mode to Inches

' Define SRF08 Registers
Private Const REG_CMD As Byte = &H00 ' Command Register (Write)
Private Const REG_REV As Byte = &H00 ' Revision Register (Read)
Private Const REG_GAIN As Byte = &H01 ' Gain Register (Write)
Private Const REG_LSR As Byte = &H01 ' Light Sensor Register (Read)

' Define ACK/NACK States
Private Const ACK As Byte = 0 ' Send ACK
Private Const NACK As Byte = 1 ' Send NACK ' Start SRF08 Ranging
' Entry: Addr = I2C Address
' Notes: You Should Delay at least 65ms After Calling this Routine.
' See the SRF08 Docs for more information

Public Sub Start_SRF08_Ranging(ByVal Addr As Byte)

Call Send_SRF08_Byte(Addr, REG_CMD, RANGE_MODE)

End Sub ' Get SRF08 Range
' Entry: Addr = I2C Address, Reg = Range Register Address
' Exit : Returns SRF08 Range in Units as Defined Above
' Notes: This Routine Requires that you First Call
Start_SRF08_Ranging() '********************************************************************
***********************************
'*

*
'* Get_SRF08_AllRanges: Reads all 17 2-byte range registers.

*
'* Entry: ADDR = I2C address, Ranges = UnsignedInteger array
with 17 cells *
'* Notes: This Routine Requires that you First Call
Start_SRF08_Ranging() *
'*

*
'* Example Code:

*
'* Dim Ranges (1 to 17) as New UnsignedInteger '17
UnsignedIntegers
*
'* Call Get_SRF08_AllRanges(ADDR, Ranges) 'get all 17
ranges, place them in the array Ranges *
'*

*
'********************************************************************
***********************************

Public Sub Get_SRF08_AllRanges(ByVal ADDR as Byte, ByRef Ranges() as
UnsignedInteger) Dim HByte As Byte
' Range High Byte
Dim LByte As Byte
' Range Low Byte
Dim Index as Byte
Dim status As Boolean '
TRUE if Slave ACK

Call I2C_Start()
' Send I2C Start Sequence

status = Send_I2C_Byte(Addr) ' Send I2C
Address
status = Send_I2C_Byte(2) '
Send Range Register Address

Call I2C_Start()
' Send I2C Restart Sequence

status = Send_I2C_Byte(Addr + 1) ' Send I2C
Address with Read Bit Set

For Index = 1 to 17 '
takes advantage of the ability to read registers sequentially
HByte = Get_I2C_Byte(ACK) '
Get Range High Byte with ACK

If (Index < 17) then
LByte = Get_I2C_Byte(ACK) '
Get Range Low Byte with ACK to signify more transaction to come
Else
LByte = Get_I2C_Byte(NACK) '
Get Range Low Byte with NACK to signify the end of the transaction
End If

Ranges(Index) = CuInt((HByte * 256) + LByte) '
Convert to Unsigned Integer
Next Call I2C_Stop() '
Send I2C Stop Sequence End Sub ====================================================
Here is the I2C interface by Mr Handy:
' MODULE "I2C.bas"
' I2C Common Routines
' Inspired by Peter H. Anderson, Gerald Coe, and Philips v2.1
Specification
' Thomas B. Handley / 02 Oct 2004 / v1.00
' This Software is Public Domain. If you Modify it, Please Remove my
Name...
' Notes: Defaults to SDA and SCL on BX-24 Pins 13 and 14. Change
Pins below
' : Requires Pullup Resistors on SDA and SCL Pins
' : High (1) Bits are Defined as Input-Tristate via Pullup
Resistors
' : Low (0) Bits are Defined as Output-Low
' : I2C Address Must be Defined in External Calling Routines
' : This version Does Not Check for Slave Clock-Stretching...
' Define SDA and SCL Pins here. In this case, Pins 13 and 14
Public Const SDA As Byte = 12 ' I2C Data on Pin 13
Public Const SCL As Byte = 13 ' I2C Clock on Pin 14 ' Send I2C Byte
' Entry: Data = Byte sent to Slave
' Exit : Returns TRUE if Slave ACK, FALSE if NACK

Public Function Send_I2C_Byte(ByVal Data As Byte) As Boolean

Dim status As Byte

Call ShiftOut(SDA, SCL, 8, Data) ' Send Byte
Call PutPin(SDA, 2) ' Set SDA High
Call PutPin(SCL, 2) ' Get Slave ACK/NACK Status
status = GetPin(SDA)
Call PutPin(SCL, 0)

If status = 0 Then ' If Slave ACK, Return TRUE
Send_I2C_Byte = TRUE
Else ' Else Return FALSE
Send_I2C_Byte = FALSE
End IF

End Function ' Get I2C Byte
' Entry: ACK_State = 0 if Send ACK to Slave, 1 if NACK
' Exit : Returns Byte from Slave

Public Function Get_I2C_Byte(ByVal ACK_State As Byte) As Byte

Get_I2C_Byte = ShiftIn(SDA, SCL, 8) ' Get Byte
If ACK_State = 0 Then ' Check ACK/NACK State
Call PutPin(SDA, 0) ' Set ACK
Else
Call PutPin(SDA, 2) ' Set NACK
End If
Call PutPin(SCL, 2) ' Send ACK/NACK
Call PutPin(SCL, 0)

End Function ' I2C Start Sequence

Public Sub I2C_Start()

Call PutPin(SDA, 2) ' Set SDA High
Call PutPin(SCL, 2) ' Set SCL High
Call PutPin(SDA, 0) ' Set SDA Low
Call PutPin(SCL, 0) ' Set SCL Low

End Sub ' I2C Stop Sequence

Public Sub I2C_Stop()

Call PutPin(SDA, 0) ' Set SDA Low
Call PutPin(SCL, 2) ' Set SCL High
Call PutPin(SDA, 2) ' Set SDA High

End Sub


--- In basicx@basi..., "arhodes19044" <spamiam@c...> wrote:
>
> I take it you have not experienced the same?

I must admit that I used the SFR04, not the SRF08. I misread your
numbers. So I really am not 100% sure of the improvements or changes
to that unit. I have been trying to read up on the SRF08 on line.
The new unit will measure 30 feet!, but I seem to see your code is
listing inches -- that is 3600 inches. You might be using SFR04 code.

I have not been able to download good documentation to compare in
details. I would need that to see if I have a useful program.

> Anyway, I am not doing any averaging. The numbers are pretty
> consistent and do not jump apround much.

The SFR04 funcitions much better if you take the last five samples
and average them. Otherwise it jitters a lot. There is simply too
much raw data to watch bounce up and down.
>
> I do not always get the SAME distances, but I after the first echo,
> wherever it may be, then the next echoes come regular intervals
> afterward. Sort of like echoes of echoes. This may be exactly the
> correct phenomenon.

Your description sounds like something is hanging on to the first
reading and not following up. The idea of echos of echos makes very
little sense to me, but then again this particular unit may not be
suitable for a hard walled interior as the greater distance implies
that it puts out more powerful ultrasound. You might try it in a
larger space or outside.

>
> As far as I can tell, the code is good. I used canned code and I
> also used customized stuff and get the same phenomenon.
> So, I do not think the code is the culprit, I think it is a
> physical/ranger hardware issue.

When it is suspected to purely be a hardware issue, you really need
to duplicate the function using a different device, maybe with a
different, but proven software. Sad to say, this gets costly and
complicated - you need to have another SRF08 to verify similar
behavior or you might find code for a PIC or something and see what
happens with that being used with your one and only device.

There is not much reason to try to figure out the software code if
you say it is good.

I do know that it is easy to get the wires reversed, but it would
seem to create a non-functioning device rather that give you input. >
>


Take a look at the following site for documentation of the SRF08.

It appears that the 17 registers are pretty much a burst of
measurements that allow you to average them for verification.

You software and hardward appear to be fine.
You are just being overrun by data. http://www.robot-electronics.co.uk/htm/srf08tech.shtml

Please forgive my previous blunders of assuming the SRF08 was like the
SRF04.


If I understand the srf08 correctly, I don't think they are meant to
be averaged. They are actually the multiple echos from the initial
ping. So if the ping hits a chair and bounces back first, that is the
first echo, then it hits the refrigerator and bounces back creating
the second echo, then the far wall, those are the three values you
would see in the registers. (I believe it will return up to 8 echos.)
Averaging them would not really give you what you want as it would
give a range somewhere between the chair and the wall and you probably
want to know specifically about the chair. []
> It appears that the 17 registers are pretty much a burst of
> measurements that allow you to average them for verification.
[]


--- In basicx@basi..., "Eric" <aliasmrjones@y...> wrote:
>
>So if the ping hits a chair and bounces back first, that is the
>first echo, then it hits the refrigerator and bounces back creating
>the second echo, then the far wall, those are the three values you
>would see in the registers. (I believe it will return up to 8 echos.)
>

Correct. There are more than 8 registers and they contain the time or
distance (as selected by the used) of the individual echo returns.

As I said before, I an getting odd echoes, which occur about every 25
inches avter the one before. The first echo sems pretty accurate out
to about 40 inches, but then after that echoes are just spaced at just
about exactly 25 inches therafter.

It is almost as if I am getting echoes of the echoes (reverberation)
rather than actual primary echo returns from specific objects further
away that the first echo.

I wonder if it is a some odd resonance in my hardware somehow. I do
not see how. My pull-up resistors are as specified by the ranger
manufacturer (1k8 if I remember correctly). The leads are short. So
I do not know....

Wide open spaces seem to give similar results as in a 12 x 12 foot
room with a carpeted floor....

-Tony



Memfault Beyond the Launch