|
|
| Author |
Message |
mikep
Joined: 24 Sep 2005
Posts: 765
Location: Austin, TX
|
|
Posted: 27 December 2005, 4:50 AM Post subject: Possible I2C Problem |
|
|
I am trying to use the Devantech SRF10 range finder that has a I2C interface. Below is a sample program that works in some cases and not others. The problem seems to be tied to using channel 0 or pins 11/12 on a ZX-24 - see the first 3 lines of the program. I have not tried a ZX-40 yet. The VM/Compiler is version 1.1.0.
Also Tom Handley's bit-banged I2C code for the compatible SRF08 works fine on pins 11/12 or 13/14 - see http://home.comcast.net/~tomhandley/rs/SRF08.zip.
| Code: | ' channel 1 pins 13,14 - range ok, version always 5 (same as bit-banged I2C)
' channel 1 pins 11,12 - range ok, version always 128
' channel 0 pins 11,12 - range ok, version always same as last range data on bus
Private Const channel as Byte = 0
Private Const sdaPin as Byte = 11
Private Const sclPin as Byte = 12
' Define SRF10 constants
Private Const SRF_CMD As Byte = &H00 ' Command Register (Write)
Private Const SRF_REV As Byte = &H00 ' Revision Register (Read)
Private Const SRF_RANGE_HIGH As Byte = &H02 ' Range High Byte (Read)
Private Const SRF_RANGE_LOW As Byte = &H03 ' Range Low Byte (Read)
Private Const SlaveID As Byte = &HE0 ' I2C slave address/id
Private Const RANGE_MODE As Byte = 80 ' Set Range Mode to Inches
Sub Main()
Dim i2cRC as Integer, range as Integer
Dim cmd(1 to 2) as Byte alias range
Dim reg as byte
Dim ver as Byte
' open I2C channel
Call OpenI2C(channel, sdaPin, sclPin)
Do
' start ranging
cmd(1) = SRF_CMD
cmd(2) = RANGE_MODE
i2cRC = I2CCmd(channel, slaveID, 2, cmd, 0, 0)
Call Sleep(0.1) ' at least 0.065
' get range, low byte first, then high byte
reg = SRF_RANGE_LOW
i2cRC = I2CCmd(channel, slaveID, 1, reg, 1, cmd(1))
reg = SRF_RANGE_HIGH
i2cRC = I2CCmd(channel, slaveID, 1, reg, 1, cmd(2))
Debug.print "Range ";CStr(range); " inches"
' get software version
i2cRC = I2CCmd(channel, slaveID, 1, SRF_REV, 1, ver)
Debug.Print "Software version "; CStr(ver)
Delay(1.0)
Loop
End Sub |
Example incorrect output using channel 0 is as follows:
| Code: | ZBasic v1.1
Range 27 inches
Software version 27
Range 2 inches
Software version 2
Range 27 inches
Software version 27
Range 4 inches
Software version 4 |
Example correct output using channel 1 with pins 13/14 is as follows:
| Code: | ZBasic v1.1
Range 72 inches
Software version 5
Range 27 inches
Software version 5
Range 2 inches
Software version 5 |
|
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 27 December 2005, 17:24 PM Post subject: |
|
|
I'll have to look into this some more but my initial observation is that there is an error in the code that retrieves the version number that should have been caught by the compiler.
The code should read, in part:
| Code: |
' get software version
reg = SRF_REV
i2cRC = I2CCmd(channel, slaveID, 1, reg, 1, ver)
Debug.Print "Software version "; CStr(ver)
|
The compiler should have warned you that you can't pass a constant by reference. It wasn't detected because the constant has the value zero which is acceptable as a special value meaning no data is being passed. However, since the write count was non-zero, the compiler should have generated a warning. |
|
| Back to top |
|
 |
mikep
Joined: 24 Sep 2005
Posts: 765
Location: Austin, TX
|
|
Posted: 27 December 2005, 17:56 PM Post subject: |
|
|
Good catch !
I can confirm that when I pass 0 by reference, the code works in all cases and this is not a I2C problem after all.
Thanks. |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 27 December 2005, 18:10 PM Post subject: |
|
|
Thanks for verifying that the modified code works correctly.
The compiler has been changed to accept a zero value for the fourth and sixth parameters only if the third and fifth parameters, respectively, are also zero. The same issue and resolution applies to SPICmd.
An updated compiler version will be posted when testing is completed. |
|
| Back to top |
|
 |
mikep
Joined: 24 Sep 2005
Posts: 765
Location: Austin, TX
|
|
Posted: 27 December 2005, 18:42 PM Post subject: |
|
|
| dkinzer wrote: | | The compiler should have warned you that you can't pass a constant by reference. It wasn't detected because the constant has the value zero which is acceptable as a special value meaning no data is being passed. However, since the write count was non-zero, the compiler should have generated a warning. | I'm not sure why in the original code it worked in one case and not others. Can you explain that? Is it some internal implementation thing? |
|
| Back to top |
|
 |
|