L298N Motor Driver Library

View Source

Hex.pm Documentation

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

  • ✅ Control up to 2 DC motors independently
  • ✅ PWM speed control (0-100% in both directions)
  • ✅ Safe motor stopping with graceful shutdown
  • ✅ GenServer-based process for reliable state management
  • ✅ Comprehensive error handling and validation
  • ✅ Extensive documentation and examples

Hardware Requirements

  • Raspberry Pi (or compatible GPIO device)
  • L298N dual H-bridge motor driver module
  • DC motors (up to 2)
  • Proper power supply for motors

Hardware Wiring

Connect your L298N module to your Raspberry Pi GPIO pins:

L298N PinFunctionRaspberry Pi GPIODescription
IN1Motor A Dir 1Any GPIO pinMotor A direction control
IN2Motor A Dir 2Any GPIO pinMotor A direction control
ENAMotor A EnablePWM capable GPIOMotor A speed control (PWM)
IN3Motor B Dir 1Any GPIO pinMotor B direction control
IN4Motor B Dir 2Any GPIO pinMotor B direction control
ENBMotor B EnablePWM capable GPIOMotor 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:

  • Positive values (1 to 100): Forward direction
  • Negative values (-1 to -100): Backward direction
  • 0: Stop motor
  • ±100: Full speed

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

  • pigpiox - GPIO control for Raspberry Pi
  • ex_doc - Documentation generation (dev only)

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:

  • Check wiring connections
  • Verify GPIO pin numbers in configuration
  • Ensure adequate power supply for motors
  • Check that pigpiod daemon is running

Permission errors:

  • Ensure your user has GPIO access permissions
  • Run with appropriate privileges if needed

PWM not working:

  • Verify EN pins are connected to PWM-capable GPIO pins
  • Check that pins aren't already in use by other processes

Debug Mode

Enable debug logging to troubleshoot issues:

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