This project for Build It Challenge 2022 involves a RC car controlled by two Arduino boards (Master and Slave), which communicate via Bluetooth. The system operates in two modes:
- Manual Mode: Controlled by an analog joystick connected to the Master Arduino.
- Autonomous Mode: The car follows a black tape on a white surface using IR sensors and avoids obstacles using a proximity sensor.
The Master Arduino controls the overall mode (manual or automatic) and sends joystick data to the Slave Arduino when in manual mode. The Slave Arduino uses the joystick data to drive the motors and control the steering (servo), and in automatic mode, it uses sensors to make decisions autonomously.
/lane-cruiser
│
├── /master # Controller code (master arduino)
│ ├── analog_joystick.h # Header file for joystick class
│ ├── analog_joystick.cpp # Source code for joystick logic
│ └── master.ino # Main code for the master arduino
│
├── /simulation
│ ├── analog_joystick.h # Header file for joystick class
│ ├── analog_joystick.cpp # Source code for joystick logic
│ ├── dc_motor.h # Header file for motor class
│ ├── dc_motor.cpp # Source file for motor logic
│ ├── infrared_proximity_sensor.h # Header file for ir sensor class
│ ├── infrared_proximity_sensor.cpp # Source code for ir sensor logic
│ ├── README.md # Documentation for CirkitDesigner project
│ ├── simulation.ino # Main code for the simulation
│ ├── ultrasonic_sensor.h # Header file for proximity sensor class
│ └── ultrasonic_sensor.cpp # Source code for proximity sensor class
│
├── /slave # RC car code (slave arduino)
│ ├── dc_motor.h # Header file for motor class
│ ├── dc_motor.cpp # Source file for motor logic
│ ├── infrared_proximity_sensor.h # Header file for ir sensor class
│ ├── infrared_proximity_sensor.cpp # Source code for ir sensor logic
│ ├── slave.ino # Main code for the slave arduino
│ ├── ultrasonic_sensor.h # Header file for proximity sensor class
│ └── ultrasonic_sensor.cpp # Source code for proximity sensor class
│
└── README.md
The files are mainly organised as follows:
- analog_joystick.cpp: This file contains the implementation for handling the analog joystick input. It simulates reading the joystick’s X and Y axis values and processes them into control signals for the RC car’s movement in manual mode.
- analog_joystick.h: The header file for the analog_joystick.cpp implementation. It defines the functions and data structures necessary for handling joystick input.
- dc_motor.cpp: This file contains the code to simulate the behavior of the DC motors used in the RC car. It includes functions to control the motor's speed and direction.
- dc_motor.h: The header file for the dc_motor.cpp implementation. It defines the functions and constants related to motor control.
- infrared_proximity.cpp: This file simulates the infrared proximity sensor used for obstacle detection. The sensor is used in automated mode to follow lines on the ground.
- infrared_proximity.h: The header file for the infrared_proximity.cpp implementation. It defines the proximity sensor's interface for reading line-following (colour) status.
To get started with the project, ensure you have the following:
- 2x Arduino boards (Arduino Uno or similar)
- 2x Bluetooth modules (HC-05)
- 1x Analog joystick
- 1x Servo (for steering control)
- 2x DC motor (for driving the wheels)
- 2x IR sensors (LDR)
- 1x Proximity sensor (HC-SR04)
- 1x Motor Controller
- 1x RC car chassis (see article for inspiration)
See article to configure bluetooth modules in AT mode to enable communication.
- Arduino IDE (or similar) to compile and upload code to the boards
- CirkitDesigner (optional) to simulate car behaviour as in /simulation
The project employs a combination of car and tank-like drive using a single joystick with x/y = [-1, 1]:
// tank-like control (in-place spin)
float left = y + x;
float right = y - x;
// car-like control
float left = y + x * abs(y);
float right = y - x * abs(y);
// car+tank mode
float spin_weight = 0.0 // 0 = car, 1 = tank
float left = y + x * (spin_weight + (1 - spin_weight) * abs(y));
float right = y - x * (spin_weight + (1 - spin_weight) * abs(y));