L298N Motor Driver Library

Hex.pmDocumentation

An Elixir library for controlling L298N dual H-bridge motor driver via GPIO. This library provides a high-level interface for motor control with PWM speed control and direction management using the Pigpiox library.

Features

Hardware Requirements

Hardware Wiring

Connect your L298N module to your Raspberry Pi GPIO pins:

L298N Pin Function Raspberry Pi GPIO Description
IN1 Motor A Dir 1 Any GPIO pin Motor A direction control
IN2 Motor A Dir 2 Any GPIO pin Motor A direction control
ENA Motor A Enable PWM capable GPIO Motor A speed control (PWM)
IN3 Motor B Dir 1 Any GPIO pin Motor B direction control
IN4 Motor B Dir 2 Any GPIO pin Motor B direction control
ENB Motor B Enable PWM capable GPIO Motor B speed control (PWM)

Example Wiring

L298N -> Raspberry Pi
IN1   -> GPIO 21
IN2   -> GPIO 20
ENA   -> GPIO 18 (PWM)
IN3   -> GPIO 16
IN4   -> GPIO 12
ENB   -> GPIO 13 (PWM)

Installation

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

def deps do
  [
    {:l298n, "~> 0.1.0"}
  ]
end

Usage

Basic Setup

# Start the L298N driver with your pin configuration
{:ok, pid} = L298n.start_link([
  motor_a: %{in1: 21, in2: 20, en: 18},
  motor_b: %{in1: 16, in2: 12, en: 13}
])

Motor Control

# Move both motors forward at 50% speed
L298n.set_motors(50, 50)

# Turn left (motor A forward, motor B backward)
L298n.set_motors(30, -30)

# Control motors individually
L298n.set_motor_a(75)    # Motor A forward at 75%
L298n.set_motor_b(-60)   # Motor B backward at 60%

# Stop all motors
L298n.stop_all()

# Check current motor speeds
speeds = L298n.get_motor_speeds()
# => %{motor_a: 0, motor_b: 0}

Speed Values

Motor speed is specified as a percentage from -100 to 100:

Single Motor Configuration

You can configure only one motor if needed:

# Configure only Motor A
{:ok, pid} = L298n.start_link([
  motor_a: %{in1: 21, in2: 20, en: 18}
])

L298n.set_motor_a(50)  # Only Motor A will move
L298n.set_motors(30, 75)  # Motor A: 30%, Motor B: ignored (not configured)

Supervision

For production use, add L298n to your supervision tree:

defmodule MyApp.Application do
  use Application

  def start(_type, _args) do
    children = [
      {L298n, [
        motor_a: %{in1: 21, in2: 20, en: 18},
        motor_b: %{in1: 16, in2: 12, en: 13},
        name: MyApp.MotorDriver
      ]}
    ]

    opts = [strategy: :one_for_one, name: MyApp.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

API Reference

Core Functions

Error Handling

The library includes comprehensive input validation:

# These will raise FunctionClauseError
L298n.set_motors(101, 0)    # Speed > 100
L298n.set_motors(0, -101)   # Speed < -100
L298n.set_motor_a("fast")   # Non-integer speed

Dependencies

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Troubleshooting

Common Issues

Motors not responding:

Permission errors:

PWM not working:

Debug Mode

Enable debug logging to troubleshoot issues:

# In config/config.exs
config :logger, level: :debug