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:
- 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.
- 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.
- 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:
- 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?
- 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?
- 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?
- 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
