/
pivotpi.ex
76 lines (65 loc) · 1.86 KB
/
pivotpi.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
defmodule GrovePi.PivotPi do
@moduledoc """
This module lets you interact with the
[PivotPi](https://www.dexterindustries.com/pivotpi-tutorials-documentation/)
through the [GrovePi](https://www.dexterindustries.com/grovepi/).
Plug your PivotPi into the GrovePi I2C-1 port. Plug your servo motor into
channel 1. You must initialize the PivotPi board using
`GrovePi.PivotPi.initialize/0`.
```elixir
iex> GrovePi.PivotPi.start()
:ok
iex> GrovePi.PivotPi.angle(1, 180)
:ok
iex> GrovePi.PivotPi.angle(1, 90)
:ok
iex> GrovePi.PivotPi.angle(1, 0)
:ok
iex> GrovePi.PivotPi.led(1, 100)
:ok
iex> GrovePi.PivotPi.led(1, 50)
:ok
iex> GrovePi.PivotPi.led(1, 0)
:ok
```
"""
@type channel :: 1..8
@type angle :: 0..180
@type percent :: 0..100
alias GrovePi.PivotPi.PCA9685
@max_12_bit_value 4095
@doc """
Move the Servo motor to a new position. Accepts angle from 0-180.
"""
@spec angle(channel, angle) :: :ok | {:error, term}
def angle(channel, angle) do
pwm_to_send = @max_12_bit_value - translate_to_servo_range(angle)
device_channel = channel - 1
PCA9685.set_pwm(device_channel, 0, pwm_to_send)
end
defp translate_to_servo_range(angle_value) do
value_scaled = angle_value / 180
round(150 + value_scaled * 450)
end
@doc """
Control the PivotPi LEDs. Channel # should match Servo #. Accepts % from 0-100.
"""
@spec led(channel, percent) :: :ok | {:error, term}
def led(channel, percent) do
pwm_to_send = translate_to_12_bit(percent)
PCA9685.set_pwm(convert_to_led(channel), 0, pwm_to_send)
end
defp translate_to_12_bit(percent) do
round(percent / 100 * @max_12_bit_value)
end
defp convert_to_led(channel) do
channel + 7
end
@doc """
Initialize the PivotPi board.
"""
@spec initialize() :: :ok | {:error, term}
def initialize() do
PCA9685.initialize()
end
end