cancel
Showing results for 
Search instead for 
Did you mean: 

Flexible Tilt angle measurement/interrupt in LIS2DW12

Vsv.1
Associate II

Hi ,

. I uses LIS2DW12. I have seen that 6D orientation angle is from 45 or 50 degrees only. So setting an interrupt for this wont be useful for my purpose.

I would like to wake up on minimum angle that I sets, say 5degree/10 degree . How could I achieve It. Is there any pseudo code available for that Like one is for 6D orientation (DT0097)?. When checked the STmem driver, I have seen that WAKE_UP_THS(34h) API is available for setting threshold values.

How I can get interrupt for a the tilt value I set (say 10 degree) for only one axis by setting threshold in this register. Also how to calculate to and from mg to degree(getting from raw value and setting to threshold)?.

Awaiting for the earliest response.

regards,

SV

14 REPLIES 14
Eleon BORLINI
ST Employee

Hi @Vsv.1​ ,

I believe you could achieve your goal by using the wake-up embedded digital feature. A wake-up interrupt generated while the device is running always in normal mode. This feature is described in application note AN5038 p.21.

You can define a threshold calculating the component of the "g" acceleration on one of the 3 spatial direction (see the AN4509 for a detailed calculation of this value, you can find some examples on page 6) and select the axis on which you want to detect the interrupt event.

You can refer to this C code: lis2dw12_wake_up.c

You should maybe disable this function if you are interested in quasi-static variation:

 /* Apply high-pass digital filter on Wake-Up function */
  lis2dw12_filter_path_set(&dev_ctx, LIS2DW12_HIGH_PASS_ON_OUT);

Please let me know if this solution is feasible for you.

-Eleon

Vsv.1
Associate II

Hi @Eleon BORLINI​ 

Thanks for all the Input.

I went through the document and tried something. I am getting interrupts every time even in stationary(When I set feed and random offset value for all three axis, without that what I am getting is TAP interrupt only). Turning off interrupt for an axis also I haven't seen, other than for Tap(which is very much required).

Can you give more light on weight setting , offset setting for each axis. Is that offset unit is 'mg' or it is angle, the maximum value of THS is 6 bits, so how it will be related to a large angle value.

I have seen a conversion fs2tomg (multiplying with .016, may i know how arrived in this calculation), is there a calculation for raw to angle in the same way.

All I expect is if I gives an offset 10, if any of the axis is tilted to more than 10degree from its current baseline, it should generate an interrupt.

Regards,

SV

Hi @Vsv.1​ ,

Let's see if I can help you.

>> Can you give more light on weight setting , offset setting for each axis. Is that offset unit is 'mg' or it is angle, the maximum value of THS is 6 bits, so how it will be related to a large angle value.

the AN4509 reports some of the thresholds related to the tilt degrees. Suppose you have your device with the z axis measuring 1g (flat position), the x and y axis will measure 0 LSB = 0 mg. If you set the threshold at 15° and enable X_WU and Y_WU (not the Z_WU), because the Z_WU would always generate an input when in flat position (Z = 1 g).

0693W000004Jcc7QAC.pngFor the threshold calculation, please consider what reported in the datasheet p.48: Wakeup threshold, 6-bit unsigned 1 LSB = 1/64 of FS. Default value: 000000.

>> I have seen a conversion fs2tomg (multiplying with .016, may i know how arrived in this calculation), is there a calculation for raw to angle in the same way.

The conversion formula for the data output is the following one, and comes from the fact that the sensitivity is 0.244 mg/LSB and the output data is on 14-bit (i.e., you have to divide by 4 to get the 16-bit LSB). You can find in the datasheet p.6:

float_t lis2dw12_from_fs2_to_mg(int16_t lsb)
{
  return ((float_t)lsb) * 0.061f;
}

-Eleon

@Eleon BORLINI​ . Thanks for the reply Eleon. I went busy in another loop and couldn't get some time later to spend on Mems. I shall come up with my doubts/result/findings on this this week.

Ok @Vsv.1​ , take your time 😉

-Eleon

Hi @Eleon BORLINI​ . I was waiting to get my hardware which took for a rework and I have checked the scenarios.

The accelerometer read and calculating angle seems almost correct by the way you suggested for each axis, from 0 to but a maximum 85-86 degrees.

here is I calculated this,

if(!lis2dw12_acceleration_raw_get(&dev_ctx, data_raw_acceleration.u8bit))

{

acceleration_mg[0] = lis2dw12_from_fs2_to_mg(data_raw_acceleration.i16bit[0]);

*psXValue = asin((double_t)(acceleration_mg[0])/GRAVITYFACTOR)*RADIAN2DEG; //GRAVITYFACTOR =1000(mg to g) and RADIAN2DEG(180*3.14) }

>>the AN4509 reports some of the thresholds related to the tilt degrees. Suppose you have your device with the z axis measuring 1g (flat position), the x and y axis will measure 0 LSB = 0 mg. If you set the threshold at 15° and enable X_WU and Y_WU (not the Z_WU), because the Z_WU would always generate an input when in flat position (Z = 1 g).

For setting wakeup for tilt angles is not worked , I referred

https://www.st.com/resource/en/application_note/dm00401877-lis2dw12-alwayson-3d-accelerometer-stmicroelectronics.pdf. page no.22.

0693W0000059ja7QAA.png 

But What I have seen is the interrupt is generated for TAP events not tilt. The code I pasted below

dev_ctx.write_reg = platform_write;

dev_ctx.read_reg = platform_read;

dev_ctx.handle = &hi2c1;

lis2dw12_device_id_get(&dev_ctx, &whoamI);

if (whoamI != LIS2DW12_ID)

{

 return error;

}

lis2dw12_reset_set(&dev_ctx, PROPERTY_ENABLE);

do {

lis2dw12_reset_get(&dev_ctx, &rst);

} while (rst);

lis2dw12_full_scale_set(&dev_ctx, LIS2DW12_2g);

lis2dw12_filter_path_set(&dev_ctx, LIS2DW12_USER_OFFSET_ON_OUT);

lis2dw12_power_mode_set(&dev_ctx, LIS2DW12_CONT_LOW_PWR_LOW_NOISE_12bit);

lis2dw12_wkup_dur_set(&dev_ctx, 0);

lis2dw12_offset_weight_set(&dev_ctx,1);

lis2dw12_wkup_threshold_set(&dev_ctx,2);

lis2dw12_usr_offset_x_set(&dev_ctx,0);

lis2dw12_usr_offset_y_set(&dev_ctx,0);

lis2dw12_usr_offset_z_set(&dev_ctx,1);

lis2dw12_pin_int1_route_get(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl);

int_route.ctrl4_int1_pad_ctrl.int1_wu = PROPERTY_ENABLE;

lis2dw12_pin_int1_route_set(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl);

lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_ODR_200Hz);

Note: I tried adding wakeup feed data set "lis2dw12_wkup_feed_data_set(&dev_ctx, 1)", but then TAP interrupt also stopped.

>> If you set the threshold at 15° and enable X_WU and Y_WU (not the Z_WU), because the Z_WU would always generate an input when in flat position (Z = 1 g).

Is it possible to enable/disable an axis from interrupt for wake up?. I have seen options enable/disable axis for tap interrupt only. Rather I think we might need to set offset only for the required axes, please correct me.

Regards,

Visakh SV

Hi @Eleon BORLINI , please check my statements observed from the result from the above post. Correct me if I'm wrong

  1. A tilt interrupt is cannot be generated for the LIS2DW12, other than in 6D orientation interrupt.
  2. The only way towards this is , 1. Getting interrupt for a TAP 2. Checking for which axis it has occurred from SRC register 3. Calculate the difference of angle to know tilt.

Regards,

VSV

Hi @Vsv.1​ ,

the problem with the tap interrupt is that you have to specify the duration of the tap signal to be detected, but if you are able to tune it, it is ok to use the tap function.

Alternatively, you could use the 6D interrupt tuning the threshold and the axis you want to detect the upward or downward crossing of that level. When the interrupt raises, you read the dataout of the "activated" axis that in that moment and you'll get the tilt angle.

-Eleon

Hi @Eleon BORLINI​ 

YEs. but the problem is for 6D we need to cross the particular level. That is not helpful for small angle tilt detection.

If the wake-up threshold interrupt can work for offset values set in x,y,z, that is what exactly I required(but not with TAP interrupt, as in my case device may get very slow tilt). Do you know Why I it is not getting interrupt for threshold and offset setting as I described in the post above

-------------------------------------------------------------------------------------

lis2dw12_filter_path_set(&dev_ctx, LIS2DW12_USER_OFFSET_ON_OUT);

lis2dw12_power_mode_set(&dev_ctx, LIS2DW12_CONT_LOW_PWR_LOW_NOISE_12bit);

lis2dw12_wkup_dur_set(&dev_ctx, 0);

lis2dw12_offset_weight_set(&dev_ctx,1);

lis2dw12_wkup_threshold_set(&dev_ctx,2);

lis2dw12_usr_offset_x_set(&dev_ctx,0);

lis2dw12_usr_offset_y_set(&dev_ctx,0);

lis2dw12_usr_offset_z_set(&dev_ctx,1);

lis2dw12_pin_int1_route_get(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl);

int_route.ctrl4_int1_pad_ctrl.int1_wu = PROPERTY_ENABLE;

lis2dw12_pin_int1_route_set(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl);

lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_ODR_200Hz);

Note: I tried adding wakeup feed data set "lis2dw12_wkup_feed_data_set(&dev_ctx, 1)", but then TAP interrupt also stopped.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Regards,

VSV