Standalone ESPHome external_components fork of latonita's draft LIS2DH12 PR (esphome#14788) with four targeted fixes applied on top.
- Stale-sample guard in
update()— the upstream draft burst-readsOUT_X_Lon every polled tick regardless of whether a fresh sample is ready, so when ESPHome'supdate_intervalruns faster than the chip's effective ODR you get duplicate samples re-published as if they were new. This fork readsSTATUS_REGfirst and bails out early ifZYXDAisn't set — only fresh data reaches the sensor publishes. Mirrors the in-treelis3dhpattern. - Throttled
loop()status reads (Fix 1b) — the upstream draft readsCLICK_SRC+INT1_SRCon every main-loop tick (~60-200 Hz), generating constant I²C traffic that can cluster into watchdog-tripping spikes (took a long time for an operation (174 ms), max is 30 ms). This fork throttles those reads to once per 50 ms, which still catches taps (event cooldown is 500 ms) and orientation transitions while cutting bus utilization ~10x. This is the actual fix for the "took a long time" warning. - Optional
interrupt_pin:for data-ready (Fix 2) — wire the LIS2DH12INT1line to a GPIO and acceleration samples are pulled in an ISR-drivenloop()instead of polled. Wheninterrupt_pin:is configured, polledupdate()is a no-op to avoid a double-read race onOUT_*registers. - High-pass filter (HPF) support (Fix 3) — enable the chip's on-die HPF on the output data path via
CTRL_REG2.FDS, with full control overHPM(mode) andHPCF(cutoff) bits. Removes the need to subtract gravity in user lambdas.
Latonita's PR has been open in draft for a while and we need these fixes in production now. Forking lets us ship without waiting for upstream review and merge. The component is otherwise a near-verbatim copy of his work.
Add the external component to your ESPHome YAML:
external_components:
- source: github://Valar-Systems/esphome-lis2dh12
components: [lis2dh12_base, lis2dh12_i2c]i2c:
sda: GPIO8
scl: GPIO9
lis2dh12_i2c:
id: accel
address: 0x19
range: 2G
resolution: high
output_data_rate: 100Hz
update_interval: 1s
# Fix 2: route INT1 (data-ready) to a GPIO; loop() drains on the ISR flag.
interrupt_pin:
number: GPIO5
mode:
input: true
pullup: false
# Fix 3: enable the on-chip high-pass filter on the output data path.
high_pass_filter: true
hpf_mode: NORMAL # NORMAL | REFERENCE | NORMAL2 | AUTORESET
hpf_cutoff: 0 # 0..3 (higher = lower cutoff frequency; depends on ODR)
sensor:
- platform: lis2dh12_base
lis2dh12_id: accel
acceleration_x:
name: "Accel X"
acceleration_y:
name: "Accel Y"
acceleration_z:
name: "Accel Z"Fixes 1 and 1b apply automatically — no YAML knobs.
These are present in the ST datasheet and partially implemented in the underlying register writes, but not yet exposed as ESPHome entities / config knobs:
- FIFO mode (stream / FIFO / bypass) and watermark interrupt
- Interrupt sources for 6D orientation (face up/down, portrait, landscape) wired as text sensor / binary sensors
- Single-tap and double-tap binary sensors / triggers exposed at the YAML level
- Activity / inactivity (sleep-to-wake) configuration
- Free-fall detection threshold / duration as YAML options
Contributions welcome.
When esphome#14788 merges into the ESPHome mainline (and the four fixes here either landed upstream or are no longer needed), drop the external_components: block and use the built-in lis2dh12_* component instead.
Original LIS2DH12 ESPHome component authored by @latonita in esphome#14788. This fork keeps CODEOWNERS pointing to the original author for the unmodified base, adds the fixes listed above, and is otherwise a near-verbatim copy of his work. Released under the same MIT license as ESPHome itself.