Remote Control Car Using a Radio Frequency Transmitter

Overview:

This project uses a radio frequency transmitter and receiver to control a two-wheeled car from a distance (remote control). Arduino collects the signal from the receiver and turns it into information that it can make decisions about and then output motor direction and power levels.

Materials:

1 Arduino Uno

1 L298N Motor Driver Board

1 Fly Sky Receiver and Transmitter Pair

1 Robot 2-wheeled Robot Chassis with DC Motors

1 9V Battery

Wiring:

**The wiring for this project is very similar to the wiring for the object avoiding robot that you built previously, accept for the addition of the wireless receiver.

FlySky Receiver to Arduino

Use the transmitter to find which mode the sticks are in…

Hold OK 🡪 Menu 🡪 System 🡪 Sticks Mode

Notice that the entire 2nd column is 5V and the entire 3rd column is GND…

Receiver

Arduino

GND

GND

5V

5V

Channel to

Match

Left Stick Y

A0

Channel to

Match

Right Stick X

A1

Wiring The Robot Chassis

L298N Pin

Arduino Pin

+5V

5V

GND

GND

ENA

6

IN1

4

IN2

5

IN3

7

IN4

8

ENB

9

You may have to play with these pin assignments depending on the orientation of your motors!

There should be two wires going into the ground port of the L298N motor driver… one from the battery and one to the Arduino.

Once the car is driving, the L298N will supply power from its +5V port into the Vin port on Arduino.

Code


#include <EnableInterrupt.h>
#define SERIAL_PORT_SPEED 57600
#define RC_NUM_CHANNELS 2
#define RC_CH1 0
#define RC_CH2 1

#define RC_CH1_INPUT A0
#define RC_CH2_INPUT A1  

int rf = 4;    // to in1 on L298N
int rb = 5;    // to in2 on L298N
int rpwm = 6;  // to ENA on L298N
int lf = 7;    // to in3 on L298N
int lb = 8;    // to in4 on L298N
int lpwm = 9;  //to ENB on L298N

uint16_t rc_values[RC_NUM_CHANNELS];
uint32_t rc_start[RC_NUM_CHANNELS];
volatile uint16_t rc_shared[RC_NUM_CHANNELS];
void rc_read_values() {
  noInterrupts();
  memcpy(rc_values, (const void *)rc_shared, sizeof(rc_shared));
  interrupts();
}
void calc_input(uint8_t channel, uint8_t input_pin) {
  if (digitalRead(input_pin) == HIGH) {
    rc_start[channel] = micros();
  } else {
    uint16_t rc_compare = (uint16_t)(micros() - rc_start[channel]);
    rc_shared[channel] = rc_compare;
  }
}
void calc_ch1() {
  calc_input(RC_CH1, RC_CH1_INPUT);
}
void calc_ch2() {
  calc_input(RC_CH2, RC_CH2_INPUT);
}

void setup() {
  Serial.begin(SERIAL_PORT_SPEED);
  pinMode(rf, OUTPUT);
  pinMode(rb, OUTPUT);
  pinMode(rpwm, OUTPUT);
  pinMode(lf, OUTPUT);
  pinMode(lb, OUTPUT);
  pinMode(lpwm, OUTPUT);
  pinMode(RC_CH1_INPUT, INPUT);
  pinMode(RC_CH2_INPUT, INPUT);
  enableInterrupt(RC_CH1_INPUT, calc_ch1, CHANGE);
  enableInterrupt(RC_CH2_INPUT, calc_ch2, CHANGE);
}
void loop() {
  rc_read_values();

  Serial.print("CH1:");
  Serial.print(rc_values[RC_CH1]);
  Serial.print("\t");
  Serial.print("CH2:");
  Serial.print(rc_values[RC_CH2]);
  Serial.println("");
  delay(200);

  double y = map(rc_values[RC_CH1], 1100, 2000, -255, 255);     //left wheel
  double spin = map(rc_values[RC_CH2], 1100, 1900, -255, 255);  //right wheel
                                                                /*
      Serial.print("Y:"); Serial.print(y); Serial.print("\t");  
    Serial.print("SPIN:"); Serial.print(spin); Serial.println("");  
    delay(200);
    */
  //forward
  if (y > 50) {
    digitalWrite(rf, HIGH);
    digitalWrite(rb, LOW);
    analogWrite(rpwm, y);
    digitalWrite(lf, HIGH);
    digitalWrite(lb, LOW);
    analogWrite(lpwm, y);
    delay(20);
  }
  //backward
  else if (y < -50) {
    digitalWrite(rf, LOW);
    digitalWrite(rb, HIGH);
    analogWrite(rpwm, abs(y));
    digitalWrite(lf, LOW);
    digitalWrite(lb, HIGH);
    analogWrite(lpwm, abs(y));
    delay(20);
  }
  //spin right
  else if (spin > 50) {
    digitalWrite(rf, LOW);
    digitalWrite(rb, HIGH);
    analogWrite(rpwm, spin);
    digitalWrite(lf, HIGH);
    digitalWrite(lb, LOW);
    analogWrite(lpwm, spin);
    delay(20);
  }
  //spin left
  else if (spin < -50) {
    digitalWrite(rf, HIGH);
    digitalWrite(rb, LOW);
    analogWrite(rpwm, abs(spin));
    digitalWrite(lf, LOW);
    digitalWrite(lb, HIGH);
    analogWrite(lpwm, abs(spin));
    delay(20);
  } else {
    digitalWrite(rf, LOW);
    digitalWrite(rb, LOW);
    digitalWrite(lf, LOW);
    digitalWrite(lb, LOW);
    delay(20);
  }
}
```

Testing

- Once you have downloaded the code, you can unplug the Arduino and power it from the motor controller through the Vin port.

- For testing place the robot up on a block so that the wheel can spin freely without it going anywhere.

- Pair your receiver with your transmitter following the same procedure you used in the Reading Radio Frequency Signal project

- Once your wheels are spinning predictably, place the robot on the ground and test its handling.

Last updated

Was this helpful?