'{$STAMP BS2e} '{$PBASIC 2.5} '*********************************************************** '**Setting range and gain settings for fast SRF08 ranging ** ** '** I2C Routines for the Basic Stamp ** '** Controlling Two SRF08 Ultrasonic Rangers ** '** ** '** Copyright 2002 - Devantech Ltd ** '** Commercial use of this software is prohibited ** '** Private and educational use only is permitted ** '** ** '** Written by Gerald Coe - January 2002 ** '** Edited by Greg Cameron for 1 meter ranging and ** '** no light metering ** '** This Code has been Tested on BS2 and BS2p ** '** It should work equally well on the BS2e and BS2sx ** '** ** '*********************************************************** LCD CON 9 ' lcd SCL CON 11 ' I2C clock/orange SDA CON 10 ' I2C data /yellow SDAin VAR IN10 ' SDAout VAR OUT10 ' To change the pins used, alter these 5 lines SDAdir VAR DIR10 ' The 4 SDA numbers must be the same, of course 'LOOP VAR Byte ' just a looping counter I2cBuf VAR Byte ' I2c read/write buffer I2cAddr VAR Byte ' Address of I2C device I2cReg VAR Byte ' Register number within I2C device I2cData VAR Word ' Data to read/write I2cAck VAR Bit ' Acknowledge bit n9600 CON $4054 ' lcd baud PAUSE 1000 'initialize lcd SEROUT lcd,n9600,[12,14] SEROUT lcd,n9600,["****JOESRF08A***"] PAUSE 3000 SEROUT lcd,n9600,[12,"LRange",13,"RRange"] Init: 'initialize SRF08 range and gain settings 'left SRF08 ranger I2cAddr = $e2 'left address I2cReg = 2 'range register I2cData = 24 'set range to 1 meter max GOSUB I2cByteWrite 'write PAUSE 70 'delay I2cAddr = $e2 'left address I2cReg = 1 'gain register I2cData = 16 'set gain to 177 max GOSUB I2cByteWrite 'write 'right SRF08 ranger I2cAddr = $e0 'right address I2cReg = 2 'range register I2cData = 24 'set range to 1 meter max GOSUB I2cByteWrite 'write PAUSE 70 'delay I2cAddr = $e0 'right address I2cReg = 1 'gain register I2cData = 16 'set gain to 177 max GOSUB I2cByteWrite 'write PAUSE 70 'delay Main: ' Left SRF08 Ranger I2cAddr = $e2 I2cReg = 0 I2cData = 80 ' Ranging command - 80 for inches, 81 for cm, 82 for uS GOSUB I2cByteWrite PAUSE 10 ' wait for ranging to complete 'I2cReg = 1 ' address of light sensor register 'GOSUB I2cByteRead 'DEBUG 2,0,0, "Light Sensor1 ", DEC3 I2cData 'SEROUT lcd,n9600,[16,77,18,3,DEC3 I2cData] I2cReg = 2 ' address of first ranging result GOSUB I2cWordRead 'DEBUG 2,0,1, "Range1 ", DEC4 I2cData SEROUT lcd,n9600,[16,71,18,4,DEC4 I2cData] ' Right SRF08 Ranger I2cAddr = $e0 I2cReg = 0 I2cData = 80 ' Ranging command - 80 for inches, 81 for cm, 82 for uS GOSUB I2cByteWrite PAUSE 10 ' wait for ranging to complete 'I2cReg = 1 ' address of light sensor register 'GOSUB I2cByteRead 'DEBUG 2,0,3, "Light Sensor2 ", DEC3 I2cData 'SEROUT lcd,n9600,[16,93,18,3,DEC3 I2cData] I2cReg = 2 ' address of first ranging result GOSUB I2cWordRead 'DEBUG 2,0,4, "Range2 ", DEC4 I2cData SEROUT lcd,n9600,[16,87,18,4,DEC4 I2cData] GOTO main '-------------------------------------------------------------------------------------------- ' I2C subroutines follow '-------------------------------------------------------------------------------------------- I2cByteWrite: ' writes I2cData.lowbyte to I2cReg at I2cAddr GOSUB I2cStart I2cBuf = I2cAddr GOSUB I2cOutByte ' send device address I2cBuf = I2cReg GOSUB I2cOutByte ' send register number I2cBuf = I2cData.LOWBYTE GOSUB I2cOutByte ' send the data GOSUB I2cStop RETURN I2cWordWrite: ' writes I2cData to I2cReg at I2cAddr GOSUB I2cStart I2cBuf = I2cAddr GOSUB I2cOutByte ' send device address I2cBuf = I2cReg GOSUB I2cOutByte ' send register number I2cBuf = I2cData.HIGHBYTE GOSUB I2cOutByte ' send the data - high byte I2cBuf = I2cData.LOWBYTE GOSUB I2cOutByte ' send the data - low byte GOSUB I2cStop RETURN I2CByteRead: GOSUB I2cStart I2cBuf = I2cAddr GOSUB I2cOutByte ' send device address I2cBuf = I2cReg GOSUB I2cOutByte ' send register number GOSUB I2cStart ' repeated start I2cBuf = I2cAddr | 1 GOSUB I2cOutByte ' send device address (with read set) I2cAck = 0 ' send Nak GOSUB I2cInByte I2cData.LOWBYTE = I2cBuf ' read the data I2cData.HIGHBYTE = 0 GOSUB I2cStop RETURN I2CWordRead: GOSUB I2cStart I2cBuf = I2cAddr GOSUB I2cOutByte ' send device address I2cBuf = I2cReg GOSUB I2cOutByte ' send register number GOSUB I2cStart ' repeated start I2cBuf = I2cAddr | 1 I2cAck = 1 ' send Ack GOSUB I2cOutByte ' send device address (with read set) GOSUB I2cInByte I2cData.HIGHBYTE = I2cBuf ' read the data I2cAck = 0 ' send Nak GOSUB I2cInByte I2cData.LOWBYTE = I2cBuf GOSUB I2cStop RETURN I2cOutByte: SHIFTOUT SDA, SCL, MSBFIRST, [I2cBuf] INPUT SDA HIGH SCL ' clock in the ack' bit LOW SCL RETURN I2cInByte: SHIFTIN SDA, SCL, MSBPRE, [I2cBuf] SDAout = 0 SDAdir = I2cAck HIGH SCL ' clock out the ack' bit LOW SCL INPUT SDA RETURN I2cStart: ' I2C start bit sequence HIGH SDA HIGH SCL LOW SDA LOW SCL RETURN I2cStop: ' I2C stop bit sequence LOW SDA HIGH SCL HIGH SDA RETURN