README.md

# L298N Motor Driver Library

[![Hex.pm](https://img.shields.io/hexpm/v/l298n.svg)](https://hex.pm/packages/l298n)
[![Documentation](https://img.shields.io/badge/docs-hexdocs-purple.svg)](https://hexdocs.pm/l298n/)

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 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`:

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

## Usage

### Basic Setup

```elixir
# 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

```elixir
# 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:

```elixir
# 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:

```elixir
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

- `L298n.start_link/1` - Start the motor driver process
- `L298n.set_motors/2` - Control both motors simultaneously
- `L298n.set_motor_a/1` - Control motor A only
- `L298n.set_motor_b/1` - Control motor B only
- `L298n.stop_all/0` - Stop all motors immediately
- `L298n.get_motor_speeds/0` - Get current motor speed settings

### Error Handling

The library includes comprehensive input validation:

```elixir
# 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](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:

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