LIS3DH.Sampler (lis3dh v0.1.0)

Copy Markdown

GenServer that drains the LIS3DH's FIFO and dispatches frames to a subscriber process.

Why this exists

Polling raw OUT_* registers from the BEAM is fine at low ODRs, but at 100 Hz+ the chip's 32-level FIFO and watermark interrupt let the host off-load buffering to silicon and only intervene on a chosen watermark threshold.

Modes

Set the :mode option to one of:

  • :stream (default) — overwrites the oldest sample when full. Best for continuous streaming at the watermark interval. Recommended.
  • :fifo — fills to 32 samples and stops. Use when you want a fixed snapshot triggered by external timing.
  • :stream_to_fifo — starts in Stream and switches to FIFO when an interrupt fires on the configured trigger pin. Use to capture history around an event (motion, free-fall, click).

The sampler only routes the FIFO watermark interrupt to INT1CTRL_REG3.I1_WTM. The chip has no equivalent INT2 bit, so external wiring must use INT1 for FIFO.

Frame format

Each FIFO sample is one X/Y/Z accelerometer reading. Frames are dispatched as {LIS3DH.Sampler, sampler_pid, [%{x: float, y: float, z: float}, ...]} messages where each map contains values in m/s² scaled from the cached operating mode and range on the LIS3DH struct.

Usage

{:ok, i2c} = Wafer.Driver.Circuits.I2C.acquire(bus_name: "i2c-1", address: 0x18)
{:ok, acc} = LIS3DH.acquire(conn: i2c)
{:ok, acc} = LIS3DH.configure_accelerometer(acc,
  mode: :high_resolution, odr: 200, range: 2)

{:ok, int1} = Wafer.Driver.Circuits.GPIO.acquire(pin: 17, direction: :in)

{:ok, _sampler} =
  LIS3DH.Sampler.start_link(acc: acc, int1: int1, mode: :stream, watermark: 16)

receive do
  {LIS3DH.Sampler, _pid, frames} -> IO.inspect(frames)
end

Summary

Types

Options accepted by start_link/1.

t()

Internal sampler state.

Functions

Returns a specification to start this module under a supervisor.

Synchronously drain the FIFO and return any complete frames. Used in pull-only mode or for on-demand reads.

Start a FIFO sampler.

Types

option()

@type option() ::
  {:acc, LIS3DH.t()}
  | {:int1, Wafer.Conn.t() | nil}
  | {:subscriber, pid()}
  | {:mode, LIS3DH.Fifo.mode()}
  | {:watermark, LIS3DH.Fifo.watermark()}
  | {:trigger, LIS3DH.Fifo.trigger()}
  | {:name, GenServer.name()}

Options accepted by start_link/1.

t()

@type t() :: %LIS3DH.Sampler{
  acc: LIS3DH.t(),
  int1: Wafer.Conn.t() | nil,
  mode: LIS3DH.Fifo.mode(),
  subscriber: pid(),
  watermark: LIS3DH.Fifo.watermark()
}

Internal sampler state.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

drain(server)

@spec drain(GenServer.server()) :: {:ok, [LIS3DH.axes()]} | {:error, term()}

Synchronously drain the FIFO and return any complete frames. Used in pull-only mode or for on-demand reads.

start_link(opts)

@spec start_link([option()]) :: GenServer.on_start()

Start a FIFO sampler.

Options

  • :acc (required) — an LIS3DH struct with :operating_mode and :range cached (e.g. via LIS3DH.configure_accelerometer/2).
  • :int1 (optional) — a Wafer.GPIO-implementing connection wired to the device's INT1 pin. Without it the sampler runs pull-only.
  • :subscriber (default self()) — process that receives frame messages.
  • :mode (default :stream) — LIS3DH.Fifo.mode/0.
  • :watermark (default 16) — LIS3DH.Fifo.watermark/0.
  • :trigger (default :int1) — Stream-to-FIFO trigger pin (LIS3DH.Fifo.trigger/0); ignored in other modes.
  • :name — optional GenServer registration name.