Arduino Nano Controlled Wireless Robot with NRF24L01 and L298N Motor Driver
View and Edit Project In Cirkit Designer
Circuit Documentation
Summary
This circuit is designed to control a robot with two DC motors using an L298N motor driver. It features wireless communication capabilities through an NRF24L01 module, allowing the robot to receive commands such as moving forward, backward, turning, stopping, and returning to its origin by retracing its steps. The Arduino Nano serves as the central microcontroller, interfacing with the motor driver and the wireless module. Power is supplied by a 4 x AAA battery mount.
Component List
Arduino Nano
- Microcontroller board based on the ATmega328P.
- It has a variety of digital and analog I/O pins for interfacing with various components.
NRF24L01
- A 2.4GHz wireless transceiver module.
- It allows for wireless communication between devices.
L298N DC Motor Driver
- A dual H-bridge motor driver.
- It can drive two DC motors or one stepper motor.
4 x AAA Battery Mount
- A battery holder for four AAA batteries.
- It provides power to the circuit.
Hobby Gearmotor with 48:1 Gearbox (x2)
- A DC motor with a gearbox for increased torque.
- Used to drive the wheels of the robot.
Wiring Details
Arduino Nano
- D2 to L298N IN1
- D3 to L298N IN2
- D4 to L298N IN3
- D5 to L298N IN4
- D6 to L298N ENA
- D7 to L298N ENB
- D9 to NRF24L01 CE
- D10 to NRF24L01 CSN
- D11/MOSI to NRF24L01 MOSI
- D12/MISO to NRF24L01 MISO
- D13/SCK to NRF24L01 SCK
- GND to L298N GND, NRF24L01 GND, and Battery Mount -
- VIN to L298N 12V
- 3V3 to NRF24L01 VCC (3V)
NRF24L01
- CE to Arduino Nano D9
- CSN to Arduino Nano D10
- MOSI to Arduino Nano D11/MOSI
- MISO to Arduino Nano D12/MISO
- SCK to Arduino Nano D13/SCK
- VCC (3V) to Arduino Nano 3V3
- GND to Arduino Nano GND
L298N DC Motor Driver
- IN1 to Arduino Nano D2
- IN2 to Arduino Nano D3
- IN3 to Arduino Nano D4
- IN4 to Arduino Nano D5
- ENA to Arduino Nano D6
- ENB to Arduino Nano D7
- GND to Arduino Nano GND
- 12V to Arduino Nano VIN
- OUT1 to Gearmotor (Motor A) pin 2
- OUT2 to Gearmotor (Motor A) pin 1
- OUT3 to Gearmotor (Motor B) pin 2
- OUT4 to Gearmotor (Motor B) pin 1
4 x AAA Battery Mount
- + to Arduino Nano VIN and L298N 12V
- - to Arduino Nano GND
Hobby Gearmotor with 48:1 Gearbox (Motor A)
- pin 1 to L298N OUT2
- pin 2 to L298N OUT1
Hobby Gearmotor with 48:1 Gearbox (Motor B)
- pin 1 to L298N OUT4
- pin 2 to L298N OUT3
Documented Code
/*
* This Arduino sketch controls a robot with two motors using an L298N driver
* and an NRF24L01 module for wireless communication. The robot can move
* forward, backward, turn left, turn right, and stop based on commands
* received wirelessly. It also has a feature to return to its origin by
* retracing its steps.
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
// Motor control pins
const int IN1 = 2;
const int IN2 = 3;
const int ENA = 6; // PWM for Motor A
const int IN3 = 4;
const int IN4 = 5;
const int ENB = 7; // PWM for Motor B
RF24 radio(9, 10); // NRF24L01 CE, CSN pins
const byte address[6] = "00001";
// Commands from the transmitter
enum Commands {
FORWARD,
BACKWARD,
LEFT,
RIGHT,
STOP,
RETURN_TO_ORIGIN
};
// Variables for tracking path and command
Commands command = STOP;
Commands path[100]; // Array to store movement commands for dead reckoning
int pathIndex = 0; // Tracks path storage index
bool returnToOrigin = false;
void setup() {
// Set motor pins as outputs
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(ENB, OUTPUT);
// NRF24L01 setup
radio.begin();
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_LOW);
radio.startListening();
}
void loop() {
// Check if a command is received
if (radio.available()) {
radio.read(&command, sizeof(command));
// If not in return-to-origin mode, store the command in path
if (!returnToOrigin && command != RETURN_TO_ORIGIN) {
path[pathIndex++] = command; // Store command
if (pathIndex >= 100) pathIndex = 99; // Prevent overflow
}
// Trigger return to origin if commanded
if (command == RETURN_TO_ORIGIN) {
returnToOrigin = true;
pathIndex--; // Set to last command position
}
}
// Execute the current command or start return-to-origin sequence
if (!returnToOrigin) {
executeCommand(command); // Normal driving mode
} else {
returnToOriginSequence(); // Retracing path to origin
}
}
// Function to execute a command
void executeCommand(Commands cmd) {
switch (cmd) {
case FORWARD:
driveForward();
break;
case BACKWARD:
driveBackward();
break;
case LEFT:
turnLeft();
break;
case RIGHT:
turnRight();
break;
case STOP:
stopMotors();
break;
}
}
// Function to retrace steps back to origin
void returnToOriginSequence() {
if (pathIndex >= 0) {
// Execute the opposite of each command in reverse order
switch (path[pathIndex--]) {
case FORWARD:
driveBackward();
break;
case BACKWARD:
driveForward();
break;
case LEFT:
turnRight();
break;
case RIGHT:
turnLeft();
break;
case STOP:
stopMotors();
break;
}
} else {
// Reached origin; reset state
stopMotors();
returnToOrigin = false;
pathIndex = 0; // Reset path index for future tracking
}
}
// Movement functions for tank-style control
void driveForward() {
analogWrite(ENA, 255); // Full speed for Motor A
analogWrite(ENB, 255); // Full speed for Motor B
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
void driveBackward() {
analogWrite(ENA, 255); // Full speed for Motor A
analogWrite(ENB, 255); // Full speed for Motor B
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
}
void turnLeft() {
analogWrite(ENA, 100); // Reduce speed for inner wheel
analogWrite(ENB, 255); // Full speed for outer wheel
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
void turnRight() {
analogWrite(ENA, 255); // Full speed for outer wheel
analogWrite(ENB, 100); // Reduce speed for inner wheel
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
void stopMotors() {
analogWrite(ENA, 0);
analogWrite(ENB, 0);
}
This code is responsible for controlling the robot's movements based on wireless commands received via the NRF24L01 module. It includes functions for driving the motors forward and backward, turning left and right, stopping the motors, and a feature to return the robot to its starting position by reversing the commands it has