'*********************************************************** '** ** '** I2C Routines for the Basic BX-24 ** '** to change the I2C address of the SRF08 ** '** ** '** Copyright 2002 - Devantech Ltd ** '** Commercial use of this software is prohibited ** '** Private and educational use only is permitted ** '** ** '** Written by Gerald Coe - February 2002 ** '** ** '*********************************************************** Const SRF08_NEW_ADDRESS As Byte = &He0 ' Place new address for SRF08 here 'avaliable addresses are: e0, e2, e4, e6, e8, ea, ec, ee ' f0, f2, f4, f6, f8, fa, fc, fe Const SCL As Byte = 14 ' I2C clock - choose any pins you wish for SCL and SDA Const SDA As Byte = 13 ' I2C data Const GB As Byte = 0 ' I2C General Broadcast address Const CmdReg As Byte = 0 ' SRF08 command register Const LdrReg As Byte = 1 ' Address of Light Sensor Register in SRF08 Const RangeReg As Byte = 2 ' Address of Range Register in SRF08 Const RangeCmd As Byte = 81 ' Ranging command - 80 for inches, 81 for cm, 82 for uS Dim I2cAck As Boolean ' Acknowledge flag Sub Main() Dim Ldr As Byte Dim Range As New UnsignedInteger Call PutPin(SCL, bxOutputHigh) Call PutPin(SDA, bxOutputHigh) Call Delay(1.0) ' Delay just to be sure SRF08 is out of reset Call I2cByteWrite(GB, CmdReg, &Ha0) ' 1st command in address change sequence Call I2cByteWrite(GB, CmdReg, &Haa) ' 2nd command in address change sequence Call I2cByteWrite(GB, CmdReg, &Ha5) ' 3rd command in address change sequence Call I2cByteWrite(GB, CmdReg, SRF08_NEW_ADDRESS) ' The new I2C address ' That's the address changed, now perform SRF08 Ranging in an endless loop at the new address Do Call I2cByteWrite(SRF08_NEW_ADDRESS, CmdReg, RangeCmd) ' Start Ranging in Cm Call Delay(0.07) ' 70mS wait for ranging to complete Ldr = I2cByteRead(SRF08_NEW_ADDRESS, LdrReg) ' Read light sensor Range = I2cWordRead(SRF08_NEW_ADDRESS, RangeReg) ' Read Range Register debug.Print "LDR = "; CStr(Ldr); ", Range = "; CStr(Range) Loop End Sub '-------------------------------------------------------------------------------------------- ' I2C subroutines follow '-------------------------------------------------------------------------------------------- ' writes I2cData to I2cReg at I2cAddr Sub I2cByteWrite(ByVal I2cAddr As Byte, ByVal I2cReg As Byte, ByVal I2cData As Byte) Call I2cStart() Call I2cOutByte(I2cAddr) ' send device address Call I2cOutByte(I2cReg) ' send register address Call I2cOutByte(I2cData) ' send the data Call I2cStop() End Sub Function I2CByteRead(ByVal I2cAddr As Byte, ByVal I2cReg As Byte) As Byte Call I2cStart() Call I2cOutByte(I2cAddr) ' send device address Call I2cOutByte(I2cReg) ' send register address Call I2cStart() ' repeated start I2cAddr = I2cAddr+1 Call I2cOutByte(I2cAddr) ' send device address with read set I2cAck = False ' setup to send Nak I2cByteRead = I2cInByte() ' get data byte with Nak Call I2cStop() End Function Function I2CWordRead(ByVal I2cAddr As Byte, ByVal I2cReg As Byte) As UnsignedInteger Set I2CWordRead = New UnsignedInteger Call I2cStart() Call I2cOutByte(I2cAddr) ' send device address Call I2cOutByte(I2cReg) ' send register address Call I2cStart() ' repeated start I2cAddr = I2cAddr+1 Call I2cOutByte(I2cAddr) ' send device address with read set I2cAck = True ' setup to send Ack I2cWordRead = CuInt(I2cInByte()*256) I2cAck = False ' setup to send Nak I2cWordRead = I2cWordRead + CuInt(I2cInByte()) Call I2cStop() End Function Sub I2cOutByte(I2cData As Byte) Call ShiftOut(SDA, SCL, 8, I2cData) ' shift data out Call PutPin(SDA, bxInputTristate) ' turn SDA around Call PutPin(SCL, bxOutputHigh) ' and clock in the ack' bit Call PutPin(SCL, bxOutputLow) End Sub Function I2cInByte() As Byte I2cInByte = ShiftIn(SDA, SCL, 8) If I2cAck=True Then Call PutPin(SDA, bxOutputLow) Else Call PutPin(SDA, bxOutputHigh) End If Call PutPin(SCL, bxOutputHigh) ' clock out the ack' bit Call PutPin(SCL, bxOutputLow) End Function Sub I2cStart() ' I2C start bit sequence Call PutPin(SDA, bxOutputHigh) Call PutPin(SCL, bxOutputHigh) Call PutPin(SDA, bxOutputLow) Call PutPin(SCL, bxOutputLow) End Sub Sub I2cStop() ' I2C stop bit sequence Call PutPin(SDA, bxOutputLow) Call PutPin(SCL, bxOutputHigh) Call PutPin(SDA, bxOutputHigh) End Sub