[Solved] Interrupt recognition on LSM303DLH

Hi guys!

I couldn’t solve it yet and hope to find some help here.

I have an LSM303DLH attached to an Arduino Mega 2560.
The project I would like to realize is quite simple. While there is nothing the Arduino should sleep, optimized also the LSM303DLH should be in Low Power Mode (but for the beginning this is not neccessary). An impact on the sensor of the LSM303DLH should activate the whole system by setting the INT1 of the LSM303DLH to LOW and wake my Arduino which now makes a LED light. I am not interessted in the value of the acceleration.
Until now my interrupt signal is on interrupt all the time, even when I just start the system.

May I can solve this. Because as I understood the datasheet, if I grab the data from the INT1_SRC_A register the interrupt signal should again be HIGH.
My problem at the moment is, I can’t read this register. May you help me please on how to read it.

I am using the pololu library for LSM303 boards:
github.com/pololu/lsm303-arduino

What I changed is this, which was not more than reading the datasheet (and similar datasheets) and copy and paste:


  else // DLM, DLH - Code-Line 266
  {
	// 0b00100100 = 0x24
	// 001 Normal Mode - 00 50Hz - 100 sensible axis zyx
	writeAccReg(CTRL_REG1_A, 0x24);
	
	// 0b00000000
	// 0 Boot - 00 HP-Filter - 0 filtered data selection - 0 HP filter enabled for int2 source - 0 HP filter enabled for int1 source -
	// 00 HP Filter Cut off Frequ
	writeAccReg(CTRL_REG2_A, 0x00);
	
	// 0b01000100
	// 0 Interrupt active HIGH - 1 open drain - 0 latch int2 - 00 Data Signal on INT2 pad - 1 latch int1 - 00 Data signal on INT1 pad
	writeAccReg(CTRL_REG3_A, 0x44);
	
	// 0b0000000
	// 0 block data update - 0 big/little endian data selection - 00 Full-Scale +-2g - 00 STsign - 0 ST disabled - 0 empty
	writeAccReg(CTRL_REG4_A, 0x00);
	
	// 0b00000000
	// 000000 empty - 00 Sleep-to-wake disabled
	writeAccReg(CTRL_REG5_A, 0x00);
	
	// 0b00110000
	// 0 AOI - 0 6D - 1 ZHIE - 1 ZLIE - 0000 for YHIE, YLIE, XHIE, XLIE
	writeAccReg(INT1_CFG_A, 0x30);
	
	// 0b00000001
	// 1LSB ~ 16mg
	writeAccReg(INT1_THS_A, 0x01);
	
	// 0b00000000
	// 1LSB ~ 10ms
	writeAccReg(INT1_DURATION_A, 0x00);
	
  }
}

This is my Arduino Test-Code:

Fist of all I initialze all needed variables. In the main-loop I look if the Pin 2 of the Arduino is LOW. This pin is connected with INT1 of the LSM303.
If an impact occurs Pin 2 goes Low and reads the data and prints it out. The value itself is yet not important.
I never get a LOW on Pin2 :frowning:


#include <Wire.h>
#include <LSM303.h>

LSM303 impactRec;
char report[80];

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  impactRec.init();
  impactRec.enableDefault();
  pinMode(2, INPUT);
}

void loop()
{
  if(digitalRead(2)==LOW){
    Serial.println("Impact occured");
    impactRec.read();
    snprintf(report, sizeof(report), "A: %6d %6d %6d    M: %6d %6d %6d",
      impactRec.a.x, impactRec.a.y, impactRec.a.z,
      impactRec.m.x, impactRec.m.y, impactRec.m.z);
    Serial.println(report);
  }
}

Hello, Bort.

I looked at your code and tried running it on an Arduino, and I found a few issues with it:

  • You say you want the LSM303DLH to generate an interrupt by setting INT1 LOW, but you’re setting the IHL bit in CTRL_REG3_A to 0, which makes the interrupt pins active high.
  • You have both ZHIE and ZLIE enabled in INT1_CFG_A, which will cause the interrupt to be always active.

This is not explained clearly in the datasheet, but a “Z high” event occurs whenever the absolute value of the Z acceleration is higher than the threshold; for example, if your threshold is 0.5 g, Z high will occur whenever the Z reading is more positive than +0.5 g or more negative than -0.5 g. Similarly, a “Z low” event occurs whenever the absolute value of the Z acceleration is lower than the threshold. The absolute value of the reading will always be either higher than or lower than the threshold, so either the Z high interrupt or the Z low interrupt will always be triggered, which would explain why the INT1 pin always seems to be high.

Also, do you have the Z axis of the accelerometer oriented perpendicular to the ground? If so, you’ll need to keep in mind that the accelerometer will detect a constant 1 g of upward acceleration due to gravity, which could make it hard to use the chip’s threshold detection to detect an impact.

You can read a register by using the library’s readAccReg() function. With the latest version of the LSM303 library, the syntax for reading INT1_SRC_A looks like this:

byte source = impactRec.readAccReg(LSM303::INT1_SRC_A);

By the way, if you would rather not modify the library directly, you could alternatively set up the interrupt in your sketch after calling enableDefault(). You have to qualify the register constants with the LSM303 class scope the same way:

   impactRec.enableDefault();

   // 0b00100100 = 0x24
   // 001 Normal Mode - 00 50Hz - 100 sensible axis zyx
   impactRec.writeAccReg(LSM303::CTRL_REG1_A, 0x24);

   // ...

Finally, I want to make sure your wiring looks reasonable. Are you using our LSM303DLH carrier? On that board, the interrupt pins are 1.8 V logic level outputs, so you need to use level shifters to connect them to a 5 V system. Could you post a picture showing your setup?

- Kevin

Thank you Kevin for your reply!

You are right! For measuring i decided to have them active HIGH. I changed this value already several times. It told me that writing to the registers works. At least to the CTRL_REG3_A. When I understand and build up my system I change this one to be active LOW. Parallel I am working to realize your advices. I think with them the project now should run in a couple of minutes.
For measuring I have a Tektronix DPO7104, which for simple Von and Gnd measurements may be a little overpowered.
For the Arduino I pull the open-drain up to 5V (VIN) and result in 3.2V at the INT1 pin. May there be an internal Pull-Up to 1.8V (VIO), because (1.8 + 3.2 = 5)V. Just found out, it didn’t work this way. I build will build a shifter now.

Yes I am using your carrier!With the Pull-Up to 5V, I only get 3.2V at INT1 (may because of an internal Pull-up, mentioned above), but this should be enough for the arduino.
arduino.cc/en/pmwiki.php?n=Reference/Constants
Pictures are attached to this post, the cables important for this approach are marked with red letters.

Thanks very much! These were very useful advices to me. I immediatelly set up the original library again and work now in the arduino surface only. I’m starting to get into this. :slight_smile:

That made it. I think it now works. Thank you a lot! I learned an awful lot on how to deal with the LSM303.




I’m glad to hear it’s working better for you now. Thanks for letting us know.

- Kevin