Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement the APIs "Set_X_ODR_With_Mode" and "Set_G_ODR_With_Mode" #12

Open
MuthukumarEC opened this issue Nov 10, 2020 · 5 comments
Open
Assignees

Comments

@MuthukumarEC
Copy link

MuthukumarEC commented Nov 10, 2020

Hello, all how to put sleep and wakeup in every 10 seconds. in this DISCO_IOT_MultiEvent example code, I made some changes as below but my device still takes 160uA current. how to implement sleep and wakeup for measurement of my LSM6DSL gyro low power mode. I added my code below. kindly help me to solve this problem

// Includes.
#include <LSM6DSLSensor.h>

#define SerialPort Serial
#define I2C2_SCL    PB10
#define I2C2_SDA    PB11
#define INT1        PD11

// Components.
LSM6DSLSensor *AccGyr;

//Interrupts.
volatile int mems_event = 0;

uint16_t step_count = 0;
char report[256];

void INT1Event_cb();
void sendOrientation();
TwoWire *dev_i2c;

void setup() {
  // Initialize serial for output.
  SerialPort.begin(9600);

  // Initialize I2C bus.
  dev_i2c = new TwoWire(I2C2_SDA, I2C2_SCL);
  dev_i2c->begin();

  //Interrupts.
  attachInterrupt(INT1, INT1Event_cb, RISING);

  // Initlialize Components.
  AccGyr = new LSM6DSLSensor(dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW);
  AccGyr->Enable_X();

  // Enable all HW events.
  AccGyr->Enable_Pedometer();
  AccGyr->Enable_Tilt_Detection();
  AccGyr->Enable_Free_Fall_Detection();
  AccGyr->Enable_Single_Tap_Detection();
  AccGyr->Enable_Double_Tap_Detection();
  AccGyr->Enable_6D_Orientation();

LSM6DSL_ACC_GYRO_W_SleepMode_G(Handeler,LSM6DSL_ACC_GYRO_SLEEP_G_ENABLED);
LSM6DSL_ACC_GYRO_W_SLEEP_DUR(Handeler, 0x0A) ;

}

void loop() {
  if (mems_event)
  {
    mems_event = 0;
    LSM6DSL_Event_Status_t status;
    AccGyr->Get_Event_Status(&status);

    if (status.StepStatus)
    {
      // New step detected, so print the step counter
      AccGyr->Get_Step_Counter(&step_count);
      snprintf(report, sizeof(report), "Step counter: %d", step_count);
      SerialPort.println(report);
    }

    if (status.FreeFallStatus)
    {
      // Output data.
      SerialPort.println("Free Fall Detected!");
    }

    if (status.TapStatus)
    {
      // Output data.
      SerialPort.println("Single Tap Detected!");
    }

    if (status.DoubleTapStatus)
    {
      // Output data.
      SerialPort.println("Double Tap Detected!");
    }

    if (status.TiltStatus)
    {
      // Output data.
      SerialPort.println("Tilt Detected!");
    }

    if (status.D6DOrientationStatus)
    {
      // Send 6D Orientation
	    sendOrientation();
    }
  }
}

void INT1Event_cb()
{
  mems_event = 1;
}

void sendOrientation()
{
  uint8_t xl = 0;
  uint8_t xh = 0;
  uint8_t yl = 0;
  uint8_t yh = 0;
  uint8_t zl = 0;
  uint8_t zh = 0;

  AccGyr->Get_6D_Orientation_XL(&xl);
  AccGyr->Get_6D_Orientation_XH(&xh);
  AccGyr->Get_6D_Orientation_YL(&yl);
  AccGyr->Get_6D_Orientation_YH(&yh);
  AccGyr->Get_6D_Orientation_ZL(&zl);
  AccGyr->Get_6D_Orientation_ZH(&zh);

  if ( xl == 0 && yl == 0 && zl == 0 && xh == 0 && yh == 1 && zh == 0 )
  {
    sprintf( report, "\r\n  ________________  " \
                      "\r\n |                | " \
                      "\r\n |  *             | " \
                      "\r\n |                | " \
                      "\r\n |                | " \
                      "\r\n |                | " \
                      "\r\n |                | " \
                      "\r\n |________________| \r\n" );
  }

  else if ( xl == 1 && yl == 0 && zl == 0 && xh == 0 && yh == 0 && zh == 0 )
  {
    sprintf( report, "\r\n  ________________  " \
                      "\r\n |                | " \
                      "\r\n |             *  | " \
                      "\r\n |                | " \
                      "\r\n |                | " \
                      "\r\n |                | " \
                      "\r\n |                | " \
                      "\r\n |________________| \r\n" );
  }

  else if ( xl == 0 && yl == 0 && zl == 0 && xh == 1 && yh == 0 && zh == 0 )
  {
    sprintf( report, "\r\n  ________________  " \
                      "\r\n |                | " \
                      "\r\n |                | " \
                      "\r\n |                | " \
                      "\r\n |                | " \
                      "\r\n |                | " \
                      "\r\n |  *             | " \
                      "\r\n |________________| \r\n" );
  }

  else if ( xl == 0 && yl == 1 && zl == 0 && xh == 0 && yh == 0 && zh == 0 )
  {
    sprintf( report, "\r\n  ________________  " \
                      "\r\n |                | " \
                      "\r\n |                | " \
                      "\r\n |                | " \
                      "\r\n |                | " \
                      "\r\n |                | " \
                      "\r\n |             *  | " \
                      "\r\n |________________| \r\n" );
  }

  else if ( xl == 0 && yl == 0 && zl == 0 && xh == 0 && yh == 0 && zh == 1 )
  {
    sprintf( report, "\r\n  __*_____________  " \
                      "\r\n |________________| \r\n" );
  }

  else if ( xl == 0 && yl == 0 && zl == 1 && xh == 0 && yh == 0 && zh == 0 )
  {
    sprintf( report, "\r\n  ________________  " \
                      "\r\n |________________| " \
                      "\r\n    *               \r\n" );
  }

  else
  {
    sprintf( report, "None of the 6D orientation axes is set in LSM6DSL - accelerometer.\r\n" );
  }

  SerialPort.print(report);
}
@cparata
Copy link
Collaborator

cparata commented Nov 12, 2020

Hi @MuthukumarEC ,
it is not clear to me what you want to do. The LSM6DSL driver was done in order to call only the APIs that you can find in the LSM6DSLSensor class. Instead, you called some low level APIs that I do not suggest to call if you don't know very well the Datasheet of the component. Unfortunately, the LSM6DSLSensor class does not support the low power mode yet. I implemented it only for LSM6DSO, LSM6DSOX and LSM6DSR. Basically, what you can currently do with the driver is disable the component and in this way it should consume less. But, when the component is disable, obviously it cannot get gyroscope and accelerometer data. The wake up functionality, implemented in the driver, consist of the generation of an interrupt by the accelerometer when you move the board. So, maybe it is not what you need for your use case.
Best Regards,
Carlo

@MuthukumarEC
Copy link
Author

Hi @cparata
Thanks for your reply. I need to get gyroscope raw data every five seconds in low power mode(30uA). but my code takes 250uA constantly. I'm using DISCO_IOT_LSM6DSL_DataLog_Terminal.ino example I manually set 26HZ in Set_G_ODR_When_Enabled but LSM6DSL take 250uA constantly. How I solve this problem. how I will get Gyroscope Raw in Low power consumption. Please suggest any example and step to active low power mode in Gyroscope.

@cparata
Copy link
Collaborator

cparata commented Nov 18, 2020

Hi @MuthukumarEC ,
unfortunately, in the current version of the LSM6DSL driver only high performance mode is supported. In order to implement the low power mode for gyroscope (and also for accelerometer), we need to implement the APIs "Set_X_ODR_With_Mode" and "Set_G_ODR_With_Mode" as I already did for LSM6DSO, LSM6DSOX and LSM6DSR. In order to do that, you need to follow the specifications of LSM6DSL that you can find in the datasheet of the component (https://www.st.com/resource/en/datasheet/lsm6dsl.pdf).
Meantime, if you need only the gyroscope data, you can disable at all the accelerometer using the API "Disable_X". In this way, you should decrease the consumption. I do not have band at the moment to add the low power mode for LSM6DSL. I could schedule this enhancement for the next months.
Best Regards,
Carlo

@MuthukumarEC
Copy link
Author

MuthukumarEC commented Nov 20, 2020

Hi @cparata,
Thanks for your support. Here, I'm Testing DISCO_IOT_LSM6DSL_DataLog_Terminal.ino code in LSM6DSL Gyroscope Measurement. The Raw data of Gyroscope XYZ(Gx,Gy,Gz) is changing every time while placing a fixed position. I try to change ODR in both X and G up to 6660HZ but that measurement of the Gyroscope still I am facing the same issue. I added my raw data as below Please give some suggestion to solve this issue on my code.

    Ax      Ay  Az               Gx        Gy      Gz

ACC: 1009 -50 42 GRO: -1330 -2940 -490
ACC: 1006 -48 48 GRO: -1400 -3290 -350
ACC: 1005 -49 42 GRO: -1260 -3290 -420
ACC: 1012 -54 33 GRO: -1400 -2660 -350
ACC: 1008 -47 36 GRO: -1330 -3080 -420
ACC: 1008 -51 47 GRO: -1540 -2660 -490
ACC: 1006 -50 50 GRO: -910 -2520 -490
ACC: 1007 -48 49 GRO: -1190 -1540 -700
ACC: 1005 -49 49 GRO: -1330 -3080 -280
ACC: 1005 -51 58 GRO: -1190 -2660 -630
ACC: 1000 -50 57 GRO: -1400 -3150 -420
ACC: 1006 -52 43 GRO: -840 -3010 -280
ACC: 1008 -50 35 GRO: -1190 -2240 -560
ACC: 1004 -50 62 GRO: -1190 -3500 -350
ACC: 1010 -52 30 GRO: -1260 -2380 -630
ACC: 1011 -50 28 GRO: -1680 -2940 -560
ACC: 1011 -68 28 GRO: -3360 -3920 -560
ACC: 1004 -52 53 GRO: -1260 -3430 -490
ACC: 1011 -50 30 GRO: -980 -2730 -350
ACC: 1007 -55 36 GRO: -1050 -3150 -420
ACC: 1006 -49 56 GRO: -980 -3640 -350
ACC: 1011 -53 31 GRO: -1190 -3080 -490
ACC: 1006 -50 42 GRO: -1260 -3010 -280
ACC: 1008 -55 33 GRO: -1050 -3920 -210
ACC: 1007 -53 37 GRO: -1050 -3010 -490
ACC: 1007 -53 42 GRO: -770 -2870 -420
ACC: 991 -43 92 GRO: -350 -7700 210
ACC: 1004 -52 38 GRO: -700 -6370 140
ACC: 1007 -52 25 GRO: -1050 -3220 -420
ACC: 1002 -56 40 GRO: -840 -3010 -490
ACC: 1007 -50 44 GRO: -1050 -3080 -490

@cparata
Copy link
Collaborator

cparata commented Nov 20, 2020

Hi @MuthukumarEC ,
it is normal. None device is perfect in the real world. You always would have some small variations from the ideal measurements, due to electrical noise, etc. In fact, in the datasheet of the LSM6DSL you can find the zero-level specs that says how the measurements can vary when the device is still. For the gyroscope of the LSM6DSL, it should be +/-3dps that, considering that your measurements are expressed in mdps, is more or less in your range; for the accelerometer of the LSM6DSL, it should be +/-40mg and also in this case you are more or less in your range.
I suggest to give a look at this article that explains how a real device works: "https://learn.adafruit.com/comparing-gyroscope-datasheets"
Best Regards,
Carlo

@fpistm fpistm changed the title Sleep and wakeup doen't work LSM6DSL implement the APIs "Set_X_ODR_With_Mode" and "Set_G_ODR_With_Mode" Jan 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants