cancel
Showing results for 
Search instead for 
Did you mean: 

IIS2DH axis Z not working

Maxime Benchemoul
Associate II

Hello everyone,

I have an issue with the IIS2DH accelerometer when I try to pool data from it.

My setup is:

STM32L442 connected to the IIS2DH using SPI interface and sending data through USART to Tera Term (using a FTDI cable).

First I have a small initialization process which sets up the chip following my needs:

400Hz, X Y and Z axis enabled, +-2G scale, high resolution, SPI 4 wires, BDU.

Then I read all the 6 control registers and the "who I am" register to check if everything is ok and I display the results on Tera Term. All works nicely, as expected.

However, when I pool data from output registers (OUT_X_L, OUT_X_H, ...) it works only for X and Y axis...

Once data from the several registers are stored, there is a small sequence which constructs the 16-bit signed integers from the high and low regisiters of each axis, then it shifts the 16 bits to the right to keep only the first 12 bits (HR mode) and finally I send the data through USART (using atoi() function to convert the data into strings).

But as I said, it works perfectly for the X and Y axis, but not for the Z axis. Instead of having something corresponding to -1g (or -1024 on a 12 bit scale), I read almost -2g (-2039).

Sometimes when I hit the sensor, the Z axis moves a little bit but it does not correspond to normal operating.

Has anyone ever encountered this type of problem?

Thank you for your help!

Maxime

2 REPLIES 2
Miroslav BATEK
ST Employee

Can you share your code?

Do you see 1g in X and Y axis if your align the axis with gravity?

Maxime Benchemoul
Associate II

Hi,

Yes I was seeing 1g on both X and Y axis when I was aligning the axis

with gravity.

I did some debugging job and now it works.

For a moment I thought it was a problem with the turn-on time of the

chip and the clock of the MCU.

I got it working at 2MHz but when I was trying to increase the frequency

up to 4 or 8MHz the Z-axis was starting to stop working properly.

Even with a small delay between the starting of the chip (I use an

analog switch on my board to monitor the voltage supply) and the initialization

process, I did not have any improvement.

Today, after a simple "refresh" of the project inside

TrueSTUDIO, my app started to work properly...

FYI my debug code (simplified, only the principal is shown):

#include "main.h"
#include "stm32l4xx_hal.h"
#include "IIS2DH_driver.h"
#include <string.h>
#include <stdlib.h>
 
#define ACC_OFF	HAL_GPIO_WritePin(SW_SENSOR_GPIO_Port, SW_SENSOR_Pin, GPIO_PIN_SET)
#define ACC_ON HAL_GPIO_WritePin(SW_SENSOR_GPIO_Port, SW_SENSOR_Pin, GPIO_PIN_RESET)
 
SPI_HandleTypeDef hspi1;
 
volatile uint8_t flag_bp = 0;
Type1_Axis16bit_t raw_data_acc;
ACC_HandleTypeDef hacc1;
ACC_Config_t cIIS2DH;
ACC_Status_t sIIS2DH;
float x, y, z;
 
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
 
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_SPI1_Init();
 
  ACC_OFF;
 
  while(flag_bp != 1);   // Wait for the user to press the push button
  flag_bp = 0;
  ACC_ON;   // Power up the accelerometer
  HAL_Delay(1);
  ACC_Init(&hspi1, &hacc1);   // Accelerometer init
  memset(raw_data_acc.u8bit, 0x00, 3*sizeof(int16_t));
 
  while (1)
  {
	  raw_data_acc.u8bit[0] = ACC_WriteRead(&hspi1, ACC_READ, ACC_OUT_X_L, 0x00);
	  raw_data_acc.u8bit[1] = ACC_WriteRead(&hspi1, ACC_READ, ACC_OUT_X_H, 0x00);
	  raw_data_acc.u8bit[2] = ACC_WriteRead(&hspi1, ACC_READ, ACC_OUT_Y_L, 0x00);
	  raw_data_acc.u8bit[3] = ACC_WriteRead(&hspi1, ACC_READ, ACC_OUT_Y_H, 0x00);
	  raw_data_acc.u8bit[4] = ACC_WriteRead(&hspi1, ACC_READ, ACC_OUT_Z_L, 0x00);
	  raw_data_acc.u8bit[5] = ACC_WriteRead(&hspi1, ACC_READ, ACC_OUT_Z_H, 0x00);
	  x = ACC_digit_to_g(&hacc1, raw_data_acc.i16bit[0]);
	  y = ACC_digit_to_g(&hacc1, raw_data_acc.i16bit[1]);
	  z = ACC_digit_to_g(&hacc1, raw_data_acc.i16bit[2]);
  }
}
 
 
void EXTI9_5_IRQHandler(void)
{
	  if(__HAL_GPIO_EXTI_GET_FLAG(GPIO_PIN_5)){
		  flag_bp = 1;
	  }
          HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);
}
 
uint8_t ACC_WriteRead(void *handle_spi, uint8_t rw, uint8_t addr, uint8_t data_reg){
	uint8_t buff_tx[2];
	uint8_t buff_rx[2];
	buff_tx[0] = rw | addr;
	buff_tx[1] = data_reg;
	HAL_GPIO_WritePin(SPI1_CS2_GPIO_Port, SPI1_CS2_Pin, GPIO_PIN_RESET);
	HAL_SPI_TransmitReceive(handle_spi, buff_tx, buff_rx, 2, 100);
	HAL_GPIO_WritePin(SPI1_CS2_GPIO_Port, SPI1_CS2_Pin, GPIO_PIN_SET);
	return buff_rx[1];
}
 
void ACC_Init(void *handle_spi, ACC_HandleTypeDef *hacc){
	uint8_t reg;
 
	// Reboot the device //
	reg = ACC_CTRL_REG5_BOOT;
	ACC_WriteRead(handle_spi, ACC_WRITE, ACC_CTRL_REG5, reg);
 
	// Set ODR to 400Hz and enable XYZ axis //
	reg = (ACC_CTRL_REG1_ODR400 << ACC_CTRL_REG1_ODR_SHIFT)
		  | ACC_CTRL_REG1_Z_EN
		  | ACC_CTRL_REG1_Y_EN
		  | ACC_CTRL_REG1_X_EN;
	ACC_WriteRead(handle_spi, ACC_WRITE, ACC_CTRL_REG1, reg);
 
	HAL_Delay(2); 
 
	// Set +/-2G scale, high resolution, 4-wires SPI and enable BDU //
	reg = (ACC_CTRL_REG4_FS_2G << ACC_CTRL_REG4_FS_SHIFT)
		  | ACC_CTRL_REG4_HR
		  | ACC_CTRL_REG4_SIM_4W
		  | ACC_CTRL_REG4_BDU;
	ACC_WriteRead(handle_spi, ACC_WRITE, ACC_CTRL_REG4, reg);
 
	HAL_Delay(1);
 
	// Set the configuration of the sensor //
	hacc->Configuration.resolution = RESOLUTION_12BIT;
	hacc->Configuration.scale = SCALE_2G;
        hacc->Configuration.sensitivity = 0.9765625;
}
 
float ACC_digit_to_g(ACC_HandleTypeDef *hacc, int16_t digit_value){
	float conv_value;
	conv_value = (digit_value >> (16-hacc->Configuration.resolution))*hacc->Configuration.sensitivity/1000.0;
	return conv_value;
}

Maxime