Current section

Files

Jump to
servo_kit lib servo_kit.ex
Raw

lib/servo_kit.ex

defmodule ServoKit do
@moduledoc """
Use PCA9685 PWM/Servo Controller in Elixir
"""
use GenServer
@type options() :: [name: GenServer.name()] | ServoKit.PCA9685.options()
@type state :: ServoKit.PCA9685.t()
def start_link(opts \\ []) do
GenServer.start_link(__MODULE__, opts, name: opts[:name] || __MODULE__)
end
def set_pwm_frequency(pid \\ __MODULE__, freq_hz) do
GenServer.call(pid, {:set_pwm_frequency, freq_hz})
end
def set_pwm_duty_cycle(pid \\ __MODULE__, duty_cycle, ch: ch) do
GenServer.call(pid, {:set_pwm_duty_cycle, duty_cycle, ch: ch})
end
@impl true
def init(opts) do
driver_options = Keyword.take(opts, [:bus_name, :address, :reference_clock_speed, :frequency])
ServoKit.PCA9685.init(driver_options)
end
@impl true
def handle_call({:set_pwm_frequency, freq_hz}, _from, state) do
case result = ServoKit.PCA9685.set_pwm_frequency(state, freq_hz) do
{:ok, new_state} ->
{:reply, result, new_state}
{:error, _} ->
{:reply, result, state}
end
end
def handle_call({:set_pwm_duty_cycle, duty_cycle, ch: ch}, _from, state) do
case result = ServoKit.PCA9685.set_pwm_duty_cycle(state, duty_cycle, ch: ch) do
{:ok, new_state} ->
{:reply, result, new_state}
{:error, _} ->
{:reply, result, state}
end
end
@doc """
Maps a given value in one range to another range.
## Examples
iex> ServoKit.map(0, {0, 180}, {2.5, 12.5})
2.5
iex> ServoKit.map(45, {0, 180}, {2.5, 12.5})
5.0
iex> ServoKit.map(90, {0, 180}, {2.5, 12.5})
7.5
iex> ServoKit.map(180, {0, 180}, {2.5, 12.5})
12.5
iex> ServoKit.map(0, {-1.0, 1.0}, {2.5, 12.5})
7.5
iex> ServoKit.map(-1, {-1.0, 1.0}, {2.5, 12.5})
2.5
iex> ServoKit.map(1, {-1.0, 1.0}, {2.5, 12.5})
12.5
"""
@spec map(number, {number, number}, {number, number}) :: float
def map(x, {in_min, in_max}, {out_min, out_max})
when is_number(x) and
is_number(in_min) and is_number(in_max) and in_min < in_max and
is_number(out_min) and is_number(out_max) and out_min < out_max do
(x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
end
end