Cirkit Designer LogoCirkit DesignerYour all-in-one circuit design IDE Launch Cirkit Designer App

Arduino UNO and Nano-Based Wireless Joystick-Controlled Robot with NRF24L01

View and Edit Project In Cirkit DesignerImage of Arduino UNO and Nano-Based Wireless Joystick-Controlled Robot with NRF24L01

Circuit Documentation

Summary

This circuit is designed to control two hobby gear motors using an Arduino UNO and an L298N motor driver. The control signals for the motors are received wirelessly via an NRF24L01 module, which communicates with another Arduino Nano equipped with a joystick module. The Arduino Nano reads the joystick's position and transmits the data to the Arduino UNO, which then adjusts the motor speeds accordingly.

Component List

  1. Arduino UNO

    • Description: A microcontroller board based on the ATmega328P.
    • Pins: UNUSED, IOREF, Reset, 3.3V, 5V, GND, Vin, A0, A1, A2, A3, A4, A5, SCL, SDA, AREF, D13, D12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0
  2. L298N DC Motor Driver

    • Description: A dual H-bridge motor driver that allows control of two DC motors.
    • Pins: OUT1, OUT2, 12V, GND, 5V, OUT3, OUT4, 5V-ENA-JMP-I, 5V-ENA-JMP-O, +5V-J1, +5V-J2, ENA, IN1, IN2, IN3, IN4, ENB
  3. NRF24L01

    • Description: A 2.4GHz wireless transceiver module.
    • Pins: IRQ (not used), MOSI, CSN, VCC (3V), GND, CE, SCK, MISO
  4. 4xAA Battery Pack

    • Description: A battery pack that holds four AA batteries.
    • Pins: POS, NEG
  5. Hobby Gearmotor with 48:1 Gearbox

    • Description: A small DC motor with a 48:1 gearbox.
    • Pins: pin 1, pin 2
  6. KY-023 Dual Axis Joystick Module

    • Description: A joystick module with two potentiometers for X and Y axis control.
    • Pins: GND, +5V, VRx, VRy, SW
  7. Arduino Nano

    • Description: A small, breadboard-friendly microcontroller board based on the ATmega328P.
    • Pins: D1/TX, D0/RX, RESET, GND, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11/MOSI, D12/MISO, VIN, 5V, A7, A6, A5, A4, A3, A2, A1, A0, AREF, 3V3, D13/SCK

Wiring Details

Arduino UNO

L298N DC Motor Driver

Arduino Nano

Code Documentation

Arduino UNO Code

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

// Use valid PWM pins for enA and enB on Arduino Uno
#define enA 5   // PWM pin
#define in1 2
#define in2 3
#define enB 6   // PWM pin
#define in3 4
#define in4 7

RF24 radio(8, 9); // CE pin = 8, CSN pin = 9
const byte address[6] = "00001"; // RF24 address

// Structure to match what's sent by transmitter
struct {
  int xAxis;
  int yAxis;
} joystickData;

// Motor speed variables
int motorSpeedA = 0;
int motorSpeedB = 0;

void setup() {
  Serial.begin(9600);

  pinMode(enA, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);

  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening(); // Set as receiver
}

void loop() {
  // Check if new data is available
  if (radio.available()) {
    radio.read(&joystickData, sizeof(joystickData));
  }

  int xAxis = joystickData.xAxis;
  int yAxis = joystickData.yAxis;

  // Debug prints
  Serial.print("X: "); Serial.print(xAxis);
  Serial.print(" | Y: "); Serial.println(yAxis);

  // ======= Y-Axis Control (Forward/Backward) =======
  if (yAxis < 470) {
    // Backward
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
    // Map Y-axis from [470..0] to [0..255]
    motorSpeedA = map(yAxis, 470, 0, 0, 255);
    motorSpeedB = map(yAxis, 470, 0, 0, 255);
  } 
  else if (yAxis > 550) {
    // Forward
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);
    // Map Y-axis from [550..1023] to [0..255]
    motorSpeedA = map(yAxis, 550, 1023, 0, 255);
    motorSpeedB = map(yAxis, 550, 1023, 0, 255);
  } 
  else {
    // Stop
    motorSpeedA = 0;
    motorSpeedB = 0;
  }

  // ======= X-Axis Control (Left/Right) =======
  if (xAxis < 470) {
    // Move left
    int xMapped = map(xAxis, 470, 0, 0, 255);
    motorSpeedA = motorSpeedA - xMapped; // Decrease left motor speed
    motorSpeedB = motorSpeedB + xMapped; // Increase right motor speed
    // Constrain the range to [0..255]
    if (motorSpeedA < 0)  motorSpeedA = 0;
    if (motorSpeedB > 255) motorSpeedB = 255;
  } 
  else if (xAxis > 550) {
    // Move right
    int xMapped = map(xAxis, 550, 1023, 0, 255);
    motorSpeedA = motorSpeedA + xMapped; // Increase left motor speed
    motorSpeedB = motorSpeedB - xMapped; // Decrease right motor speed
    // Constrain the range to [0..255]
    if (motorSpeedA > 255) motorSpeedA = 255;
    if (motorSpeedB <