How to solve problems communicating with an ADXL345, ADXL346 or ADXL350 via I2C.

I am having trouble debugging some I2C stuff and I am looking for some tips

On the test jig, I am reading device ID of 0xFF.

When I hook up a logic analyzer, it looks like everything is being NACKed rather than ACKed.

  • From experience it sometimes feels like every new board has some I2C communications issues.

    I2C is a simple protocol using only 2 wires and is quite tolerant of many issues but sometimes tricky to get working.  Here are some suggestions:

    1)    1) Check connections:

          A. Is the device powered, check ground, vddio and all power/ground connections on the device.

          B. Check the reserved pins; some reserved pins need to be grounded, others tied high and others must be open.

          C. Check the I2C connections for opens shorts or crossed wires:

                                              i.     Is SDA on the device tied to SDA on the master?

                                             ii.     Is SCL tied to SCL on the master?

                                            iii.    Although the SDO pin is not used as part of I2C it sets the I2C address is it open? Tied high or tied low?  It should be tied one way or the other not left floating.

          D. Check the I2C pull-ups; is there a pull-up on SCL and SDA?

    2)   2) Check the I2C master driver, firmware or software.  Are you using known good software that works for your I2C master?  Since in this question we have hooked up a Logic analyzer; we can confirm the master is working.

    3)   3)  Check for the correct device address.  Since the ADXL345 and related parts have a pin that selects between more than one I2C address and there are two possible I2c addresses have the software look for the device at both addresses.

    Below is some software that I used on a recent board after re-checking the wiring several times.

    Note that in the I2C code there is a verision of the routines with a P (Primary) suffix and a version with an A (Alternate) suffix to represent the two possible addresses

    Please note that this is not a complete example and relies on the standard header files and support routines posted here:

    Header files and utility routines:

    http://ez.analog.com/thread/2563?tstart=30

    Some example applications

    http://ez.analog.com/thread/2420?tstart=0

    It is a partial example to highlight the key pieces of code and not get bogged down in the lower level code or full project detail since they will vary with your hardware setup.  More complete examples can be posted if requested.

      UART_Config();

      myputchar('\r');

      myputchar('\n');

      debug_printf("Hello world\n");

      debug_printf("DEBUG @ line %d in file %s\n", __LINE__, __FILE__);

      while(1) {

      xl346ReadP(1,XL346_DEVID,buffer);

      debug_printf("Device Primary ID is %x\n",buffer[0]);

      xl346ReadA(1,XL346_DEVID,buffer);

      debug_printf("Device ALT ID is %x\n",buffer[0]);

      }

    This is based on the IO routines:

    void xl346ReadP(unsigned char count, unsigned char regaddr, unsigned char *buf){

      int i;

      /* send I2c start and the alt address, the register address */

    #ifdef xdebug_printf_h_

      debug_printf("DEBUG @ line %d in file %s, read %d bytes from 0x%02x.\n", __LINE__, __FILE__,count, regaddr);

    #endif

      I2C_START();

      I2C_WRITE(XL346_SLAVE_WRITE); /* read bit not set */

      I2C_WRITE(regaddr);

      I2C_STOP();

        // start and send the read command

      I2C_START();

      I2C_WRITE(XL346_SLAVE_READ);

     

      for( i=0;i<count;i++ ){

        buf[i] = I2C_READ();

        if( i+1<count ){

          I2C_ACK_M();

        } else {

          /* end the burst read with a nack then stop */

          I2C_NACK_M();

          I2C_STOP();

        }

      }

    }

    void xl346ReadA(unsigned char count, unsigned char regaddr, unsigned char *buf){

      int i;

      /* send I2c start and the alt address, the register address */

    #ifdef xdebug_printf_h_

      debug_printf("DEBUG @ line %d in file %s, read %d bytes from 0x%02x.\n", __LINE__, __FILE__,count, regaddr);

    #endif

      I2C_START();

      I2C_WRITE(XL346_ALT_WRITE); /* read bit not set */

      I2C_WRITE(regaddr);

      I2C_STOP();

        // start and send the read command

      I2C_START();

      I2C_WRITE(XL346_ALT_READ);

     

      for( i=0;i<count;i++ ){

        buf[i] = I2C_READ();

        if( i+1<count ){

          I2C_ACK_M();

        } else {

          /* end the burst read with a nack then stop */

          I2C_NACK_M();

          I2C_STOP();

        }

      }

    }

    I hope this helps.

  • This question has been assumed as answered either offline via email or with a multi-part answer. This question has now been closed out. If you have an inquiry related to this topic please post a new question in the applicable product forum.

    Thank you,
    EZ Admin