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);
        }      
    
}
`
Parents
  • 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.

Reply
  • 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.

Children
  • Hello, you are right, I have a mistake in the function read.I tested it

      X = accel_I2C_register_read(m_device_address,access_data,( uint8_t *) WHO , sizeof(WHO));
    

    printf(" result is %x ,%d ",WHO, X);

    I find 17 instead of 33 107/5000 So I have not properly configure reading and writing, I will change the ones you recommended

  • Hello ,Here are the functions I used to read and write For the read I sent a '1' to allow read

    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; //to configured the I2C read 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;
    

    } 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;
    

    }

    Is what i have is correct?

    Thanks,

  • Hi Amed, I have edited my answer

  • I thank you greatly for help, just when I changed the variable "uint8_t rx_buffer [6];" In variable globle the program accel read axes does not work

  • Hello, For the function accel_set threshold it does not work (it is the function that is responsible for the detection of interrupts: if there is a movement or not)

    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 (" test"); printf ("Threshold @ %x(%d)\n",ths, ths);

    return 0;
    

    } Thanks

Related