dajtxx But the above readings are with the board sitting on my desk. So does -9.8… equate to 1g?

The measurements are in m/s2. 1g = 9.80665 m/s2

And why are there non-zero values on x & Y when the board is not moving? Do I need to put some code in to add offsets for manufacturing or something?

XY are never going to be perfect zero. They could be offset by a small amount in either the positive or negative direction.

To get the sample working I had to enable floating point support on the MCU and use newlib so the double values could be printed out. I also changed the setup of the sensor using guiconfig to have no trigger so it’s being polled by the code because I was getting constant reboots with the trigger enabled.

Yea, I’m aware of this, turns out the driver was changed along the way and now requires two pins to be defined for interrupts (even if there’s only one connected!) I opened up a ticket on the Zephyr repolast week: https://github.com/zephyrproject-rtos/zephyr/issues/34794

Easiest solution for now is to pick another pin that you’re not using as the INT2 pin in your .overlay file.

&i2c1 {
	lis2dh@18 {
		compatible = "st,lis2dh";
		label = "LIS2DH";
		reg = <0x18>;
		irq-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>, <&gpio0 30 GPIO_ACTIVE_HIGH>;
	};
};
2 years later

@mlYallow

Both interrupt pins are/can be connected. Here’s a snippet from the schematic:

INT1 is, by default, connected. INT2 is the opposite. If you need it simply solder the jumper that’s on the bottom of the board. I believe it’s been like this since V3 of the board.

    jaredwolff Thank you for the reply! I use the SparkFun Thing nRF9160 Thing Plus which unfortunately does not have this option. Am I correct to think that the only way to get interrupt to work on the SparkFun board is to manually solder the INT2 pin to the nRF9160 - P0.29 pin?

    Best Regards

      mlYallow what type of interrupt are you trying to configure. I know the LIS2DH is fairly flexible on how you can use the interrupt pins. (in some ways, redundant). The driver is not as flexible though. :\

      mlYallow Am I correct to think that the only way to get interrupt to work on the SparkFun board is to manually solder the INT2 pin to the nRF9160 - P0.29 pin?

      P0.29 is one option. It may be tough to get to since the pads are underneath the LIS2DH though.

        jaredwolff I’ve been trying to set the “SENSOR_ATTR_UPPER_THRESH” and/or “SENSOR_ATTR_LOWER_THRESH” alternatively using the "SENSOR_TRIG_DELTA, as I want movement to trigger the system into a different state. The plan is to connect a display that I want to wake up when the accelerometer detects movement.

        Yeah, soldering on pads that are underneath the LIS will turn out difficult, hehe.

        Yea, unfortunately you’ll have to configure the INT1_CFG register manually or modify the driver. 😦

          a month later

          Just some remarks from my current experience with ncs 2.3.0 / zephyr v3.2.99-ncs2:

          The bindings introduce a “anym-on-int1” flag, which allows to route the SENSOR_TRIG_DELTA also to int1. With that you need to define only 1 gpio for interrupt mapping.

          The SENSOR_TRIG_DELTA seems to enable mainly the threshold interrupts. Though you already recognized, one axis may show pretty large values, a large threshold is usually used. Otherwise the threshold interrupt will fire permanently, But that large threshold makes it also less sensitive. The documentation explains the functions in more details.

          Luckily the LIS2DH12 supports also a “REFERENCE” and “High pass filter”. To use it , you need to enable CONFIG_LIS2DH_ACCEL_HP_FILTERS and use

          struct sensor_value filter = {
                    .val1 = 1,
                    .val2 = 0,
                };
          
             rc = sensor_attr_set(accelerometer_dev, SENSOR_CHAN_ACCEL_XYZ,
                                     SENSOR_ATTR_CONFIGURATION,
                                     &filter);

          That will still not be the wanted behavior for motion, because the filter should be frequently reset.
          The driver unfortunately does support that out of the box (maybe worth to extend).
          I put some extra lines in my application:

          ...
          #include <zephyr/drivers/i2c.h>
          ...
          #define LIS2DH_REG_CTRL2 0x21
          static const struct i2c_dt_spec accelerometer_i2c_spec = I2C_DT_SPEC_GET(DT_ALIAS(accelerometer_sensor));
          ...
          
                rc = i2c_reg_update_byte_dt(&accelerometer_i2c_spec, LIS2DH_REG_CTRL2, 0xc0, enable ? 0xc0 : 0);
                if (rc) {
                   LOG_ERR("Accelerometer error: could not enable autoreset high-pass filter for device %s, %d / %s",
                           accelerometer_dev->name, rc, strerror(-rc));
                }
          
                value.val1 = enable ? 1 : 0;
                rc = sensor_attr_set(accelerometer_dev, SENSOR_CHAN_ACCEL_XYZ,
                                     SENSOR_ATTR_CONFIGURATION,
                                     &value);
                if (rc) {
                   LOG_ERR("Accelerometer error: could not set high-pass filter for device %s, %d / %s",
                           accelerometer_dev->name, rc, strerror(-rc));
                }

          With that I get the result I was expecting “motion detection”.

          (Edit: not using LIS2DH_REG_CTRL2 may also result in useful behavior, just check, if that fits for you as well.)

          Hope it helps.

          a month later

          jaredwolff Hi again🙂 I’ve got the new CircuitDojo feather9160 board and soldered the JUMP3 pad. I have decided that I want to read the accelerometer once every second, which as far I understand, corresponds to the accelerometer sample provided. What confuses me is that the trigger is not getting triggered, and stays in the while loop, see below.

              printf("Waiting for triggers\n");
              while (true)
              {
                  k_sleep(K_MSEC(2000));
              }

          I’m not getting any errors when running the code, here is the serial output:
          Booting Zephyr OS build v3.2.99-ncs2 ***
          Sampling at 1 Hz
          Waiting for triggers

          Am right to expect a reading from the accelerometer once every second?

          In advance, thank you.
          Kind Regards.

            printf("Waiting for triggers\n");
            while (true)
            {
                k_sleep(K_MSEC(2000));
            }

            There is no magic in that. It sleeps for 2s in a endless loop. It just prevents the app from exit.

            The magic for the accelerometer is in

            rc = sensor_trigger_set(sensor, &trig, trigger_handler);

            that registers an callback trigger_handler, which is then called, when the LIS2DH reports an event via the IO pins and these pins are configured for that interrupt. When that callback is executed, it calls

            static void trigger_handler(const struct device *dev,
                                        const struct sensor_trigger *trig)
            {
                fetch_and_display(dev);
            }

            and that display then the values.

                if (rc < 0)
                {
                    printf("ERROR: Update failed: %d\n", rc);
                }
                else
                {
                    printf("#%u @ %u ms: %sx %f , y %f , z %f\n",
                           count, k_uptime_get_32(), overrun,
                           sensor_value_to_double(&accel[0]),
                           sensor_value_to_double(&accel[1]),
                           sensor_value_to_double(&accel[2]));
                }

            at the end of fetch_and_display should then print at least an error.
            Otherwise, I would guess, either the interrupt isn’t configured well (e.g. nRF9160 pin 29 for data ready, but nRF9160 pin 30 wired to LIS2DH int1 which is then the default event for that “data_ready”), or some other issue with the configuration prevents the callback from being called, e.g.

            CONFIG_LIS2DH_TRIGGER_NONE=y

            instead of

            CONFIG_LIS2DH_TRIGGER_GLOBAL_THREAD=y

            A very first shot, it may work or not, would be to use exchanged pins in the overlay, e.g. instead of

            iq-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>, <&gpio0 30 GPIO_ACTIVE_HIGH>;
            iq-gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>, <&gpio0 29 GPIO_ACTIVE_HIGH>;

              AchimKraus

              Thanks for the swift reply!

              Just changed the pins as you suggested and it worked.

              I get the other parts you explained above but could you explain why changed the pins resulted in it working? Wouldn’t both pin 29 and 30 be valid irq pins that could trigger the accelerometer?

              Kind regards,
              and again, thank you🙂

                The schematics shows on page 3 the wiring.

                nRF9160 pin 30 <– JMP 1 — LIS2DH INT 1
                nRF9160 pin 29 <– JMP 3 — LIS2DH INT 2

                The LIS2DH documentation explains, how the events (e.g. “data ready” or “any motion/threshold”) are then mapped/configured to the INT1 or INT2 pins. The driver (I analyzed that some weeks ago) maps these events by default:

                data-ready => INT1
                any-motion => INT2

                With that, “data-ready” is
                LIS2DH INT1 – JMP 1 —> nRF9160 pin 30

                and bindings then explains:

                The INT1 and (optional) INT2 signal connections.

                With that,

                iq-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>, <&gpio0 30 GPIO_ACTIVE_HIGH>;

                maps pin 29 to the “data ready” event, but physically it’s connected to pin 30.

                iq-gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>, <&gpio0 29 GPIO_ACTIVE_HIGH>;

                maps then the defaults of the LIS2DH driver to the current wiring.

                If you add the “anym-on-int1”, you even don’t need JMP3. Then the LIS2DH reports both, “data-ready” and “any-motion” on INT1, which is wired to PIN30 and all works without modification.

                  14 days later

                  I think the .overlay file in the sample program should be changed to:
                  irq-gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>, <&gpio0 29 GPIO_ACTIVE_HIGH>;
                  because according to the schematics for feather V5, INT1 is connected to P0.30 and INT2 is (via jmp3) connected to P0.29

                    AS a “nice to have” the codesnippet from the zephyr sample count be added also, allowing the temperature to be read, I have testet that i works.

                      if (IS_ENABLED(CONFIG_LIS2DH_MEASURE_TEMPERATURE)) {
                      	if (rc == 0) {
                      		rc = sensor_channel_get(sensor, SENSOR_CHAN_DIE_TEMP, &temperature);
                      		if (rc < 0) {
                      			printf("\nERROR: Unable to read temperature:%d\n", rc);
                      		} else {
                      			printf(", t %f\n", sensor_value_to_double(&temperature));
                      		}
                      	}
                      
                      } else {
                      	printf("\n");
                      }

                      I think the .overlay file in the sample program should be changed to:

                      That depends on what should be achieved. If that should support a “unmodified feather v5”, I think,

                           lis2dh: lis2dh@18 {
                      		/* changed in v5 */
                      		irq-gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>;
                      		anym-on-int1;
                      	}; 

                      as version specific definition will be the right one. Maybe adding

                      irq-gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>, <&gpio0 29 GPIO_ACTIVE_HIGH>;

                      as comment addressing JMP 3.

                      allowing the temperature to be read,

                      The question is more, what “the temperature” really represents. The nRF9160 has a temperature as well (“AT%XTEMP?”), but in my opinion none of them provide the value of a real temperature sensor.

                        The temperature on the LIS2DH supposedly does output a temperature but it’s with a 25 degree offset. So 25 - (your reading) should get you the actual temp. I’ve only tested this across a few different devices. There was one device that was giving some weird values. So IMO better to use something more reliable/dedicated.

                          The question is more, what “the temperature” really represents.

                          The point is more, it represents the temperature of that chip, which may depend on the current consumption and self heating. For the LIS2DH that maybe acceptable, but it’s more a general topic. If you want the temperature of something (e.g. environment) a extra sensor is more accurate. With the newer zephyr versions, one-wire got supported and that makes using a cheap temperature sensor (DS18B20) possible.
                          And if someone doesn’t care too much, the modem’s temperature does it as well.

                          100% agree. Especially if you need something accurate.

                            Terms and Conditions | Privacy Policy