Skip to content

Instantly share code, notes, and snippets.

@bchase
Last active November 2, 2016 19:18
Show Gist options
  • Select an option

  • Save bchase/b6b9774582abaa3b45ed87a6fd918dbf to your computer and use it in GitHub Desktop.

Select an option

Save bchase/b6b9774582abaa3b45ed87a6fd918dbf to your computer and use it in GitHub Desktop.
Elixir + Raspberry Pi 2 GPIO to drive a 4 channel relay module (https://smile.amazon.com/gp/product/B00KTEN3TM)
defmodule RPi.GPIO.RelayController do
use GenServer
### CLIENT API ###
def start_link do
GenServer.start_link __MODULE__, :init_args, []
end
def on( pid, relay_num), do: GenServer.cast(pid, {:on, relay_num})
def off(pid, relay_num), do: GenServer.cast(pid, {:off, relay_num})
### SERVER INIT ###
def init(:init_args) do
{:ok, relays}
end
@relay_to_gpio %{ # rpi2b
1 => 6, # pin#31
2 => 13, # pin#33
3 => 19, # pin#35
4 => 26, # pin#37
}
defp relays do
@relay_to_gpio
|> Enum.map(fn {relay, gpio} -> {relay, init_gpio(gpio)} end)
|> Enum.into(%{})
end
defp init_gpio(gpio) do
{:ok, pid} = Gpio.start_link(gpio, :output)
Gpio.write(pid, 0)
pid
end
### SERVER CALLBACKS ###
def handle_cast({io, relay_num}, relays) when io in [:on, :off] do
set(relays[relay_num], io)
{:noreply, relays}
end
defp set(relay, :on), do: Gpio.write(relay, 1)
defp set(relay, :off), do: Gpio.write(relay, 0)
end
defmodule RelayTest do
require Integer
alias RPi.GPIO.RelayController
def roll(relays, opts \\ [times: 1, pause: 100]) do
for i <- 1..opts[:times] do
for relay_num <- 1..4 do
on_or_off = if Integer.is_even(i), do: :on, else: :off
apply RelayController, on_or_off, [relays, relay_num]
:timer.sleep opts[:pause]
end
end
end
end
{:ok, relays} = RPi.GPIO.RelayController.start_link
RelayTest.roll relays, times: 6, pause: 100
RelayTest.roll relays, times: 6, pause: 50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment