This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

accelerometer_result_error

Hello ,I wrote a program that allows to control the LIS2DE12 accelerometer but I am reviewing a fixed result which is always X = 72, Y = 33, Z = 32, I find out where the problem , thanks you in advance.

`int main(void)	
{
	int8_t X,Y,Z;
    
    uart_config();
    
    //accel_I2C_datawrite(&twi_instance);
    twi_init();
     m_device_address = accel_addr;
 
    uint8_t rx_buffer[6];
   rx_buffer[0] = 0x00;
//int threshold;
//accel_set_threshold(threshold);
    
        




            while(true)
        {
            accel_xyz_read(&X,&Y,&Z);
         printf("Groupeer accelero DATA2:  X: %d  Y: %d  Z: %d  \n", X ,Y,Z);
					nrf_delay_ms(1000);
        }      
    
}
`
  • Hello Amed

    From what I can see in the code you posted, you do not write anything to the LIS2DE12 chip (the accel_I2C_datawrite in main is commented out) until you try and read from it.

    So you never configure the chip on start-up.

    In your accel_I2C_datawrite function (which is currently commented out) you write to the CTRL_REG1 register, however it seems like you write all zeroes, 0x00. If you look at the description of CTRL_REG1 in the LIS2DE12 datasheet this will ensure the chip is in power-down mode, as well as disable all axis. It also states specifically in the LPen field that the field must be set to 1 for correct operation of the device.

    I would imagine you have to have the chip powered up and correctly configured, with the axis sensors enabled, for it to generate any sensible data.

    You state in your comment that you want an indication that there is movement without reading the axis, I recommend you look at the INT1_CFG and INT2_CFG register. There you can configure interrupts on movement detection for the different axis. This will generate a change in pin 11 and 12 of the LIS2DE12, which you can sense with a GPIO of the nRF chip.

    Best regards

    Jørn Frøysa

  • Hello, Thank you for your quick reply I have configured the registers of LI2SD12, and here is all the code if you help me to make it work, in fact I tried to expoliter the result of register INT1_THS by the function accel_set_threshold Best Regards,

  • Could you please edit this comment and use the code functionality? the normal formatting of comments completely mess up the code. Just press edit on your comment, select all your code and press the button with the "101 010" in the toolbar above.

  • Thanks , this the code that used

      #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_uart.h"
    #include "app_error.h"
    #include "nrf_drv_twi.h"
    #include "nrf_delay.h"
    static uint8_t m_device_address;  
    /*UART buffer size. */
    #define UART_TX_BUF_SIZE 256
    #define UART_RX_BUF_SIZE 1
    const uint8_t access_data                = 0x01; 
    #define DEVICE_SCL_PIN 13
    #define DEVICE_SDA_PIN 12
    #define accel_addr 0X19
    #define CTRL_REG1 0x20
    #define CTRL_REG2 0x21
    #define CTRL_REG3 0x22
    #define CTRL_REG4 0x23
    #define CTRL_REG5 0x24
    #define INT1_THS  0x32 
    
    
    #define OUT_X_L   0x28    /**< Accelero X LSB output */
    #define OUT_X_H   0x29    /**< Accelero X MSB output */
    #define OUT_Y_L   0x2A    /**< Accelero Y LSB output */
    #define OUT_Y_H   0x2B    /**< Accelero Y MSB output */
    #define OUT_Z_L   0x2C    /**< Accelero Z LSB output */
    #define OUT_Z_H   0x2D    /**< Accelero Z MSB output */
    
    #define INT1_CFG  0x30    /**< Interrupt setting register */
    #define INT1_SRC  0x31    /**< Interrupt status register */
    #define INT2_THS  0x32    /**< Interrupt threshold */
    
    #define SO_2G    61       /**< Set sensitivity to 0.061mg/digit for FS=2g */
    #define SO_4G   122       /**< Set sensitivity to 0.122mg/digit for FS=4g */
    #define SO_8G   244       /**< Set sensitivity to 0.244mg/digit for FS=8g */
    #define SO_16G  732       /**< Set sensitivity to 0.732mg/digit for FS=16g */
    
    #define FS_2G    0x00     /**< Set full-scale value to 2g */
    #define FS_4G    0x10     /**< Set full-scale value to 4g */
    #define FS_8G    0x20     /**< Set full-scale value to 8g */
    #define FS_16G   0x30     /**< Set full-scale value to 16g */
    
    #define THS_2G   16       /**< Interrupt threshold sensitivity for FS=2g -> 16mg/digit */
    #define THS_4G   31       /**< Interrupt threshold sensitivity for FS=4g -> 31mg/digit */
    #define THS_8G   63       /**< Interrupt threshold sensitivity for FS=8g -> 63mg/digit */
    #define THS_16G 187       /**< Interrupt threshold sensitivity for FS=16g -> 125mg/digit */
    #define BURST_MODE 0x80
    #define FS_ACCEL   FS_2G
    #define SO_ACCEL   SO_2G  //Sensitivity set to 2G
    #define THS_ACCEL THS_2G
    
    nrf_drv_twi_t twi_instance = NRF_DRV_TWI_INSTANCE(0);
    
    uint8_t device_address = 0; 
    bool device_found = false; 
    
    static const nrf_drv_twi_t * p_twi_master;
    
    static void uart_events_handler(app_uart_evt_t * p_event)
    {
        switch (p_event->evt_type)
        {
            case APP_UART_COMMUNICATION_ERROR:
                APP_ERROR_HANDLER(p_event->data.error_communication);
                break;
    
            case APP_UART_FIFO_ERROR:
                APP_ERROR_HANDLER(p_event->data.error_code);
                break;
    
            default:
                break;
        }
    }
    
    static void uart_config(void)
    {
        uint32_t                     err_code;
        const app_uart_comm_params_t comm_params =
        {
            RX_PIN_NUMBER,
            TX_PIN_NUMBER,
            RTS_PIN_NUMBER,
            CTS_PIN_NUMBER,
            APP_UART_FLOW_CONTROL_DISABLED,
            false,
            UART_BAUDRATE_BAUDRATE_Baud115200
        };
        APP_UART_FIFO_INIT(&comm_params,
                           UART_RX_BUF_SIZE,
                           UART_TX_BUF_SIZE,
                           uart_events_handler,
                           APP_IRQ_PRIORITY_LOW,
                           err_code);
    
        APP_ERROR_CHECK(err_code);
    }
    
    //test of the twi bus
    void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
    {     ret_code_t err_code;  
          static bool init_done = false;
          static bool timeout_flag = false;
          static uint8_t x_sample;
          switch(p_event->type)
        {
            case NRF_DRV_TWI_EVT_DONE:
                        if (!init_done) {                               
                                init_done = true;
                                return;
                // If EVT_DONE (event done) is received a device is found and responding on that particular address
                printf("\r\n!!\r\nGroupeer accelero found at 7-bit address: %#x!\r\n!\r\n\r\n", device_address);
                device_found = true;
                        err_code = nrf_drv_twi_rx(&twi_instance , accel_addr, &x_sample, sizeof(x_sample));
                                    APP_ERROR_CHECK(err_code);
                break;
            case NRF_DRV_TWI_EVT_ADDRESS_NACK:
                printf("No address ACK on address: %#x!\r\n", device_address);
                    printf("on");
                break;
            case NRF_DRV_TWI_EVT_DATA_NACK:
                printf("No data ACK on address: %#x!\r\n", device_address);
                break;
                }   
            default:
                break;        
        }   
    }
    
    //init the twi_bus
    void twi_init (void)
    {
        ret_code_t err_code;
        uint8_t reg[2] = {CTRL_REG1, 0x01};
        const nrf_drv_twi_config_t twi_config = {
           .scl                = DEVICE_SCL_PIN,
           .sda                = DEVICE_SDA_PIN,
           .frequency          = NRF_TWI_FREQ_400K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH
        };
        
        err_code = nrf_drv_twi_init(&twi_instance, &twi_config, twi_handler, NULL);
        APP_ERROR_CHECK(err_code);
        
        nrf_drv_twi_enable(&twi_instance);
                err_code = nrf_drv_twi_tx(&twi_instance, accel_addr, reg, sizeof(reg), false);
        APP_ERROR_CHECK(err_code);
    }
     ret_code_t accel_I2C_register_write(uint8_t slave_addr,uint8_t * pdata, uint32_t bytes)
    {
        ret_code_t ret_code;
        
        ret_code = nrf_drv_twi_tx(p_twi_master, slave_addr, pdata, bytes , false);
        
        return ret_code;
    }
    
    ret_code_t accel_I2C_datawrite(const nrf_drv_twi_t * p_twi_instance)
    {
      nrf_drv_twi_enable(p_twi_instance);  
    	
    	
    
        //ret_code_t ret_code;
    //          
    //    uint8_t tx_data1[2] = {CTRL_REG1, 0x00};
    //    ret_code = accel_I2C_register_write(accel_addr, tx_data1, sizeof(tx_data1) );
    //        nrf_delay_ms(10);
    //				uint8_t tx_data2[2] = {CTRL_REG1, 0x01};
    //       ret_code = accel_I2C_register_write(accel_addr, tx_data2, sizeof(tx_data2) );
    //	   	nrf_delay_ms(1);
    //        
    //        return ret_code;
    }
    
    ret_code_t accel_I2C_register_read(uint8_t slave_addr, uint8_t reg_addr,  uint8_t * pdata, uint32_t bytes)
    {   
        ret_code_t ret_code;
    
        ret_code = nrf_drv_twi_tx(p_twi_master,slave_addr, &reg_addr,1,false);
    
        if(ret_code != NRF_SUCCESS)
        {
         
                return ret_code;
        }
    
        ret_code = nrf_drv_twi_rx(p_twi_master,slave_addr, pdata, bytes);
    
        return ret_code;
    }
    // read the axes x, y,z
    static void accel_xyz_read(uint16_t * x_value, uint16_t * y_value, uint16_t * z_value)
    {
        m_device_address = accel_addr;
        ret_code_t ret_code;
    
        uint8_t rx_buffer[6];
        rx_buffer[0] = 0x00;
    
    
    
    	ret_code = accel_I2C_register_read(m_device_address,access_data, rx_buffer, sizeof(rx_buffer));
    
       *x_value = (rx_buffer[1]<<8)|rx_buffer[0];
       *y_value = (rx_buffer[3]<<8)|rx_buffer[2];
       *z_value = (rx_buffer[5]<<8)|rx_buffer[4];
        //return ret_code;
    }
    
    //this function will ensure the traitement of interruption in INT1_THS
    int accel_set_threshold(int threshold)
    { m_device_address = accel_addr;
        int max_threshold = 127* THS_2G  ;
        uint8_t ths = threshold/THS_2G;
        uint8_t accel_reg[2];
        printf( "hors threshold \n");
    	
      if (threshold > max_threshold) {
          printf( "Threshold out of range\n");
          return -1;
        }
    else
    {	
        accel_reg[0] = INT1_THS;
    
        accel_reg[1] = ths;
    
        accel_I2C_register_write(m_device_address,accel_reg, sizeof(accel_reg) );
      accel_I2C_register_read(m_device_address,INT1_THS, &ths ,sizeof(INT1_THS));
    
      printf ("Ahmed test");
       printf ("Threshold @ %x(%d)\n",ths, ths);
    
     	return 0;
    }
    }
    int main(void)	
    {
    	  uint16_t X,Y,Z;
        nrf_gpio_cfg_output(LED_1);
        nrf_gpio_pin_set(LED_1);
        uart_config();
        printf("Start");
    	  // nrf_drv_twi_enable(&twi_instance);  
        accel_I2C_datawrite(&twi_instance);
        twi_init();
        // m_device_address = accel_addr;
     
        uint8_t rx_buffer[6];
        rx_buffer[0] = 0x00;
    //    
        accel_xyz_read(&X,&Y,&Z);
            // printf("Groupeer accelero DATA:  X: %d  Y: %d  Z: %d  \n", X ,Y,Z);
                while(true)
            {
    		int threshold =100;
      accel_set_threshold(threshold);
    //            accel_xyz_read(&X,&Y,&Z);
    //         printf("Groupeer accelero DATA2:  X: %d  Y: %d  Z: %d  \n", X ,Y,Z);
    					nrf_delay_ms(100);
            }      
        
    }
    
  • Hi,

    1. One of the quickest ways to check if the TWI communication is working correctly is to read the WHO_AM_I register (address 0x0F). If the result is 0x33, then your TWI read function is working correctly.
    2. In your main function, you are calling a datawrite to the accelerometer before twi_init. You should call twi_init first and then the read/write operations.
    3. In Chapter 6 of the datasheet, for a read operation, the address byte MSB bit should be 1. How and where are you setting that? Similarly, for the write operation, the MSB should be 0. Once you have written the correct values (for the resolution, axes and ODR in the control registers), the accelerometer buffer will be filled with the correct acceleration values which you will be able to read

    EDIT:

    Try the following steps,

    1. Modify your twi_init function to this ..

      void twi_init (void) { ret_code_t err_code; // uint8_t reg[2] = {CTRL_REG1, 0x01}; const nrf_drv_twi_config_t twi_config = { .scl = DEVICE_SCL_PIN, .sda = DEVICE_SDA_PIN, .frequency = NRF_TWI_FREQ_400K, .interrupt_priority = APP_IRQ_PRIORITY_HIGH };

              err_code = nrf_drv_twi_init(&twi_instance, &twi_config, twi_handler, NULL);
              APP_ERROR_CHECK(err_code);
          
              nrf_drv_twi_enable(&twi_instance);
              // err_code = nrf_drv_twi_tx(&twi_instance, accel_addr, reg, sizeof(reg), false);
              //APP_ERROR_CHECK(err_code);
          }
      
    2. In

      main(){ . . . twi_init(); // Initialize the twi module first // Because only after initializing the twi module, you can use it . . }

    3. In your accel_I2C_register_read function, the reg_addr parameter is uint8_t which is 8 bits. The MSB of these 8 bits needs to be 1. So you can modify it to ...

      ret_code_t accel_I2C_register_read(uint8_t slave_addr, uint8_t reg_addr, uint8_t * pdata, uint32_t bytes) {
      ret_code_t ret_code;

      reg_addr = (uint8_t)(reg_addr|0x80);// This OR operation will make the MSB "1"
      
      ret_code = nrf_drv_twi_tx(p_twi_master,reg_addr, &reg_addr,1,false);
      
      if(ret_code != NRF_SUCCESS)
      {
      
              return ret_code;
      }
      
      ret_code = nrf_drv_twi_rx(p_twi_master,slave_addr, pdata, bytes);
      
      return ret_code;
      

      }

    4. In your function accel_xyz_read, the rx_buffer array is a local variable defined inside the function. Once you exit the function, the values held in this array are lost. Make this array a global variable. This will retain the values for other functions to access.

Related