-->
Page 1 of 1

[Resolved] I2C data woes trying to read MPL3115A2

PostPosted: Wed Jul 15, 2015 11:00 am
by Steve Morgan
I'm trying to read barometric pressure and temperature from an MPL3115A2 and have been banging my head against a wall for the past two days. This is my first project with an ESP8266 and the first time I've tried to hand-cut code to deal with I2C devices. For reference, my ESP8266 is actually a SparkFun Thing. I originally tried using the Arduino IDE, but switched to NodeMCU in the hope that I would have more success. Thus far, I haven't.

This is my code...
Code: Select allid=0  -- Software I2C
io_pin= {[0]=3,[2]=4,[4]=2,[5]=1,[12]=6,[13]=7,[14]=5} -- this maps GPIO numbers to internal IO references

sda=io_pin[2] -- connect to pin GPIO2
scl=io_pin[14] -- connect to pin GPIO14

addr=0x60 -- the I2C address of our device

function initialise()
     i2c.setup(id,sda,scl,i2c.SLOW)
   
    write_reg(addr,0x26,0x38)
    write_reg(addr,0x13,0x07)
    write_reg(addr,0x26,0x39)

    print("Waiting for data")
    repeat
      status = read_reg(addr,0x00)
      uart.write(0,".")
    until bit.band(status,0x08) == 0x08

    print("")
    print("Status")
    print(status)
    Pmsb = read_reg(addr,0x01)
    Pcsb = read_reg(addr,0x02)
    Plsb = read_reg(addr,0x03)
    Tmsb = read_reg(addr,0x04)
    Tlsb = read_reg(addr,0x05)

    print("Pmsb")
    print(Pmsb)
    print("Pcsb")
    print(Pcsb)
    print("Plsb")
    print(Plsb)
    print("Tmsb")
    print(Tmsb)
    print("Tlsb")
    print(Tlsb)
   
end

function read_reg(dev_addr, reg_addr)
     i2c.start(id)
     i2c.address(id, dev_addr ,i2c.TRANSMITTER)
     i2c.write(id,reg_addr)
     i2c.stop(id)
     i2c.start(id)
     i2c.address(id, dev_addr,i2c.RECEIVER)
     c=i2c.read(id,1)
     i2c.stop(id)
     return string.byte(c)
end

function write_reg(dev_addr, reg_addr, val)
     i2c.start(id)
     i2c.address(id, dev_addr ,i2c.TRANSMITTER)
     i2c.write(id,reg_addr)
    i2c.write(id,val)
     i2c.stop(id)
end

initialise()


And this is the output I get:

Code: Select allWaiting for data
.........................................................................
Status
14
Pmsb
14
Pcsb
14
Plsb
14
Tmsb
14
Tlsb
14


Having initialised the device, it polls the status register until the device reports that data is available. The status of 14 indicating that there is both pressure and temperature data.

The obvious problem is that every register that I read to retrieve the data returns the same value: 14 (decimal).

I've tried putting some delays in between the write and read steps in read_reg, but it's made no difference.

Can someone point out what I'm doing wrong?
Thanks.

Re: I2C data woes trying to read MPL3115A2

PostPosted: Wed Jul 15, 2015 4:46 pm
by tytower
I don't know nodemcu but would suggest its reading the wrong pin. Check the wiki on this page above you for the pin assignments. I2C requires specific pin setup too but I can't tell, from the short bit of code, what you have done ..

Re: I2C data woes trying to read MPL3115A2

PostPosted: Thu Jul 16, 2015 2:50 pm
by Steve Morgan
Fixed it!

I tried an i2c scanner, which confirmed that I was using the correct GPIO pins.

Going over the datasheet for the MPL3115A2 finally revealed the answer.

When reading a register from the device, I SHOULDN'T have been using i2c.stop(id) after sending the address. Rather, the datasheet said to send an i2c.start(id) again.

Lo-and-behold, with the offending line commented out, I'm now successfully reading pressure and temperature. Here's the updated read_reg function, for reference:

Code: Select allfunction read_reg(dev_addr, reg_addr)
     i2c.start(id)
     i2c.address(id, dev_addr ,i2c.TRANSMITTER)
     i2c.write(id,reg_addr)
     -- i2c.stop(id) <-- This was the problem. Mustn't send the Stop
     i2c.start(id)
     c=i2c.read(id,1)
     i2c.stop(id)
     return string.byte(c)
end