I have a header put together for this, and it is working. Somewhat.
There are still some issues. I’m examining the CLICK_SRC register within the loop, but I never see single clicks, only double clicks. It also seems to be more sensitive on certain axis than others.
The text in the data sheet for the previous version (LSM303DLHC) was actually a bit more descriptive, although they are still structured differently.
ConfigureClickDetection() is called from setup(), GetClickInfo() is called from within the loop() and the if the return indicates a click occurred then PrintClickInfo() is called to display the individual bit values from the result register.
#ifndef ClickStuff_h
#define ClickStuff_h
#include <Arduino.h>
#include <LSM303.h>
#include <Adafruit_CharacterOLED.h>
typedef struct
{
bool isInterrupt;
bool isDouble;
bool isSingle;
bool isPositive;
bool isZ;
bool isY;
bool isX;
} ClickInfo;
// Retrieves the info on the click status and returns a struct populated with that data.
ClickInfo GetClickInfo(LSM303 compass)
{
ClickInfo inf;
// Read click bit info from source register.
byte clickInf = compass.readReg(LSM303::CLICK_SRC); // Get the source register byte, click data from accelerometer.
inf.isInterrupt = clickInf & 0x40; // bit is 1 if interrupt occurred (i.e. it registered a click)
inf.isDouble = clickInf & 0x20; // bit is 1 if it is a double click
inf.isSingle = clickInf & 0x10; // bit is 1 if it is a single click
inf.isPositive = clickInf & 0x8; // bit is 0 if positive direction, 1 negative direction
inf.isZ = clickInf & 0x4; // bit is 1 if click is on the Z axis
inf.isY = clickInf & 0x2; // bit is 1 if click is on the Y axis
inf.isX = clickInf & 0x1; // bit is 1 if click is on the X axis
return inf;
}
void PrintClickInfo(ClickInfo inf, Adafruit_CharacterOLED lcd)
{
lcd.clear();
lcd.setCursor(0, 2);
lcd.print(String(inf.isInterrupt) + "," + String(inf.isDouble) + "," + String(inf.isSingle) + "," + String(inf.isPositive) + "," + String(inf.isZ) + "," + String(inf.isY) + "," + String(inf.isX));
}
// Handle click: examine generated values, do something.
void Click(ClickInfo inf, Adafruit_CharacterOLED lcd)
{
// Do something here based on click input.
PrintClickInfo(inf, lcd);
// Give us time to read results on display.
delay(4000);
}
void ConfigureClickDetection(LSM303 compass)
{
/*
These are the click related registers from the spec sheet for reference.
CTRL0 HP_Click(position 3) High-pass filter enabled for click function. Default value: 0 (0: filter bypassed; 1: filter enabled)
CTRL3 _Click(position 7) Click generator interrupt on INT1. Default value: 0 (0: disable; 1: enable)
CTRL4 _Click(position 8) Click generator interrupt on INT2. Default value: 0 (0: disable; 1: enable)
CLICK_CFG
ZD(position 6) Enable interrupt double click-click on Z-axis. Default value: 0 (0: disable interrupt request; 1: enable interrupt request on measured accel. value higher than preset threshold)
ZS(position 5) Enable interrupt single click-click on Z-axis. Default value: 0 (0: disable interrupt request; 1: enable interrupt request on measured accel. value higher than preset threshold)
YD(position 4) Enable interrupt double click-click on Y-axis. Default value: 0 (0: disable interrupt request; 1: enable interrupt request on measured accel. value higher than preset threshold)
YS(position 3) Enable interrupt single click-click on Y-axis. Default value: 0 (0: disable interrupt request; 1: enable interrupt request on measured accel. value higher than preset threshold)
XD(position 2) Enable interrupt double click-click on X-axis. Default value: 0 (0: disable interrupt request; 1: enable interrupt request on measured accel. value higher than preset threshold)
XS(position 1) Enable interrupt single click-click on X-axis. Default value: 0 (0: disable interrupt request; 1: enable interrupt request on measured accel. value higher than preset threshold)
CLICK_SRC
IA(position 7) Interrupt active. Default value: 0 (0: no interrupt has been generated; 1: one or more interrupts have been generated)
DClick(position 6) Double click-click enable. Default value: 0 (0: double click-click detection disable; 1: double click-click detection enable)
SClick(position 5) Single click-click enable. Default value: 0 (0: single click-click detection disable; 1: single click-click detection enable)
Sign(position 4) Click-click sign. 0: positive detection; 1: negative detection
Z(position 3) Click-click sign. 0: positive detection; 1: negative detection
Y(position 2) Y click-click detection. Default value: 0 (0: no interrupt; 1: Y high event has occurred)
X(position 1) X click-click detection. Default value: 0 (0: no interrupt; 1: X high event has occurred)
CLICK_THS _, Ths6, Ths5,Ths4, Ths3, Ths2, Ths1, Ths0 Click-click threshold. Default value: 000 0000
TIME_LIMIT _, TLI6, TLI5, TLI4, TLI3, TLI2, TLI1, TLI0 Click-click time limit. Default value: 000 0000
TIME_LATENCY TLA7, TLA6, TLA5, TLA4, TLA3, TLA2, TLA1, TLA0 Click-click time latency. Default value: 000 0000
TIME_WINDOW TW7, TW6, TW5, TW4, TW3, TW2, TW1, TW0 Click-click time window
Act_THS _, ACTH6, ACTH5, ACTH4, ACTH3, ACTH2, ACTH1, ACTH0 Sleep to Wake, Return to Sleep activation threshold 1LSb = 16mg
Act_DUR ActD7, ActD6, ActD5, ActD4, ActD3, ActD2, ActD1, ActD0 Sleep to Wake, Return to Sleep duration DUR = (Act_DUR + 1)*8/ODR
IG_CFG1 Inertial interrupt generator 1 configuration register.
AOI And/Or combination of interrupt events. Default value: 0.
6D 6-direction detection function enabled. Default value: 0.
ZHIE/ZUPE Enable interrupt generation on Z high event or on direction recognition. Default value: 0 (0: disable interrupt request; 1: enable interrupt request)
ZLIE/ZDOWNE
YHIE/YUPE
YLIE/YDOWNE
XHIE/XUPE
XLIE/XDOWNE
IG_THS1 0, THS6, THS5, THS4, THS3, THS2, THS1, THS0 Interrupt generator 1 threshold. Default value: 000 0000
IG_DUR1 0, D6, D5, D4, D3, D2, D1, D0 Duration value. Default value: 000 0000. D6 - D0 bits set the minimum duration of the interrupt 1 event to be recognized. Duration steps and maximum values depend on
the ODR chosen.
*/
// Turn on single and double clicks for Z, Y and X axis
compass.writeReg(LSM303::CLICK_CFG, 0x3F);
// Set click/double click configuration values
compass.writeReg(LSM303::CLICK_THS, 0x3C);
compass.writeReg(LSM303::TIME_LIMIT, 0x46);
compass.writeReg(LSM303::TIME_LATENCY, 0x40);
compass.writeReg(LSM303::TIME_WINDOW, 0xFF);
compass.writeReg(LSM303::Act_THS, 0x0);
compass.writeReg(LSM303::Act_DUR, 0x30);
}
#endif