Current section
Files
Jump to
Current section
Files
test/support/veml7700.ex
defmodule CircuitsSim.Device.VEML7700 do
@moduledoc """
Vishay VEML7700 ambient light sensor
Typically found at 0x10 or 0x48
See the [datasheet](https://www.vishay.com/docs/84286/veml7700.pdf) for details.
Call `set_state/3` to change the state of the sensor.
"""
alias CircuitsSim.I2C.I2CDevice
alias CircuitsSim.I2C.I2CServer
defstruct als_config: 0,
als_threshold_high: 0,
als_threshold_low: 0,
als_power_saving: 0,
als_output: 0,
white_output: 0,
interrupt_status: 0
@type t() :: %__MODULE__{
als_config: 0..0xFFFF,
als_threshold_high: 0..0xFFFF,
als_threshold_low: 0..0xFFFF,
als_power_saving: 0..0xFFFF,
als_output: 0..0xFFFF,
white_output: 0..0xFFFF,
interrupt_status: 0..0xFFFF
}
@spec child_spec(keyword()) :: Supervisor.child_spec()
def child_spec(args) do
device = __MODULE__.new()
I2CServer.child_spec_helper(device, args)
end
@spec new(keyword) :: t()
def new(_options \\ []) do
%__MODULE__{}
end
@spec set_state(String.t(), Circuits.I2C.address(), number()) :: :ok
def set_state(bus_name, address, kv) do
I2CServer.send_message(bus_name, address, {:set_state, kv})
end
## protocol implementation
defimpl I2CDevice do
@cmd_als_config 0
@cmd_als_threshold_high 1
@cmd_als_threshold_low 2
@cmd_als_power_saving 3
@cmd_als_output 4
@cmd_white_output 5
@cmd_interrupt_status 6
@impl I2CDevice
def read(state, count) do
{:binary.copy(<<0>>, count), state}
end
@impl I2CDevice
def write(state, <<@cmd_als_config, als_config::little-16>>) do
%{state | als_config: als_config}
end
def write(state, _), do: state
@impl I2CDevice
def write_read(state, <<@cmd_als_config>>, read_count) do
result = <<state.als_config::little-16>> |> trim_pad(read_count)
{result, state}
end
def write_read(state, <<@cmd_als_output>>, read_count) do
result = <<state.als_output::little-16>> |> trim_pad(read_count)
{result, state}
end
def write_read(state, _to_write, read_count) do
{:binary.copy(<<0>>, read_count), state}
end
defp trim_pad(x, count) when byte_size(x) >= count, do: :binary.part(x, 0, count)
defp trim_pad(x, count), do: x <> :binary.copy(<<0>>, count - byte_size(x))
@impl I2CDevice
def render(state) do
light_lux = Float.round(state.light_lux * 1.0, 3)
"Light: #{light_lux} lux"
end
@impl I2CDevice
@spec handle_message(CircuitsSim.Device.VEML7700.t(), {:set_state, any}) :: {:ok, struct}
def handle_message(state, {:set_state, kv}) do
{:ok, struct!(state, kv)}
end
end
end