This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Adding TWI communication with accelerometer to BLE

Hello,

I have a nRF51DK. I am trying to use the TWI driver to communicate via I2C with an accelerometer MMA8452Q. I already have a working code based on several SDK examples : basically it is based on the "experimental : multiactivity" example with a custom BLE service. Softdevice S130. As I said I try to add TWI support to get the data from the accelerometer and transfer the data over BLE. On the hardware side, I have a separate 3.3V to supply the accelerometer and I connect directly the SCL pin to the P0.07 pin of the nRF51DK and the SDA pin to the P0.30 pin of the nRF51DK. On the software side, I have added to my working code :

  • a call to twi_init() in the main function

  • the function twi_init() itself, based on the SDK TWI sensor example

  • after the call of twi_init in the main function, a first call to nrf_drv_twi_tx is performed in order to set the accelerometer in active mode. I then expect a call to the TWI event handler to say "NRF_DRV_TWI_TX_DONE", but the handler is never called.

  • the TWI event handler function twi_evt_handler itself

  • I added a timer event every 2000 ticks to initiate a read action on the I2C bus; the handler is named accelerometer_sample_read_timeout_handler

As written above, the TWI event handler is not called after the first write action (set the sensor in active mode). However, if I disconnect the wires between the nRF51DK and the sensor the handler is immediately called with the "NRF_DRV_TWI_ERROR" event (NRF_TWI_ERROR_ADDRESS_NACK).

I guess I must be doing something wrong but I can't figure out what. Could you please help me? Attached is the main.c and the MMA8452Q.h (containing the registers defines).

Thanks a lot in advance for your help. main.c MMA8452Q.h

  • I think I corrected my problem but I am unsure whether the correction is right or not: In the twi_sensor example, the address of the sensor is defined like this:

    #define MMA7660_ADDR        (0x98U >> 1)
    

    the ">> 1" probably refers to the following description of the twi functions: [in] address Address of a specific slave device (only 7 LSB). However, when I use the same syntax for the MMA8452Q device, i.e.:

    #define MMA8452Q_ADDR      (0x1DU >> 1)
    

    the device never answers to any read or write requests. When I remove the ">> 1" everything works perfectly. Is this correct to remove the ">> 1" in my case? And why?

  • I was just playing around with this stuff as well. If you look at the datasheet for the accelerometer they're using in the example, the address is actually 0x4c. When shift that up you get 0x98. What I believe is happening (I'm still learning this stuff myself) is that they are writing the address like that because there needs to be room for the read/write bit to be set, but to be honest, that's a guess.

Related