4-Wheel Drive Car Project with NRF24L01 Communication, HC-SR04 Obstacle Detection, and L298N Motor Driver Issues

Hello,

I’m currently working on a 4-wheel drive car project using an Arduino setup and I’ve run into a few issues that I could really use some advice on. The car is intended to be controlled wirelessly using the NRF24L01 module, with obstacle detection managed by two HC-SR04 ultrasonic sensors and the motors driven by an L298N motor driver.

Here’s a breakdown of my setup:

Project Setup:

Transmitter Arduino (Sender) – Arduino Uno:

  • Buttons: 4 buttons for controlling the car's movement (left, right, forward, backward) connected to pins 2, 3, 4, and 5.
  • LCD Display: 16x2 I2C LCD for displaying sensor readings and movement status.
  • Wireless Communication: NRF24L01 module connected (CE pin to 7, CSN pin to 8).

Receiver Arduino (Car) – Arduino Mega 2560:

  • Motor Control: L298N motor driver controlling 4 motors (connected to pins 22, 23, 24, 25).
  • Obstacle Detection: 2 HC-SR04 ultrasonic sensors (front: trig on pins 2, echo on pins 3; back: trig on pins 4, echo on pins 5).
  • Wireless Communication: NRF24L01 module (CE pin to 7, CSN pin to 8, and the SPI pins connected to the Mega).
  • Motor Library: I’m using a custom library to control the motors (found here).

Issues I’m Facing:

  1. Communication Issues:
  • My NRF24L01 modules are not transmitting/receiving reliably.
  • The transmitter seems to send data, but the receiver is having trouble reading it. Even though the wiring and libraries seem correct, I’m getting compiler errors and unreliable behavior.
  • When I try to read data from the receiver side, it seems like the module just doesn’t acknowledge the incoming data.
  1. Obstacle Detection Not Stopping the Car:
  • I’ve set up the two HC-SR04 sensors to detect obstacles, but the car doesn’t stop when an obstacle is detected.
  • The sensors sometimes return a 0 cm reading, which I suspect is a false value, and I’m not sure how to handle it.
  • I’ve tried filtering out false readings, but nothing seems to be working properly.
  1. Voltage Concerns:
  • I’m using the NRF24L01 with the long antenna, but I’m not sure whether it’s a 3.3V or 5V module.
  • Some forums suggest using level shifters or voltage dividers, but I’m not sure if I need to adjust my power setup.

What I’ve Tried:

  • Double-checking the wiring several times to ensure everything is correct.
  • Ensuring proper power supply (I’m using a 3.3V regulator for the NRF24L01).
  • Using non-blocking delays with millis() for smooth operation on the car and transmitter.
  • Changing the NRF24L01 address and channel settings to improve communication.
  • Applying a voltage divider to the HC-SR04 ultrasonic sensors and ensuring proper communication.

My Questions:

  1. NRF24L01 Communication:
  • Has anyone had issues with NRF24L01 communication not working, even though the wiring seems correct? Are there any tips for ensuring the receiver works as expected? Should I use a different library or tweak some settings to get better results?
  1. HC-SR04 Sensor Handling:
  • How do I handle the issue of the HC-SR04 sensor returning a 0 cm reading? I’m looking for a way to filter out false readings and prevent the car from acting on them.
  • What is the best way to improve the reliability of the sensors in such a setup?
  1. Power Setup for NRF24L01:
  • Does the NRF24L01 module require any special power setup? I’ve seen conflicting advice about whether it needs 3.3V or 5V. Could this be the root cause of the communication issues?
  1. Smooth Movement Control:
  • I’d like to get smooth movement control and reliable wireless communication. Any advice on how to achieve this in a 4-wheel drive car setup with NRF24L01, HC-SR04, and L298N?

Code (Transmitter):

#include <SPI.h>
#include <RF24.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Pin definitions for buttons
const int leftButtonPin = 2;
const int rightButtonPin = 3;
const int forwardButtonPin = 4;
const int backwardButtonPin = 5;

// LCD setup
LiquidCrystal_I2C lcd(0x27, 16, 2);  // I2C address 0x27, 16x2 LCD

// NRF24L01 setup
RF24 radio(7, 8);  // CE pin 7, CSN pin 8

void setup() {
  // Initialize Serial Monitor for debugging
  Serial.begin(9600);

  // Initialize the LCD
  lcd.begin();
  lcd.print("Transmitter");

  // Set button pins as INPUT
  pinMode(leftButtonPin, INPUT);
  pinMode(rightButtonPin, INPUT);
  pinMode(forwardButtonPin, INPUT);
  pinMode(backwardButtonPin, INPUT);

  // Initialize NRF24L01 communication
  radio.begin();
  radio.openWritingPipe(0xF0F0F0F0E1LL);  // Receiver address
  radio.setPALevel(RF24_PA_HIGH);  // Set transmission power
  radio.setChannel(108);  // Set frequency channel

  // Display message on LCD
  lcd.setCursor(0, 1);
  lcd.print("Ready to send!");
}

void loop() {
  // Read button states
  int leftButtonState = digitalRead(leftButtonPin);
  int rightButtonState = digitalRead(rightButtonPin);
  int forwardButtonState = digitalRead(forwardButtonPin);
  int backwardButtonState = digitalRead(backwardButtonPin);

  // Send data based on button press
  if (leftButtonState == HIGH) {
    sendMovementCommand("LEFT");
  } else if (rightButtonState == HIGH) {
    sendMovementCommand("RIGHT");
  } else if (forwardButtonState == HIGH) {
    sendMovementCommand("FORWARD");
  } else if (backwardButtonState == HIGH) {
    sendMovementCommand("BACKWARD");
  } else {
    sendMovementCommand("STOP");
  }

  // Update LCD display
  updateLCD();

  // Small delay for button debounce
  delay(100);
}

void sendMovementCommand(const char* command) {
  radio.write(command, sizeof(command));  // Send command to receiver
}

void updateLCD() {
  lcd.clear();
  lcd.print("Send command");
  lcd.setCursor(0, 1);
  lcd.print("Forward/Back");
}

Code (Car-side):

#include <SPI.h>
#include <RF24.h>
#include <LiquidCrystal_I2C.h>
#include <L298N.h>

// Pin definitions for motor control (L298N)
const int motorA1 = 2;
const int motorA2 = 3;
const int motorB1 = 4;
const int motorB2 = 5;

// NRF24L01 setup
RF24 radio(6, 7);  // CE pin 6, CSN pin 7

// HC-SR04 sensor pins
const int trigPinFront = A0;
const int echoPinFront = A1;
const int trigPinBack = 8;
const int echoPinBack = 9;

// Initialize LCD (if needed)
LiquidCrystal_I2C lcd(0x27, 16, 2);  // I2C address 0x27, 16x2 LCD

// Initialize L298N motor driver
L298N motor(motorA1, motorA2, motorB1, motorB2);

void setup() {
  // Initialize Serial Monitor for debugging
  Serial.begin(9600);

  // Initialize LCD
  lcd.begin();
  lcd.print("Receiver");

  // Set sensor pins
  pinMode(trigPinFront, OUTPUT);
  pinMode(echoPinFront, INPUT);
  pinMode(trigPinBack, OUTPUT);
  pinMode(echoPinBack, INPUT);

  // Initialize NRF24L01 communication
  radio.begin();
  radio.openReadingPipe(1, 0xF0F0F0F0E1LL);  // Address should match transmitter
  radio.setPALevel(RF24_PA_HIGH);
  radio.setChannel(108);  // Set channel to match transmitter
  radio.startListening();

  // Motor stop initially
  motor.stop();
}

void loop() {
  // Check if data is available from the transmitter
  if (radio.available()) {
    char receivedData[32] = "";
    radio.read(&receivedData, sizeof(receivedData));  // Read incoming data

    // Display received data on LCD
    lcd.clear();
    lcd.print("Command: ");
    lcd.print(receivedData);

    // Check obstacle detection
    if (isObstacleDetected()) {
      motor.stop();  // Stop if obstacle is detected
      lcd.setCursor(0, 1);
      lcd.print("Obstacle detected!");
    } else {
      // Move car based on received command
      if (strcmp(receivedData, "FORWARD") == 0) {
        motor.driveFWD();  // Move forward
      } else if (strcmp(receivedData, "BACKWARD") == 0) {
        motor.driveRVS();  // Move backward
      } else if (strcmp(receivedData, "LEFT") == 0) {
        motor.driveLEFT();  // Turn left
      } else if (strcmp(receivedData, "RIGHT") == 0) {
        motor.driveRIGHT();  // Turn right
      } else if (strcmp(receivedData, "STOP") == 0) {
        motor.stop();  // Stop the car
      }
    }
  }
}

// Function to measure distance using HC-SR04
long measureDistance(int trigPin, int echoPin) {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  long duration = pulseIn(echoPin, HIGH);
  long distance = duration * 0.034 / 2;  // Distance in cm

  return distance;
}

// Function to check if any obstacle is detected
bool isObstacleDetected() {
  long frontDistance = measureDistance(trigPinFront, echoPinFront);
  long backDistance = measureDistance(trigPinBack, echoPinBack);

  // Check if the distance is below threshold (e.g., 20 cm)
  if (frontDistance < 20 || backDistance < 20) {
    return true;  // Obstacle detected
  }

  return false;  // No obstacle
}

Conclusion:

I’d really appreciate any advice or help from the community to get this project on track! The car is almost there, but I’m struggling with the communication and obstacle detection issues. If anyone has used a similar setup or faced similar challenges, I’d love to hear your thoughts.

Thanks in advance for your time and help!

Update: I changed the Mega for a Uno for the suitability And here's the updated pins: IN1-4 2-5, NRF CE CSN 6-7 Front HCSR04 Trig and echo: A0-A1 Back HCSR04 :8-9

Skip the communication for the moment and go for the obstacle detection making it work.
Please cook down the text into schematics. Pin numbers are no good.

Let me make a schematic on tinkercad didn't realise i needed a schematic, sorry!

I did my best at recreating it

For the NRF24L01 issues, I’d recommend making sure you're using a dedicated 3.3V regulator, not just the 5V from the Arduino. Sometimes the module doesn’t play nice with 5V, even with a level shifter. Also, make sure you're not overloading the module’s power supply, try adding a capacitor (around 10uF) between VCC and GND to smooth things out. As for the HC-SR04, a common trick to avoid 0 cm readings is to add a small delay between measurements, like 50ms.

1 Like

Do also need to pretend there are a couple of SR04s an LCD and a 3.3V regulator, and a power supply?

Sorry but the same no good. I step aside.

i tried my best atleast :frowning: did you try sarcasm

ooh a good reply finally!

I'm just trying to point out that you diagram does not convey any usefull information as to whether you actually have things connected correctly.

The code means nothing without a proper schematic.

I'm pretty sure i connected the pins correctly but after Iftar i'll redo the wiring and i'll inform you

Did the NRF devices work properly BEFORE you put it in the car?

You are complaining about all the free help you have been getting?

no, it didn't

The other ones i've been talking about didn't help with the problem directly

But you put in the car anyway?

i was hoping that this was the one that worked. I had 1 pair not work. i was really hoping. And it can't be broken i bought 2 pairs and those 2 pairs can't be broken in a row

If rated operating voltage is 3-3.6V you can easily fry them with 5V.

I put 3.3V at the VCC (top-left, 2nd pin) but still used 5V communication logic

Then that's not the problem.
I see you had doubts about correct operating voltage on your OP.