Skip to content

sid2baker/sm_4rel4in

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SM4rel4in

Elixir library for Sequent Microsystems SM4rel4in HAT - a 4-relay/4-input stackable HAT for Raspberry Pi.

Features

  • 4 x Relay Outputs: SPDT relays, 8A/250VAC, 5A/30VDC
  • 4 x Universal Inputs: Digital, AC detection, pulse counting, PWM measurement
  • 2 x Quadrature Encoders: Using input pairs 1-2 and 3-4
  • Current Measurement: For relay outputs
  • 4 x Configurable LEDs: Auto (follow input) or manual mode
  • Stackable: Up to 8 boards with I2C addressing
  • Interrupt Support: GPIO interrupt-driven updates via Circuits.GPIO

Installation

Add sm_4rel4in to your list of dependencies in mix.exs:

def deps do
  [
    {:sm_4rel4in, "~> 1.0.0"},
    {:circuits_i2c, "~> 2.0"},
    {:circuits_gpio, "~> 2.0"}
  ]
end

Quick Start

# Start the server (stack level 0, interrupt on GPIO 4)
{:ok, pid} = SM4rel4in.start_link(stack: 0, interrupt_pin: 4)

# Control relays
SM4rel4in.set_relay(1, true)   # Turn on relay 1
SM4rel4in.set_all_relays(15)   # Turn on all relays (binary 1111)

# Read inputs
{:ok, state} = SM4rel4in.get_digital_input(1)
{:ok, bitmap} = SM4rel4in.get_all_digital_inputs()

# Enable pulse counting
SM4rel4in.set_counting_enabled(1, true)
{:ok, count} = SM4rel4in.get_pulse_count(1)

# Subscribe to changes
SM4rel4in.subscribe()
# Receive: {:sm4rel4in_change, stack_level, changes}

Configuration

Supervision Tree

For production applications, add to your supervision tree:

children = [
  {SM4rel4in, [stack: 0, interrupt_pin: 4, name: :sm4rel4in]}
]

Supervisor.start_link(children, strategy: :one_for_one)

Multiple HATs

Stack multiple HATs with different stack levels:

children = [
  {SM4rel4in, [stack: 0, interrupt_pin: 4, name: :hat_0]},
  {SM4rel4in, [stack: 1, interrupt_pin: 17, name: :hat_1]},
  {SM4rel4in, [stack: 2, interrupt_pin: 27, name: :hat_2]}
]

API Reference

Relay Control

# Single relay control
SM4rel4in.set_relay(server, relay, state)
{:ok, state} = SM4rel4in.get_relay(server, relay)

# All relays (bitmap: bit 0 = relay 1, bit 1 = relay 2, etc.)
SM4rel4in.set_all_relays(server, 0b1010)  # Relays 2&4 on
{:ok, bitmap} = SM4rel4in.get_all_relays(server)

Digital Inputs

# Single input
{:ok, state} = SM4rel4in.get_digital_input(server, channel)
{:ok, ac_detected} = SM4rel4in.get_ac_input(server, channel)

# All inputs
{:ok, bitmap} = SM4rel4in.get_all_digital_inputs(server)
{:ok, ac_bitmap} = SM4rel4in.get_all_ac_inputs(server)

PWM Measurement

{:ok, frequency_hz} = SM4rel4in.get_frequency(server, channel)
{:ok, duty_cycle_percent} = SM4rel4in.get_pwm_fill(server, channel)
{:ok, pulses_per_second} = SM4rel4in.get_pulse_rate(server, channel)

Pulse Counting

# Enable/disable counting
SM4rel4in.set_counting_enabled(server, channel, true)
{:ok, enabled} = SM4rel4in.get_counting_enabled(server, channel)

# Read and reset counters
{:ok, count} = SM4rel4in.get_pulse_count(server, channel)
SM4rel4in.reset_pulse_count(server, channel)

Quadrature Encoders

# Enable encoder (channel 1 = inputs 1&2, channel 2 = inputs 3&4)
SM4rel4in.set_encoder_enabled(server, encoder_channel, true)

# Read encoder (signed 32-bit, positive/negative for direction)
{:ok, count} = SM4rel4in.get_encoder_count(server, encoder_channel)
SM4rel4in.reset_encoder_count(server, encoder_channel)

Current Measurement

# Read relay output currents
{:ok, current_a} = SM4rel4in.get_current(server, relay_channel)
{:ok, rms_current_a} = SM4rel4in.get_rms_current(server, relay_channel)

LED Control

# Set LED mode
SM4rel4in.set_led_mode(server, led, :auto)    # Follow input state
SM4rel4in.set_led_mode(server, led, :manual)  # Software control

# Control LEDs (manual mode only)
SM4rel4in.set_led(server, led, true)
SM4rel4in.set_all_leds(server, 0b1010)  # LEDs 2&4 on

Change Notifications

# Subscribe to all changes
SM4rel4in.subscribe(server)

# In your process, receive messages:
receive do
  {:sm4rel4in_change, stack_level, changes} ->
    # changes = [{:digital_inputs, old_map, new_map}, ...]
    IO.inspect(changes)
end

Hardware Setup

I2C Configuration

Enable I2C on your Raspberry Pi:

sudo raspi-config  # Interface Options -> I2C -> Enable

Stack Level Configuration

Set the stack level using jumpers on the HAT:

  • Stack 0: No jumpers
  • Stack 1: A0 jumper
  • Stack 2: A1 jumper
  • Stack 3: A0 + A1 jumpers
  • etc.

Interrupt Pin

Connect the interrupt pin from the HAT to a GPIO pin on your Raspberry Pi for real-time updates.

Architecture

The library consists of several modules:

  • SM4rel4in: Main API module
  • SM4rel4in.Server: GenServer managing HAT state and interrupts
  • SM4rel4in.Relays: Relay control functions
  • SM4rel4in.Inputs: Input reading functions
  • SM4rel4in.Counters: Pulse counting functions
  • SM4rel4in.Encoders: Quadrature encoder functions
  • SM4rel4in.LEDs: LED control functions
  • SM4rel4in.I2C: Low-level I2C communication
  • SM4rel4in.Registers: Register definitions and validation

Example Application

defmodule MyApp.HAT do
  use GenServer
  
  def start_link(opts) do
    GenServer.start_link(__MODULE__, opts, name: __MODULE__)
  end
  
  def init(_opts) do
    # Start HAT server
    {:ok, _pid} = SM4rel4in.start_link(stack: 0, interrupt_pin: 4)
    
    # Subscribe to changes
    SM4rel4in.subscribe()
    
    # Enable pulse counting on input 1
    SM4rel4in.set_counting_enabled(1, true)
    
    {:ok, %{}}
  end
  
  def handle_info({:sm4rel4in_change, _stack, changes}, state) do
    # Handle input changes
    Enum.each(changes, fn
      {:digital_inputs, _old, new} ->
        # React to digital input changes
        if Map.get(new, 1) == 1 do
          SM4rel4in.set_relay(1, true)  # Turn on relay 1
        else
          SM4rel4in.set_relay(1, false)
        end
        
      {:pulse_counts, _old, new} ->
        # Log pulse count changes
        Logger.info("Pulse count updated: #{inspect(new)}")
        
      _ ->
        :ok
    end)
    
    {:noreply, state}
  end
end

License

MIT

Links

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages