Use LIS3DH with Electron

@rickkas7 Hi Rick, can you tell me how to use the SPI mode with Electron and LIS3DH? I want to let Electron not sending any data when it is moving. So how to use your library?

I saw your MovingExample.cpp in your Github repository. But I am confused with the wire connection:

// LIS3DH is connected as in the AssetTracker, to the primary SPI with A2 as the CS (SS) pin, and INT connected to WKP
LIS3DHSPI accel(SPI, A2, WKP);

Does Electron have a pin named SPI? I know there is a WKP in on Electron, but I donā€™t find a SPI pin.

Thanks.

@anderson916, the respective pins for each of the available SPI interfaces is documented here
https://docs.particle.io/reference/firmware/electron/#spi

SPI uses three ā€œfixedā€ pins (CLK, MISO, MOSI) and one free to choose SS/CS pin to select which SPI device you want to talk to, when you have more than one device sharing the same bus.
Only ever one slave is allowed to have its SS/CS pin pulled low at any given moment.

My LIS3DH driver

(LIS3DH in the Community Libraries) does work in I2C mode. Just follow the example here:

Basically, youā€™d use:

// Connect the Adafruit LIS3DH breakout
// https://www.adafruit.com/products/2809
// VIN: 3V3
// GND: GND
// SCL: C5 (Electron Wire1)
// SDA: C4 (Electron Wire1)
// INT: WKP
LIS3DHI2C accel(Wire1, 0, WKP);

Or you could use for the regular I2C interface on D0/D1:

LIS3DHI2C accel(Wire, 0, WKP);
1 Like

Thanks. Yes, I2C mode works fine and I can get X,Y, Z. I am wondering how I can determine whether the device is static or not by X,Y, Z. Should I use SPI mode because your moving example uses SPI mode.

No, use the moving example, just change the definition for accel to use the LIS3DI2C object instead. The motion detection options work for both I2C and SPI the same way, so I didnā€™t replicate every combination of test.

Thanks. You saved my life.

But I have no luck with your position example. Should I connect INT pin to the WKP pin of Electron? Is it a must?

Can I judge whether the device is static or not just by X, Y and Z values?

If I recall correctly, the LIS3DH does not have built-in gravity compensation. So if itā€™s sitting flat, Iā€™d expect it to have a Z acceleration of 9.8 meters/sec^2 due to gravity. Itā€™s worse when itā€™s tilted, because there will be some effects of gravity on X and Y as well. You either have to ignore Z, compensate for it, or do the math to handle tilting.

Some other accelerometers, like the ADXL365, have a mode where you calibrate its gravity cancellation, but I donā€™t think the LIS3DH does that.

How would you use this LIS3DH ( https://github.com/rickkas7/LIS3DH) library to only monitor the X axis and to ignore Y and Z? Do you you have to modify the library? Iā€™ve got it working great using the examples, but Iā€™m not sure how to customize the other settings. An example would be great.

Thanks!

You want to only wake on move for a change in the X axis?

I havenā€™t tested this, but you should be able to make the setup code that looks something like this:

	// Initialize sensors
	LIS3DHConfig config;
	config.setLowPowerWakeMode(16);
    config.int1_cfg = LIS3DH::INT1_CFG_XHIE_XUPE;

	sensorsInitialized = accel.setup(config);

The setLowPowerWakeMode method normally enables detection in all 3 axes:

int1_cfg = LIS3DH::INT1_CFG_ZHIE_ZUPE | LIS3DH::INT1_CFG_YHIE_YUPE | LIS3DH::INT1_CFG_XHIE_XUPE;

The extra configuration line changes the setting so it only detects X instead.

Thanks Rick! I will try that.

Rick,

Which files do the new statements go? Do I need to mod the library? Also why is the System Thread required?

Thanks again!

That code goes into your setup() function. All of the code examples have a similar pattern, you just need to add the extra line:

config.int1_cfg = LIS3DH::INT1_CFG_XHIE_XUPE;

This overrides the default configuration without having to make a copy of the library.

Hello Rick,
I have no hardware yet and I am scoping out the support on the LIS3DH for a new project with a BluzDK.
I want to use the tapping feature and the temperature measure.
I read a couple coding examples from your library and Sparkfun to understand how to read the temperature.
I also tried to read here how to get temperature info and this file includes a comment that has me thinking I should use a different sensor:
//Note: By also setting tempEnabled = 1, temperature data is available
//on ADC3. Temperature differences can be read at a rate of
//1 degree C per unit of ADC3

First of all, do you expect I will be able to run your code on a BluzDK with I2C?
Have you tried reading the temperature? What is meant by differences? I see a comment in the header file about the sensor being ā€œhorribly inaccurateā€. There is very little coverage in the datasheet, but it states it is calibrated at Vdd=2.5V. The designs I found use 3.3V.
Finally, I am not sure how to adapt the Sparkfun ADC examples with your library to read the temperature.

Thanks,
Pesc

@rickkas7 Quick question.

I have an Electron + GPS Receiver + LIS3DH chip.

If I wanted to use the LIS3DH chip in i2c mode along with your Asset Tracker RK library would I only need to change these line:

LIS3DHI2C accel(Wire1, 0, WKP);

Yes. sort of. You canā€™t use the AssetTracker class, which is the compatibility layer that makes it look like the regular AssetTracker library.

But you can use the LIS3DH and TinyGPS++ classes directly with the LIS3DH in I2C mode and the GPS in regular serial mode. Most of the AssetTracker compatibly methods are a thin layer on top of the LIS3DH and TinyGPS++ methods, so itā€™s not hard to write to the underlying API. There are several examples that do that.

1 Like

Sweet!

Iā€™m using the TinyGPS++ library already with this new I2C GPS chip:

My goal is to use the LIS3DH over I2C also if possible.

Hoping I can get your Asset Tracker RK library wake on movement working with all the chips running over I2C.

Iā€™ll let you know how it goes.

The GPS module is very accurate but I want to compare it to the Active GPS antenna on the Particle Asset Tracker just to see the difference.

1 Like

@rickkas7 I got everything working on the i2c bus using your Asset Tracker library :slight_smile:

Itā€™s nice to have a quality Accelerometer to add to my box of tools.

I did notice one line that I think needs to be changed regarding the GPS positioning.

In the GPS Wait State case you have if (gps.location.isValid()) {

I noticed that the program would constantly use the previous GPS Fix location data even though it had zero satellites in view. If I would have moved the GPS unit it would have still used the old GPS position data even though I was someplace different.

I looked this up and others noticed the same issue with the gps.location.isValid() command.

Here is a way to force the code to get a new GPS fix if the old GPS position data is older than a preset threshold.

2 Likes

Thatā€™s a reasonable workaround. Basically once the GPS goes valid, itā€™s never not valid again. Itā€™s just the way it works, but I didnā€™t understand that when I wrote the code. Checking the age is a reasonable way to work around it.

2 Likes

Iā€™m happy I can pitch in on this :slight_smile:

I have a similar issue, but while using SPI mode. It should be wired properly.

(for the record)
// VIN: 3V3
// 3VO: no connection
// GND: GND
// SCL: A3 (SCK)
// SDA: A5 (MOSI)
// SDO: A4 (MISO)
// CS: A2 (SS)
// INT: WKP

while using your example for the position: https://go.particle.io/shared_apps/59b1b31e8465f88348000ca4

It states the device was no found, printing ā€˜ā€˜no sampleā€™ā€™ continously. In addition, using accel.calibrateFilter wonā€™t do anything either. However, the Wakeonmove example does seem to work as it will wake up the Electron and even the sensitivty seems adjustable with code.

When I use the code with my Asset Tracker it works flawlessly.