I've been working on a library for the SRF02 ultrasonic ranging module for a few weeks now. I've tested it as far as I can so I am posting it here for anyone else to use and hoping that someone else will be able to test it. I have been using a 16F914 with version 0.93 of the software I2C library for testing.
There are some notes at the top of the header file which give a list of the functions that are included which covers everything except resetting the automatic calibration.
I have also posted a demo program which shows off the main features.
I have been unable to change the bus address of the device. I have tried a few things and nothing seems to have worked so if anyone can give me some pointers with that I'd be grateful, as it would allow me to test the 'Fake range' and the 'Ping' functions properly.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
' LIBRARY FOR SRF02 ULTRASONIC SENSOR MODULE IN I2C MODE
' V0.1 Peter Everett 07/11/2014
' The SRF02 is a small ultrasonic transeiver with built in calibration and measurement processing
' It can be accessed using I2C or SPI (This library is for the I2C mode)
' The module has a typical range from 16 cm to 6 m
' Information on the module can be found here http://www.robot-electronics.co.uk/htm/srf02tech.htm
' FUNCTION LIST AND STATUS
' SRF_Measure Tested in cm and inches Oct 2014. uS gives a result so assumed correct.
' SRF_FakeMeasure Untested. No means to transmit another synchronised burst
' SRF_Ping Part tested Oct 2014. LED flashes but no means to listen for a reply
' SRF_GetResult Tested Oct 2014
' SRF_GetCalib Tested Nov 2014
' SRF_SWVer Tested Nov 2014
' SRF_ChangeAddr Doesn't work. Not figured out why so function disabled by default
'
'variables
dim SRF_ver as byte 'Software version
dim SRF_units as byte 'Units of the measurement
dim SRF_cmd as byte 'Command to be sent to the module
dim SRF_rngH as byte 'High byte of the mesurement result
dim SRF_rngL as byte 'Low byte of the measurement result
dim SRF_Result as word '16 bit word for the measurement result
dim SRF_Calib as word '16 bit word for the calibration value (minimum distance that can be measured)
Sub SRF_Measure (in SRF_units, optional SRF_Base as byte = 0xE0)
'Send a pulse and take a measurement
'SRF_units determines the units of the measurement
'0 = Inches
'1 = Centimetres
'2 = Microseconds
'The unit will be stored after the reading and can be read by the main program e.g. for adding to the display
'Taking a reading will blink the LED on the module
Select case SRF_units
case 0
SRF_cmd = 0x50
case 1
SRF_cmd = 0x51
case 2
SRF_cmd = 0x52
case else
'this is an 'error' condition if an invalid unit is specified
SRF_units = 255
end select
'send the command
'the result is stored on the chip and must be read back by the main program using the SRF_GetResult function
I2CStart
I2CSend SRF_Base 'device in write mode
I2CSend 0 'register 0 ('command' register)
I2CSend SRF_cmd 'send command
I2CStop
End Sub
Sub SRF_FakeMeasure (in SRF_units, optional SRF_Base as byte = 0xE0)
'Take a measurement but don't send a pulse
'This is used if another transmitter sends the pulse and the module is to listen for it. The send/receive need to be synchronised.
'SRF_units determines the units of the measurement
'0 = Inches
'1 = Centimetres
'2 = Microseconds
'The unit will be stored after the reading and can be read by the main program e.g. for adding to the display
'Taking a reading will blink the LED on the module
'The code for this function is the same as for SRF_Measure apart from the values of the command that is issued
Select case SRF_units
case 0
SRF_cmd = 0x56
case 1
SRF_cmd = 0x57
case 2
SRF_cmd = 0x58
case else
'this is an 'error' condition if an invalid unit is specified
SRF_units = 255
end select
'send the command
'the result is stored on the chip and must be read back by the main program using the SRF_GetResult function
I2CStart
I2CSend SRF_Base 'device in write mode
I2CSend 0 'register 0 ('command' register)
I2CSend SRF_cmd 'send command
I2CStop
End Sub
Sub SRF_Ping (optional SRF_Base as byte = 0xE0)
'Send a pulse but doesn't take a measurement
'Sending a pulse will blink the LED on the module
'send the command
I2CStart
I2CSend SRF_Base 'device in write mode
I2CSend 0 'register 0 ('command' register)
I2CSend 0x5C 'send command
I2CStop
End Sub
Sub SRF_GetResult (optional SRF_Base as byte = 0xE0)
'Reads the result of the last measurement and stores in the SRF_Result variable
'The units of the measurement are whatever was set in the SRF_Measure command
I2CStart
I2CSend SRF_Base 'device in write mode
I2CSend 2 'register 2 (start of the measurement registers)
I2CRestart
I2CSend (SRF_Base + 1) 'device in read mode
I2CReceive SRF_rngH 'read high byte
I2CReceive SRF_rngL, nack 'read low byte
I2CStop
'Combine the high and low bytes to give a 16 bit word as a result
SRF_Result = (SRF_rngH * 255) + SRF_rngL
End Sub
Sub SRF_GetCalib (optional SRF_Base as byte = 0xE0)
'Reads the auto tune result
'The units of this measurement are the same as the last ranging measurement
'Therefore this only works if a measurement has been taken
'The datasheet says that 5-6 measurements need to be taken for the tuning to be completed
'The code for this function is the same as SRF_GetResult apart from the register location
I2CStart
I2CSend SRF_Base 'device in write mode
I2CSend 4 'register 4 (start of the autotune registers)
I2CRestart
I2CSend (SRF_Base + 1) 'device in read mode
I2CReceive SRF_rngH 'read high byte
I2CReceive SRF_rngL, nack 'read low byte
I2CStop
'Combine the high and low bytes to give a 16 bit word as a result
SRF_Calib = (SRF_rngH * 255) + SRF_rngL
End Sub
Sub SRF_SWVer (optional SRF_Base as byte = 0xE0)
'Reads the software version from the module
I2CStart
I2CSend SRF_Base 'device in write mode
I2CSend 1 'register 1 (start of the autotune registers)
I2CRestart
I2CSend (SRF_Base + 1) 'device in read mode
I2CReceive SRF_ver 'read software version
I2CStop
End Sub
Sub SRF_ChangeAddr (SRF_OldBase, SRF_NewBase)
'Changes the bus address of the sensor from SRF_OldBase to SRF_NewBase
'The address is changed by writing values 0xA0 0xA5 and 0xAA to the command register, followed by the new address.
'The address for the module is 'flashed' on the LED when it is powered up
'Only the following addresses can be used with the module: E0 (default), E2, E4, E6, E8, EA, EC, EE, F0, F2, F4, F6, F8, FA, FC, FE
'At present this function doesn't seem to work so it is disabled
Exit Sub
'check the new address is valid
If SRF_NewBase > 0xFE then
Print "Invalid address 1"
Exit Sub
End If
If SRF_NewBase < 0xE0 then
Print "Invalid address 2"
Exit Sub
End If
'If (SRF_NewBase % 2) = 1 then ''compiler doesn't recognise % as modulus?
' Exit Sub
'End If
'Output to LCD to verify address
CLS
Print "New address: "
Print SRF_NewBase
Exit Sub
'Address is valid, continue
I2CStart
I2CSend SRF_OldBase 'device in write mode
I2CSend 0 'register 0 ('command' register)
I2CSend 0xA0 'send first command
I2CStop
I2CStart
I2CSend SRF_OldBase 'device in write mode
I2CSend 0 'register 0 ('command' register)
I2CSend 0xA5 'send second command
I2CStop
I2CStart
I2CSend SRF_OldBase 'device in write mode
I2CSend 0 'register 0 ('command' register)
I2CSend 0xAA 'send third command
I2CStop
I2CStart
I2CSend SRF_OldBase 'device in write mode
I2CSend 0 'register 0 ('command' register)
I2CSend SRF_NewBase 'send new address
I2CStop
End Sub
I have updated my SRF02.h library to version 0.2. Changes are:
- SRF_ChangeAddr now works and allows the I2C bus address to be changed which allows multiple sensors to be used
- SRF_Ping and SRF_FakeMeasure have been tested as best as I can and you seem to be able to detect a ping from one sensor on another.
The new file is attached. There's hardly any change from version 0.1.
Hello,
I've been working on a library for the SRF02 ultrasonic ranging module for a few weeks now. I've tested it as far as I can so I am posting it here for anyone else to use and hoping that someone else will be able to test it. I have been using a 16F914 with version 0.93 of the software I2C library for testing.
Technical details of the module are here: http://www.robot-electronics.co.uk/htm/srf02tech.htm
There are some notes at the top of the header file which give a list of the functions that are included which covers everything except resetting the automatic calibration.
I have also posted a demo program which shows off the main features.
I have been unable to change the bus address of the device. I have tried a few things and nothing seems to have worked so if anyone can give me some pointers with that I'd be grateful, as it would allow me to test the 'Fake range' and the 'Ping' functions properly.
Code Listing:
Last edit: Peter 2014-11-07
Example program:
Displays the module software version, takes some measurements then reports the calibration data.
Results are displayed on a 2x16 LCD module.
Last edit: Peter 2014-11-07
@Peter. Very nice.
May I include this good work in the next release of GCB?
This is a good addition to the portfolio!
Yes, no problem including it.
Hopefully a few more people will play around with it and test it. Being unable to change the module address is a bit of a limitation.
I have updated my SRF02.h library to version 0.2. Changes are:
- SRF_ChangeAddr now works and allows the I2C bus address to be changed which allows multiple sensors to be used
- SRF_Ping and SRF_FakeMeasure have been tested as best as I can and you seem to be able to detect a ping from one sensor on another.
The new file is attached. There's hardly any change from version 0.1.
@Peter. Thank you again. Can we publish as part of the next GCB release? I will add headers etc. for you.
Go for it.
If I find any more bugs in it beforehand I will let you know.