bma180 accelerometer with I2C
seiko99
Posts: 9
I finally got a quickstart board and need to quickly get started on what I thought would be a simple project of connecting this breakout board I got from sparkfun.
I have dug and dug for any projects with sample code I can look at using this thing and can't find a thing. I think that quad copters since they use propellers is clouding the search engines - lol
This is such a great sensor and has been out so long, surely someone has done something with it. I started an object file with all the registers and values and have been trying to modify the c code that is on the sparkfun site, but I guess the jump to spin is too much for me.
I have been at it almost every evening for almost 2 weeks and am getting nowhere. Help?
I have dug and dug for any projects with sample code I can look at using this thing and can't find a thing. I think that quad copters since they use propellers is clouding the search engines - lol
This is such a great sensor and has been out so long, surely someone has done something with it. I started an object file with all the registers and values and have been trying to modify the c code that is on the sparkfun site, but I guess the jump to spin is too much for me.
I have been at it almost every evening for almost 2 weeks and am getting nowhere. Help?
Comments
To read from a BMA180 register if the BMA180 SCL is <SCL pin> and SDA is on the next higher I/O pin do:
Z := i2c.ReadByte(<SCL pin>, <device>, i2c#OneAddr | <register>)
To write to a BMA180 register do:
i2c.WriteByte(<SCL pin>, <device>, i2c#OneAddr | <register>, <data to write>)
The <device> code is the 8-bit byte that selects the device. It's the device address (a 7-bit number) shifted left one bit to make the byte sent to the device. The least significant bit of this byte is always zero for these routines. The BMA180 allows for two different device addresses depending on the setting of one of the device's pins. See the datasheet for details.
Similarly, you can read or write multiple bytes from / to successive BMA180 registers. See the comments in Simple_I2C_Driver for details.
I just spent $60 bucks on ink to finally print out the datasheet. I have started with the Basic_i2c_driver and created my own object file containing all the registers for the bma180.
I was confused at first thinking that I had to use the prop's SCL and SDA. I am believing now that this is bit-bang and I can use whatever pins I want. I guess my biggest confusion comes from the examples that were put together by James Burrows (I think). The i2c object is initialized and then the object/device specific routines are initialized and used. They are so device specific, it is daunting as a first propeller project.
Anyways, I am pushing on and will post some code tonight hopefully. Your examples should help a lot. I am excited about the things I see with the propeller. Last year I built a machine with an arduino mega that drove me so crazy with the interrupt game that I almost gave up. I think once this little accelerometer starts doing what I need, I may have a mega for sale on ebay.
This is where I am at for the moment. The "i2c#bma180address | BMA_CHIPID" is not making sense and is just me guessing. Maybe I am over analyzing.
Should it be i2c.ReadByte(i2cscl, bma180address, BMA_CHIPID) ? I see that the interpreter wants a constant if I do it the old way.
Thanks again for any help
A piece of my code for one axis is as follows:
VAR
long id
word bmversion, temp, temp1, temp2, temp3, temp4, temptemp
long tempX, tempY, tempZ
PUB getX
repeat while temp <> 1
temp := i2cObject.readLocation(bmaddress, ACCXLSB) & $1
temp := i2cObject.readLocation(bmaddress, ACCXMSB)
temp2 := temp << 8
temp2 |= i2cObject.readLocation(bmaddress, ACCXLSB)
tempX := temp2 >> 2
temp := 0
I guess I should convert to signed decimal? Are the <> and other bitwise methods I am calling the right ones? Oh yeah, how about degrees?
I decided to not right shift, leaving a couple of flag bits in the word. It is really inconsequential if I can get the negative numbers (I would rather work with 14 bits). As it is, I only get positive.
I tried setting tempX to $FF80 which should be negative 128. Still wont show negative. I printed out my words in binary and the sign bits are set.
I am playing around with numbers.spin, but not getting anywhere. Help?
Two easy ways to fix this. Use the "~~variable" 16-bit sign extension operator. (i.e. "tempX := ~~temp2" ) Or, to sign extend any word width, use the shift left and shift arithmetic right operators. (i.e. "tempX := (temp2 <<16) ~> 16" )
Lawson
Thank you. Your profile pic leads me to think you are a tesla fan. Am I correct? I am in Victoria just south of you.
did you ever get your spin code working for the BMA180? I just ordered one and it'd be great if I could use your code to take some readings!