博世加速度計BMA400的自動喚醒和自動低功耗介紹

自動喚醒和自動低功耗的概念


自動喚醒


如圖所示,喚醒功能可以通過檢測定義的運動來生成中斷,而自動喚醒功能可以將BMA400從低功耗模式切換到正常模式。在切換到正常模式期間,之前在正常模式下定義的傳感器配置(在進入低功耗模式之前),如ODR(輸出數據率)、量程、OSR(過採樣率)、FIFO(先進先出隊列)、中斷將自動恢復。因此,主機只需要在初始化時配置一次BMA400,BMA400通過自動喚醒功能進入正常模式後無需重新配置參數。

從低功耗模式喚醒的三種可能觸發條件是:

  • 通過串行命令
  • 通過超時
  • 通過活動喚醒中斷

這三種條件可以並行啟用。

請注意,如果配置了超時喚醒,則只能將BMA400切換到正常模式,並且不能映射到中斷引腳(INT1和INT2)。

自動低功耗

除了串行命令外,還有三種可能的觸發條件可以自動將BMA400切換到低功耗模式:

  • 通過超時
  • 通過Gen1上的活動(Gen1中斷將觸發切換到低功耗模式)
  • 通過數據就緒(DRDY)

這三種條件可以並行啟用。

在超時模式下,計數器也可以通過Gen2中斷重置。這可以用來擴大BMA400在正常模式下的活動時間(如果在Gen2檢測到某些活動)。

相關寄存器


使用案例

在這一部分,我們提供了幾個典型的示例和示例代碼;您可以根據特定用途修改它們。

通過超時實現自動喚醒和自動低功耗

案例描述

在這個案例中,自動喚醒和自動低功耗功能都是通過超時觸發的。因此,在配置和啟用後,BMA400將按以下順序工作: 重複:             低功耗模式採樣(2.5ms ~ 10.24s)             通過超時自動切換到正常模式             正常模式採樣((2.5ms ~ 10.24s))             通過超時自動切換到低功耗模式

參數配置

在這個例子中,量程=2g,ODR=100Hz,加速度數據源=filter1

自動低功耗相關

寄存器(0x2A),寄存器(0x2B): auto_lp_timeout_thres = 400 (400 * 2.5ms = 1s), 無符號12位,超時閾值,2.5ms/lsb auto_lp_timeout: 設置為1(啟用),將超時作為自動低功耗條件的來源

對於mode auto_lp_timeout = 0x02,gen2中斷將重置超時計數器,這可以用來延遲自動低功耗,如果滿足某些條件,例如,在手錶/手環中,gen2可以配置為檢測身體運動,只有在未檢測到運動時,超時計數器才會繼續,並在定義的時間後,傳感器最終進入低功耗模式。

自動喚醒相關

wakeup_timeout_thres = 0x0FFF (最大值,0x0fff * 2.5ms = 10.24s) 寄存器(0x2C)和(0x2D),無符號12位,自動喚醒超時閾值,2.5ms/lsb wkup_timeout: 設置為1(啟用)

示例代碼

#### BMA400 Auto wakeup and Auto low power features
##### _Usage of auto wakeup and auto low power features in sensor_
``` c

/* Auto wake-up timeout testing setting */
int8_t bma400_timeout_autowakeup_auto_lp(struct bma400_dev *dev)
{
int8_t rslt = 0;
uint8_t power_mode;
uint16_t int_status;
struct bma400_device_setting dev_setting[2];

/* Selecting auto wakeup on timeout */
dev_setting[0].type = BMA400_AUTOWAKEUP_TIMEOUT;

/* Selecting auto low power mode*/
dev_setting[1].type = BMA400_AUTO_LOW_POWER;

/* Get the previously set settings */
rslt = bma400_get_device_setting(&dev_setting, 2, dev);
if (rslt == BMA400_OK) {
/* Enable auto wakeup on timeout feature */
dev_setting[0].conf.auto_wakeup.wakeup_timeout = BMA400_ENABLE;
/* Set the timeout value as maximum (10.24s) */
dev_setting[0].conf.auto_wakeup.timeout_thres = BMA400_AUTO_WAKEUP_TIMEOUT_MAX;

/* Set auto low power on timeout feature */
dev_setting[1].conf.auto_lp.auto_low_power_trigger = BMA400_AUTO_LP_TIMEOUT_EN;
/* Set the timeout value as 1s (400*2.5ms) */
dev_setting[1].conf.auto_lp.auto_lp_timeout_threshold = 400;

/* Set the configurations in sensor */
rslt = bma400_set_device_setting(&dev_setting, 2, dev);

/* The sensor toggles between Low-power mode and Normal mode for every 10.24s
* as configured by user which can be tested and verfied by reading the power mode
* and printing it continuously as follows
* while (1) {
* rslt = bma400_get_power_mode(&power_mode, dev);
* printf("\n POWER MODE : %d",power_mode);
* }
* The power mode toggling can be seen from the printed console output
*/
}

return rslt;
}

通過位置實現自動喚醒和自動低功耗

案例描述

在這個例子中,喚醒中斷被定義為檢測傳感器的非平坦位置。配置了一個閾值(94mg),因此如果傳感器傾斜超過閾值,喚醒中斷將被設置,並將BMA400切換到正常模式(自動喚醒功能)。

一旦進入正常模式,Gen1將不斷檢測傳感器位置,並檢查傳感器是否回到平坦範圍內,這個範圍應該小於94mg(這裡gen1閾值設置為40mg)。因此,一旦滿足gen1條件,BMA400將通過自動低功耗功能自動切換到低功耗模式。

參數配置

量程=4g,ODR=100,OSR=1

自動低功耗相關

寄存器(0x2B) AUTOLOWPOW_1.gen1_int = 1; 設置此位,Gen1的中斷將觸發從正常模式切換到低功耗模式

自動喚醒相關

寄存器(0x2D) AUTOWAKEUP_1 wkup_int = 1; 使用喚醒中斷自動喚醒

喚醒中斷相關

寄存器(0x2F) WKUP_INT_CONFIG0 wkup_x_en, wkup_y_en, wkup_z_en = 1; 啟用三個軸 num_of_samples = 3; 在低功耗模式下將監視4(=3+1)連續樣本 wkup_refu = 0; 手動更新,由主機配置

示例代碼

/* #### BMA400 Auto wakeup and Auto low power features

##### _Usage of auto wakeup and auto low power features in sensor_ */

/* Auto wake-up based on position testing setting */
int8_t bma400_position_autowakeup_auto_lp(struct bma400_dev *dev)
{
int8_t rslt = 0;
uint8_t power_mode;
uint16_t int_status;
struct bma400_device_setting dev_setting[2];
/* Interrupt configuration structure */
struct interrupt_enable int_en;

/* Selecting auto wakeup on wakeup interrupt event */
dev_setting[0].type = BMA400_AUTOWAKEUP_INT;

/* Selecting auto low power mode*/
dev_setting[1].type = BMA400_AUTO_LOW_POWER;

/* Get the previously set settings */
rslt = bma400_get_device_setting(&dev_setting, 2, dev);
if (rslt == BMA400_OK) {
dev_setting[0].conf.wakeup.wakeup_axes_en = BMA400_XYZ_AXIS_EN
dev_setting[0].conf.wakeup.wakeup_ref_update = BMA400_MANUAL_UPDATE
dev_setting[0].conf.wakeup.sample_count = BMA400_SAMPLE_COUNT_4
dev_setting[0].conf.wakeup.int_wkup_threshold = 3
dev_setting[0].conf.wakeup.int_wkup_ref_x = 0
dev_setting[0].conf.wakeup.int_wkup_ref_y = 0
dev_setting[0].conf.wakeup.int_wkup_ref_z = 32 /* (0, 0, 1g) */
dev_setting[0].conf.wakeup.int_map = BMA400_INT_CHANNEL_1

/* Enable auto low power on Gen1 trigger */
dev_setting[1].conf.auto_lp.auto_low_power_trigger = BMA400_AUTO_LP_GEN1_TRIGGER;

/* Set the configurations in sensor */
rslt = bma400_set_device_setting(&dev_setting, 2, dev);

if (rslt == BMA400_OK) {

/* Enable the Generic interrupts in the sensor */
int_en.int_sel = BMA400_AUTO_WAKEUP_EN;
int_en.conf = BMA400_ENABLE;

rslt = bma400_enable_interrupt(&int_en, 1, dev);

/* The sensor toggles between Low-power mode and Normal mode if tilt the device(sensor)
* or place it back to flat
* this can be verfied by reading the power mode and printing it continuously as follows
* while (1) {
* rslt = bma400_get_power_mode(&power_mode, dev);
* printf("\n POWER MODE : %d",power_mode);
* }
* The power mode toggling can be seen from the printed console output
*/
}

return rslt;
}


/*##### BMA400 Generic interrupt configuration
##### _Usage of Generic interrupt1 and 2 for activity/inactivity detection in sensor_ */

/* Generic Interrupt feature */
int8_t bma400_generic_interrupts_by_position(struct bma400_dev *dev)
{
int8_t rslt = 0;
/* Variable to store interrupt status */
uint16_t int_status;
/* Sensor configuration structure */
struct bma400_setting accel_settin[2];
/* Interrupt configuration structure */
struct interrupt_enable int_en[2];

/* Select the GEN1 and GEN2 interrupts for configuration */
accel_settin[0].type = BMA400_GEN1_INT;
accel_settin[1].type = BMA400_GEN2_INT;

/* Get the configurations set in the sensor */
rslt = bma400_get_sensor_setting(&accel_settin[0], 2, dev);

/* Modify the required parameters from the "gen_int" structure present
* inside the "bma400_setting" structure to configure the selected
* GEN1/GEN2 interrupts */

if (rslt == BMA400_OK) {
/* Set the GEN 1 interrupt for activity detection */
accel_settin[0].conf.gen_int.int_map = BMA400_INT_CHANNEL_2;
accel_settin[0].conf.gen_int.axes_sel = BMA400_XYZ_AXIS_EN;
accel_settin[0].conf.gen_int.criterion_sel = BMA400_INACTIVITY_INT;
accel_settin[0].conf.gen_int.evaluate_axes = BMA400_ALL_AXES_INT;
accel_settin[0].conf.gen_int.ref_update = BMA400_MANUAL_UPDATE;
accel_settin[0].conf.gen_int.data_src=BMA400_DATA_SRC_ACC_FILT2;
accel_settin[0].conf.gen_int.gen_int_thres = 0x05;
accel_settin[0].conf.gen_int.gen_int_dur = 100;
accel_settin[0].conf.gen_int.hysteresis = BMA400_HYST_0_MG;
accel_settin[0].conf.gen_int.int_thres_ref_x = 0;
accel_settin[0].conf.gen_int.int_thres_ref_y = 0;
accel_settin[0].conf.gen_int.int_thres_ref_z = 512; /* (0, 0, 1g) for gen1 reference. */

/* Set the GEN 2 interrupt for in-activity detection */
accel_settin[1].conf.gen_int.int_map = BMA400_INT_CHANNEL_2;
accel_settin[1].conf.gen_int.axes_sel = BMA400_XYZ_AXIS_EN;
accel_settin[1].conf.gen_int.criterion_sel = BMA400_INACTIVITY_INT;
accel_settin[1].conf.gen_int.evaluate_axes = BMA400_ANY_AXES_INT;
accel_settin[1].conf.gen_int.ref_update = BMA400_ONE_TIME_UPDATE;
accel_settin[1].conf.gen_int.data_src=BMA400_DATA_SRC_ACC_FILT1;
accel_settin[1].conf.gen_int.gen_int_thres = 0x10;
accel_settin[1].conf.gen_int.gen_int_dur = 0x01;
accel_settin[1].conf.gen_int.hysteresis = BMA400_HYST_0_MG;

/* Set the configurations in the sensor */
rslt = bma400_set_sensor_setting(&accel_settin[0], 2, dev);

if (rslt == BMA400_OK) {

/* Enable the Generic interrupts in the sensor */
int_en[0].int_sel = BMA400_GEN1_INT_EN;
int_en[0].conf = BMA400_ENABLE;

int_en[1].int_sel = BMA400_GEN2_INT_EN;
int_en[1].conf = BMA400_DISABLE;

rslt = bma400_enable_interrupt(&int_en[0], 2, dev);

}
}
}
}
return rslt;
}

★博文內容均由個人提供,與平台無關,如有違法或侵權,請與網站管理員聯繫。

★文明上網,請理性發言。內容一周內被舉報5次,發文人進小黑屋喔~

評論