Weird values
John Abshier
Posts: 1,116
CON 'CMPSO3Demo _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 SCL = 0 'Define Constants SDA = 1 VAR OBJ C : "CMPS03" Tv : "Tv_Text" PUB Main | version, bBearing, wBearing Init Tv.str(string("Bus check ")) Tv.dec(C.BusCheck) Tv.out(13) Tv.str(string("Device Present ")) Tv.dec(C.Present) Tv.out(13) if C.Present Tv.str(string("Present")) Tv.out(13) version := C.GetVersion Tv.str(string("Version ")) Tv.hex(version,8) Tv.out(13) bBearing := C.GetBBearing Tv.str(string("Byte Bearing ")) Tv.hex(bBearing,8) Tv.out(13) wBearing := C.GetWBearing Tv.str(string("Word Bearing ")) Tv.hex(WBearing,8) PUB Init Tv.start(12) ' should check fail Tv.out($00) ' clear Tv.out($01) ' home C.Init(SDA, SCL)
CON 'CMPS03 object CMP_ADDRESS = $C0 OBJ I2C : "I2C LowLevel" PUB Init(SDA, SCL) repeat 9 I2C.i2cStop I2C.Initialize(SDA, SCL) ' Initialize i2c MASTER in present COG PUB GetVersion result := ReadReg($00) return PUB GetBBearing result := ReadReg($1) return PUB GetWBearing : wBearing wBearing := ReadReg($2) wBearing <<= 8 wBearing |= REadReg($3) return PRI ReadReg(reg) I2C.i2cStart I2C.i2cWrite(CMP_ADDRESS | 0, 8) I2C.i2cWrite(reg, 8) I2C.i2cStart I2C.i2cWrite(CMP_ADDRESS | 1, 8) result := I2C.i2cRead(0, 8) return PUB BusCheck result := I2C.testBus return PUB Present result := I2C.devicePresent(CMP_ADDRESS) return
The output of the program that reads a CMPS03 compass is
Version 9· This is the correct value.
bBearing $9E8· This should be a byte. E8 would be reasonable.
wBearing $9E80CD6 This should be a word. $0CD6 is a consistent result with $E8 for bBearing
I don't understand what is going on.· I thought that the result local variable was set to 0 on a call.
Comments
This is simple to fix... if you are expecting a BYTE, then just AND the result with $FF... expecting a WORD, then AND the result with $FFFF... for a LONG, just leave it alone.
I'll make note of this when I release this object in the future.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Who says you have to have knowledge to use it?
I've killed a fly with my bare mind.
CJ, I tried stuffing the result into the proper sized variable, but Spin only allows long local variables.
John, as you pointed out in a PM...
"The problem is that i2cData is global to the object. Making it local to Pub i2cRead solves the problem."
The reason I made i2cData global was so that I could use the incoming data as a FIFO (First-In-First-Out).
This kind of circumstance has been handy for some applications I have come across so I implemented the variable
this way.· That said, it is difficult to design a one size fits all.· The whole idea anyway is that the propeller
objects can be modified by the user to fit a specific application.· In some cases, the way I did it can reduce
the amount of code space required, when in a pinch can make a real impact.· For example:
a section of your code that reads....
...could be re-written as...
...it only saves a 'long' but if this can be applied several times, it could make a difference.
And yes, documentation is the answer, however the Lowlevel I2C routines John uses here have not officially been released
to the object exchange, instead they were used in an object (DS1307) which has been released.
As far as the ack bit ... this depends on the i2c device itself.· On some devices they don't care, on others they either
look for a "1" or a "0".· From the documentation, it looks like the CMPS03 wants to see a "0".
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.