Use this forum to chat about hardware specific topics for the ESP8266 (peripherals, memory, clocks, JTAG, programming)

User avatar
By Moey
#36716 Hi,
hopefully this is the right place to post. I'm currently struggling to get communication going with an LTC4151 current- and voltage-monitor. Scanning the I2C-bus I get a reply on the expected address. However if I'm reading on the registers for current, voltage and auxiliary voltage I always get the same result no matter what voltage is applied to the ADC. Here's a link to the datasheet of that chip: http://cds.linear.com/docs/en/datasheet/4151ff.pdf

Also setting the control-register seems to work, but I cannot read it back. Always getting 0es.

Have a look at my test-code:
Code: Select allgpiolookup = {[0]=3,[1]=10,[2]=4,[3]=9,[4]=1,[5]=2,[10]=12,[12]=6,[13]=7,[14]=5,[15]=8,[16]=0}

ltc4151 = 0x6f

-- setup I2c
function init_i2c()
     -- SDA and SCL can be assigned freely to available GPIOs
     local sda = gpiolookup[0] -- GPIO0
     local scl = gpiolookup[2] -- GPIO2

     i2c.setup( 0, sda, scl, i2c.SLOW )
end

function getI2C( address )
        local rec
        local msb = 0
        local lsb = 0

        i2c.start( 0 );
        i2c.address( 0, ltc4151, i2c.TRANSMITTER )
        i2c.write( 0, address )
        i2c.stop( 0 )

        i2c.start( 0 )
        i2c.address( 0, ltc4151, i2c.RECEIVER )
        rec = i2c.read( 0, 2 )
        i2c.stop( 0 )

        msb = string.byte( rec, 1 )
        lsb = string.byte( rec, 2 )

print( msb )
print( lsb )

        local ret = bit.lshift( msb, 4 ) + bit.rshift( lsb, 4 )

        return( ret )
end

function getADC_current()
        -- Read current: Address 0x00;
        return( getI2C( 0x00 ) )
end

function getADC_usol()
        -- Read voltage: Address 0x02;
        return( getI2C( 0x02 ) )
end

function getADC_uaux()
        -- Read aux-voltage: Address 0x04;
        return( getI2C( 0x04 ) )
end

function getControl()
        -- Read control register: Address 0x06;
        local ret
        i2c.start( 0 )
        i2c.address( 0, ltc4151, i2c.TRANSMITTER )

        i2c.write( 0, 0x06 )
        i2c.stop( 0 )

        i2c.start( 0 )
        i2c.address( 0, ltc4151, i2c.RECEIVER )
        ret = i2c.read( 0, 1 )
        i2c.stop( 0 )

        return( string.byte( ret ) )
end

function setI2C( address, val )
        i2c.start( 0 )
        i2c.address( 0, ltc4151, i2c.TRANSMITTER )
        i2c.write( 0, address, val )
        i2c.stop( 0 )
end

function ltctest()
        -- enter test mode
        setI2C( 0x06, 0x04 )

        setI2C( 0x00, 0xaa )
        setI2C( 0x01, 0xa0 )

        print( getADC_usol() )

        -- reset control register
        setI2C( 0x06, 0x00 )
end

init_i2c()


After starting up the esp-module, I entered the following:

Code: Select all> dofile("ltc4151.lua")
> getADC_usol()
0
240
> print( getADC_usol() )
0
240
15
> print( getControl() )
0
> setI2C( 0x06, 0x04 )
> print( getControl() )
0
> ltctest()
170
160
2730
> print( getADC_usol() )
0
240
15
>

As you can see, I always get back 0 and 240 (0x00 for msb and 0xf0 for lsb).

Now look at the ltctest carefully: first I'm setting the control-register to 0x04 (test-mode). In this mode you should be able to set arbitrary values to the ADC-registers. I'm setting register 0x00 and 0x01! After that, I'm reading back register 0x02 and 0x03!! And there I'm getting the expected values. Reading back 0x00/01 I still get the 0x00 and 0xf0 values. Something is messed up there.

Finally I already did read that chip successfully on an Atmega 8. The only difference in the code to me is, that I'm doing a repeated-start after writing the register I want to read. In Lua I have to make a i2c.stop, i2c.start and i2c.address with RECEIVER-option set.

Code: Select alluint16_t getI2C( uint8_t address ) {
   uint8_t msb, lsb;
   msb = lsb = 0;

   if( i2c_start( LTC4151 + I2C_WRITE ) == 0 ) {
      i2c_write( address );
      i2c_rep_start( LTC4151 + I2C_READ );
      msb = i2c_readAck();
      lsb = i2c_readNak();
      i2c_stop();

      return( ( msb << 4 ) + ( lsb >> 4 ) );
   } else {
      return( 0 );
   }
}


Any ideas on how I can get down to the problem? Unfortunately I'm not blessed with a memory oscilloscope. So I can't actually look into the bus or timings :(

Appreciate your help!