IMU Shield interrupt


#1

Hi,

I have a particle electron connected to imu sheild lsm9ds1.
I am using interrupt 1 from imu
The problem is int 1 is always high.

Pls help
Code used:

 

SYSTEM_MODE(SEMI_AUTOMATIC);

#include <SparkFunLSM9DS1.h>
#include <stdarg.h>
// #include "PublishQueue.h"
#include "math.h"

typedef struct vec3 {
  float x,y,z;
} vec3;

//
//
//
//  macros
//------------------------------------------------------------------------------

#define logi(msg) Serial.print("INFO:  "), Serial.println(msg)
#define loge(msg) Serial.print("ERROR: "), Serial.println(msg)

#define s_to_ms(x)             (x*1000)
#define ellapsed_time_since(x) (millis() - (x))

// SDO_XM and SDO_G are both pulled high, so our addresses are:
#define LSM9DS1_M   0x1E // Would be 0x1C if SDO_M is LOW
#define LSM9DS1_AG  0x6B // Would be 0x6A if SDO_AG is LOW




//
//
//
//  constants
//------------------------------------------------------------------------------

// After connecting, always wait 1 minute before disconnecting again
const uint32_t  TIME_BEFORE_DISCONNECT   = s_to_ms(60);

// When sending events, only send one every 10 minutes
const uint32_t TIME_BETWEEN_EVENTS       = s_to_ms(10);

// At 10am, report battery life and stay on for 10 minutes
const uint32_t DAILY_BATTERY_REPORT_HOUR = 10;

// How much deviation is considered 'activity'
const float ACCEL_ANOMOLY_THRESHOLD   = 0.0001f;

const uint32_t SLEEP_INTERVAL = 1;  // seconds

//
// event names

static const char *batteryEventName = "read-battery";
static const char* anomolyEventName = "test-activity-detected";
static const char* activityListEventName = "test-activity-detected";

//
// status leds

LEDStatus blinkRed(RGB_COLOR_RED, LED_PATTERN_BLINK);
LEDStatus blinkMagenta(RGB_COLOR_MAGENTA, LED_PATTERN_BLINK);
LEDStatus blinkGreen(RGB_COLOR_GREEN, LED_PATTERN_BLINK);
LEDStatus blinkYellow(RGB_COLOR_YELLOW, LED_PATTERN_BLINK);

//
//
//
//  globals
//------------------------------------------------------------------------------


static bool cellular_connected  = false;
static uint32_t  cellular_activated  = 0;
static uint32_t  last_message_sent   = 0;
static vec3 baseline_accel      = {0};

static FuelGauge batteryMonitor;
static LSM9DS1 imu;

//static PublishQueue pubQueue(1000);



//
//
//
//  funcs
//------------------------------------------------------------------------------


#if 0 // DEPRECATED CODE

float magnitude(float x, float y, float z) {
   return sqrt(x * x + y * y + z * z);
}

void update_baseline(float x, float y, float z) {
  baseline_accel.x = baseline_accel.x * 0.99f + x * 0.01f;
  baseline_accel.y = baseline_accel.y * 0.99f + y * 0.01f;
  baseline_accel.z = baseline_accel.z * 0.99f + z * 0.01f;
}


bool detect_anomoly(float x, float y, float z) {
  return ( abs(baseline_accel.x - x) > ACCEL_ANOMOLY_THRESHOLD ) ||
         ( abs(baseline_accel.y - y) > ACCEL_ANOMOLY_THRESHOLD ) ||
         ( abs(baseline_accel.z - z) > ACCEL_ANOMOLY_THRESHOLD );
}

bool detect_anom(float x, float y, float z) {

  float magnitude = sqrt(x * x + y * y + z * z);

  return magnitude > 1.1f || magnitude < 0.9f;
}

#endif

#define LSM9DS1_M_CS	A0 // Can be any pin
#define LSM9DS1_AG_CS	A1  // Can be any other pin


void connect_to_particle() {

  logi("connecting to particle");

  if( !Particle.connected() ) {

    Particle.connect();
    Particle.process();

  }

  logi("done");
}

void disconnect_from_particle() {

  logi("disconnecting from particle");

  if( Particle.connected() ) {

    Particle.disconnect();
    Particle.process();

  }

  logi("done");
}

void connect_cellular() {

  logi("enabling cellular");

  if( !Cellular.ready() ) {

    Cellular.on();
    Cellular.connect();

    while (Cellular.connecting() && !Cellular.ready()) {
      logi(".");
      delay(s_to_ms(1));
    }
  }

  logi("done");

}

void disconnect_cellular() {

  logi("disabling cellular");

  Cellular.off();

  while (Cellular.ready()) {
    logi(".");
    delay(s_to_ms(1));
  }

  logi("done");
}

void connect_to_cloud() {

  connect_cellular();
  delay(500);
  connect_to_particle();
  delay(500);

  cellular_connected = true;
  cellular_activated = millis();
}

void disconnect_from_cloud() {

  disconnect_from_particle();
  delay(500);
  disconnect_cellular();
  delay(500);

  cellular_connected = false;
}

#if 0 // DEPRECATED CODE

void report_battery_daily() {

  static uint32_t hour      = 0;
  static bool run_once = false;

  //
  // run once at the turn of the hour

  if( hour == DAILY_BATTERY_REPORT_HOUR && !run_once ) {
    connect_to_cloud();

    Particle.publish(batteryEventName,
        String::format("%.02f,%.02f",
          batteryMonitor.getVCell(),
          batteryMonitor.getSoC()));

    run_once = true;

    disconnect_from_cloud();

  } else if( hour != DAILY_BATTERY_REPORT_HOUR && run_once ) {
    run_once = false;
  }

}

#endif

//
//
//
//  setup
//------------------------------------------------------------------------------

void start_accelerometer() {

  // Configure the IMU
  imu.settings.device.commInterface = IMU_MODE_I2C;
  imu.settings.device.agAddress = LSM9DS1_AG ;
  imu.settings.device.mAddress = LSM9DS1_M;

  imu.settings.gyro.latchInterrupt = false;
  imu.settings.gyro.sampleRate = 0;
  imu.settings.gyro.enabled = false;
  imu.settings.accel.scale = 2;
  imu.settings.mag.enabled = false;
  imu.settings.mag.sampleRate = 0;

  if(!imu.begin()) {

    blinkRed.setActive(true);
    delay(5000);
    blinkRed.setActive(false);
  }

  imu.calibrate(true);


  imu.sleepGyro(true);


  imu.configAccelInt(ZHIE_XL | ZLIE_XL | YHIE_XL | YLIE_XL | XHIE_XL | XLIE_XL);


  imu.configAccelThs(40, X_AXIS, 120, 0);
  imu.configAccelThs(40, Y_AXIS, 120, 0);
  imu.configAccelThs(40, Z_AXIS, 120, 0);



  imu.configInt(XG_INT1, INT1_IG_XL , INT_ACTIVE_HIGH, INT_PUSH_PULL);


}


void setup() {

  Serial.begin(115200);
  start_accelerometer();

}



#define RB_SIZE 500

typedef struct {

  uint16_t event_count;
  uint32_t events[RB_SIZE];

  uint32_t last_upload;

} hm_ring_buffer;

void rb_load(hm_ring_buffer* buffer) {

    EEPROM.get(0, *buffer);

}

void rb_store(hm_ring_buffer* buffer) {

    EEPROM.put(0, *buffer);

}

void rb_add_event(hm_ring_buffer* buffer, uint32_t timestamp) {

    if( buffer->event_count < RB_SIZE )
      buffer->events[buffer->event_count++] = timestamp;
}

bool rb_is_full(hm_ring_buffer* buffer) {

  return buffer->event_count == RB_SIZE;

}

void rb_reset(hm_ring_buffer* buffer) {
  memset(buffer, 0, sizeof(hm_ring_buffer));
}

bool rb_upload(hm_ring_buffer* buffer) {

  bool success = true;

  for(int i = 0; i < buffer->event_count; ++i) {

    if(!Particle.publish(activityListEventName, String::format("time: %d, bat: %.02f", buffer->events[i], batteryMonitor.getSoC()))) {
      success = false;
    }

    delay(75);
  }

  return success;
}


//
//
//
//  main loop
//------------------------------------------------------------------------------

hm_ring_buffer buffer;

void loop() {

  blinkMagenta.setActive(true);
  delay(300);
  blinkMagenta.setActive(false);

  buffer = {0};

#if 0 // RESET EEPROM STORAGE

  buffer.last_upload = Time.now();
  rb_store(&buffer);

#endif

  rb_load(&buffer);

  rb_add_event(&buffer, Time.now());

  uint32_t time_since_upload = Time.now() - buffer.last_upload;
  uint32_t mins_since_upload = time_since_upload / 60;

  if(rb_is_full(&buffer) || mins_since_upload > 5 ) {

      connect_to_cloud();

      if(rb_upload(&buffer)) {
        rb_reset(&buffer);
        buffer.last_upload = Time.now();
      } else {

        blinkYellow.setActive(true);
        delay(1000);
        blinkYellow.setActive(false);

      }

      disconnect_from_cloud();
  }

  rb_store(&buffer);
  delay(50);

  System.sleep(A2, RISING);

  return;

  // NOTE(Tom): only required in MANUAL mode
  // if (Particle.connected()) {
  //   Particle.process();
  // }
}

#2

Can you post a fully implemented test sketch?


#3

Also, which IMU library are you using?


#4

Hi, I updates the code above. Thanks


#5

I am using SparkFunLSM9DS1.hThanks