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

Arduino Nano Controlled Robotic Vehicle with L298N Driver and NRF24L01 Wireless Communication

View and Edit Project In Cirkit DesignerImage of Arduino Nano Controlled Robotic Vehicle with L298N Driver and NRF24L01 Wireless Communication

Circuit Documentation

Summary

The circuit in question is designed to control a set of DC motors using an Arduino Nano microcontroller in conjunction with an L298N DC motor driver. The system also includes an NRF24L01 module for wireless communication, allowing remote control of the motors. A Lipo battery provides the power source for the circuit. The Arduino Nano is programmed to interpret signals received from the NRF24L01 module and accordingly drive the motors via the L298N motor driver.

Component List

DC Motor

L298N DC Motor Driver

Arduino Nano

NRF24L01

Lipo Battery

Wiring Details

DC Motor

L298N DC Motor Driver

Arduino Nano

NRF24L01

Lipo Battery

Documented Code

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

//#define PRINT_DEBUG   //Uncomment this line if you want to print the values on serial monitor

#define SIGNAL_TIMEOUT 500  // This is signal timeout in milli seconds.

const uint64_t pipeIn = 0xF9E8F0F0E1LL;
RF24 radio(8, 9); 
unsigned long lastRecvTime = 0;

struct PacketData
{
  byte xAxisValue;    
  byte yAxisValue;
} receiverData;

//Right motor
int enableRightMotor=5; 
int rightMotorPin1=2;
int rightMotorPin2=3;

//Left motor
int enableLeftMotor=6;
int leftMotorPin1=4;
int leftMotorPin2=7;

void setup()
{
  pinMode(enableRightMotor,OUTPUT);
  pinMode(rightMotorPin1,OUTPUT);
  pinMode(rightMotorPin2,OUTPUT);

  pinMode(enableLeftMotor,OUTPUT);
  pinMode(leftMotorPin1,OUTPUT);
  pinMode(leftMotorPin2,OUTPUT);

  rotateMotor(0,0); 

  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.openReadingPipe(1,pipeIn);
  radio.startListening(); //start the radio receiver 

  #ifdef PRINT_DEBUG
    Serial.begin(115200);
  #endif
}

void loop()
{
    int rightMotorSpeed=0;
    int leftMotorSpeed=0;
    // Check if RF is connected and packet is available 
    if(radio.isChipConnected() && radio.available())
    {
      radio.read(&receiverData, sizeof(PacketData)); 
      int mappedYValue = map(receiverData.yAxisValue, 0, 254, -255, 255); 
      int mappedXValue = map(receiverData.xAxisValue, 0, 254, -255, 255); 
      int motorDirection = 1;     
      if (mappedYValue < 0)
      {
        motorDirection = -1;
      }

      rightMotorSpeed = abs(mappedYValue) - mappedXValue;
      leftMotorSpeed = abs(mappedYValue) + mappedXValue;

      rightMotorSpeed = constrain(rightMotorSpeed, 0, 255);
      leftMotorSpeed = constrain(leftMotorSpeed, 0, 255);

      rotateMotor(rightMotorSpeed * motorDirection, leftMotorSpeed * motorDirection);

      lastRecvTime = millis();  

      #ifdef PRINT_DEBUG  
        Serial.println(receiverData.xAxisValue);
        Serial.println(receiverData.yAxisValue);      
      #endif
    }
    else
    {
      //Signal lost. Reset the motor to stop
      unsigned long now = millis();
      if ( now - lastRecvTime > SIGNAL_TIMEOUT ) 
      {
        rotateMotor(0, 0);   
     }
   }
}

void rotateMotor(int rightMotorSpeed, int leftMotorSpeed)
{
  if (rightMotorSpeed < 0)
  {
    digitalWrite(rightMotorPin1,LOW);
    digitalWrite(rightMotorPin2,HIGH);    
  }
  else if (rightMotorSpeed > 0)
  {
    digitalWrite(rightMotorPin1,HIGH);
    digitalWrite(rightMotorPin2,LOW);      
  }
  else
  {
    digitalWrite(rightMotorPin1,LOW);
    digitalWrite(rightMotorPin2,LOW);      
  }

  if (leftMotorSpeed < 0)
  {
    digitalWrite(leftMotorPin1,LOW);
    digitalWrite(leftMotorPin2,HIGH);    
  }
  else if (leftMotorSpeed > 0)
  {
    digitalWrite(leftMotorPin1,HIGH);
    digitalWrite(leftMotorPin2,LOW);      
  }
  else
  {
    digitalWrite(leftMotorPin1,LOW);
    digitalWrite(leftMotorPin2,LOW);      
  }  

  analogWrite(enableRightMotor, abs(rightMotorSpeed));
  analogWrite(enableLeftMotor, abs(leftMotorSpeed));    
}

This code is responsible for setting up the Arduino Nano to communicate with the NRF24L01 module and control the DC motors through the L298N motor driver. It includes a structure to hold the packet data received from the NRF24L01 module, functions to initialize the system, and a loop that continuously checks for incoming data to control the motors. The rotateMotor function is used to set the direction and speed of the motors based on the received data.