Shop OBEX P1 Docs P2 Docs Learn Events
Trouble Porting Arduino code for LSM303 — Parallax Forums

Trouble Porting Arduino code for LSM303

CountMurphyCountMurphy Posts: 19
edited 2013-03-30 19:41 in Propeller 1
So I recently bought a LSM303 tilt compasated compass (https://www.sparkfun.com/products/10703 ). I was originally hopeing it would be a simple serial interface that I could just read the headings off of. The chip however uses I2C. The site also contains sample Arduino code (http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/Magneto/LSM303_Example.zip ). Now I've never worked with I2C, but I begain to port that code over to spin, but I am having trouble just reading values off the chip. Could someone more experianced in spin and I2C look at my code and give me a few pointers? Or if someone knows of an already built object for the chip that would be helpful too. Thanks in advance. Hopefully my code isn't that far off.

Edit: the data ready pin on the chip is going high, so I think its initalized ok. I just cant read it :(

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2013-03-24 17:38
    A few things come to mind. Device addresses have to be pre-shifted for most drivers (to make space for the r/w bit). In your case you'd end up with $3C and $30. Also, you should get an updated version of the I2C driver, one which supports single byte addresses (the old version was hardcoded for 16bit addresses and the name you use suggests usage of the old one). And one more thing, WriteByte includes start/stop calls, so there is no need to wrap your call(s) with start/stop.
  • CountMurphyCountMurphy Posts: 19
    edited 2013-03-24 18:00
    Ok, driver updated and all start stop calls have been stripped from the write functions. I am uncertain what you meant with shifting the addresses to $3C and $30. Could you clarify?
  • kuronekokuroneko Posts: 3,623
    edited 2013-03-24 18:12
    I am uncertain what you meant with shifting the addresses to $3C and $30. Could you clarify?
    Device addresses a only 7 bit in size, the LSBit (in a byte) is used to indicate a read or write operation. For example your $1E (%0001_1110) is shifted left by 1 (*2) and therefore becomes %0011_1100 ($3C). Bit 0 of the address is then inserted by the driver, e.g. (in ReadPage)
    ackbit := (ackbit << 1) | Write(SCL, devSel [COLOR="#FF0000"]| Recv[/COLOR])
    
    Also, make sure your register address is or'd with i2c#OneAddr to indicate single byte address mode, e.g.
    i2c.WriteByte(22, LSM303_ACC, [COLOR="#FF0000"]i2c#OneAddr|[/COLOR]CTRL_REG1_A, $27)
    
  • CountMurphyCountMurphy Posts: 19
    edited 2013-03-24 18:52
    Ok, I'm making progress. If I print out temp under the LSM303_read method I do get data back (the same data looped but its more than i had). If I try to print the accel and mag arrays I still get zeros. I think I'll need to rewrite all the portions that used single byte originally. thanks for your advice. Never would have figured out the address shifting with out it.
  • CountMurphyCountMurphy Posts: 19
    edited 2013-03-30 14:46
    If anyone could offer a hand I'm still having a ton of trouble talking to this device. I've made the changes that were prevously discussed, however I'm still not getting any real data from the chip. I think the issue lies in the read code. With the read functions the arduino has :
    Wire.beginTransmission(LSM303_MAG);
      Wire.send(OUT_X_H_M);
    

    For spin's i2c object I have no idea how to translate it. The docs in the i2c object suggested something like
    i2c.WriteByte( <SCL pin #>, <device code>, i2c#NoAddr)
    
    but when I try it I get a compile error because I didn't send a data varable with it.

    I'm beyond confused and would really appreciate some help.
  • kuronekokuroneko Posts: 3,623
    edited 2013-03-30 17:52
    For spin's i2c object I have no idea how to translate it. The docs in the i2c object suggested something like
    i2c.WriteByte( <SCL pin #>, <device code>, i2c#NoAddr)
    
    but when I try it I get a compile error because I didn't send a data varable with it.
    That's a copy+paste issue in the documentation, for WriteByte you need the 4th parameter which is the payload (byte to be written).
  • CountMurphyCountMurphy Posts: 19
    edited 2013-03-30 19:24
    kuroneko wrote: »
    That's a copy+paste issue in the documentation, for WriteByte you need the 4th parameter which is the payload (byte to be written).


    But I'm not sure what the payload would be. The code quoted above seems to open a connection to the magnetometer and sends it a register, then closes the connection. There is no data packet. After it writes, it attempts to read. could all those lines be summed up with this?
    i2c.ReadByte(22,LSM303_MAG,OUT_X_H_M|i2c#OneAddr)
    

    Thats my confusion. I'm not sure if the beginTransmit and the send are part of the i2c.ReadByte code, or its something else.
  • kuronekokuroneko Posts: 3,623
    edited 2013-03-30 19:31
    You tell me! It (sample code) looked a bit suspicious to me last time I checked. The accelerometer part looked more consistent (i.e. reading the relevant L/H values). I assume it works on the Arduino? FWIW, beginTransmission looks like it combines sending start and device selector.
  • CountMurphyCountMurphy Posts: 19
    edited 2013-03-30 19:41
    kuroneko wrote: »
    You tell me! It (sample code) looked a bit suspicious to me last time I checked. The accelerometer part looked more consistent (i.e. reading the relevant L/H values). I assume it works on the Arduino? FWIW, beginTransmission looks like it combines sending start and device selector.

    Ok, I'm going to assume that ReadByte is the correct code. I'm going to use the accelerometer code as more of a guide. I will get this working eventually. Thanks for your patience. I know these are really noobish questions. And yeah, the code did work on the arduino. One step closer.....
Sign In or Register to comment.