Virtual Reality R/C Car Part 3

Virtual Reality R/C Car Part 3

May 04, 2018

Luke Ridley

So the next step on this project is really what sets this project apart from your typical R/C build. In order to make the driver feel like they are actually driving the car we added a FatShark FPV system to the car. In order to mount this system on the car I created a self contained box for the radio receiver, small LiPo battery, and the FatShark camera. If you have a 3D printer and a FatShark set up at home here is a link to the STL Files:


Here is the case assembled and mounted on the car:


vr car


To put the case together I used 4 2.5mm screws and two #10 x 5/8 screw and nuts. I purchased the on/off switch from amazon at this link:


The goggles that we are using for the system are the FatShark Teleporter Model. Which work pretty well. The main drawback of the setup currently is that the camera is fixed facing forward on the car. While driving you want to be able to look around. Its kind of like trying to drive a car that only has a windshield. It works but it does not feel totally intuitive. In the future I would like to add some sort of moving camera mount that follows the head motion of the driver. Either with an accelerometer, two servos, and an Arduino or with some technology from FatShark. I know FatShark makes a Trinity Head Tracker Module so this may be a good route to go.



Also I have made a slight change to the code as well. The car now has two modes determined by the position of a switch. There is Easy Mode (Shown above) and Sport Mode. The difference is in easy mode the cars speed is limited. However in sport mode the more you turn the throttle the faster the car will go. It is harder to control that way but once you get used to it, it is very worth it. I will post a video soon of a test of this change. I have Highlighted the changes I made in the code to do this below:


#include <SoftwareServo.h>

#include <SPI.h>  

#include "RF24.h"

RF24 radio(9, 10);

SoftwareServo steering;

SoftwareServo gogojuice;

byte addresses[][6] = {"1Node", "2Node"}; // These will be the names of the "Pipes"

struct dataStruct {

  unsigned long _micros;  // to save response times

  int throttle;          // The Joystick position values

  int handBreak;

  int bikeTilt;

  bool pushButton;          // The Joystick push-down switch

} myData;                 // This can be accessed in the form:  myData.Xposition  etc.        

void setup()  




  pinMode(3, OUTPUT);

  pinMode(5, OUTPUT);


  radio.begin();          // Initialize the nRF24L01 Radio




  // Open a writing and reading pipe on each radio, with opposite addresses


  radio.openReadingPipe(1, addresses[0]);

  // Start the radio listening for data






void loop()  


  if ( radio.available())


    while (radio.available())   // While there is data ready to be retrieved from the receive pipe

    { &myData, sizeof(myData) ); // Get the data


    radio.stopListening();                     // First stop listening so we can transmit

    radio.write( &myData, sizeof(myData) );    // Send the received data back.

    radio.startListening();                    // Now resume listening so we catch the next packet


    double Mode;

    if (HIGH == digitalRead(6))


        Mode = 0.01;




        Mode = 0;



    int drive;

    int bikeTiltRecieved = myData.bikeTilt;

    int handBreakRecieved = myData.handBreak;

    int throttleRecieved = myData.throttle;

    int tilt = map(bikeTiltRecieved, 0, 1023, 0, 180);

    if (throttleRecieved > 100 && handBreakRecieved < 100)


      drive = 96 + throttleRecieved*Mode;


    if (throttleRecieved < 100 && handBreakRecieved > 100)


      drive = 85;


    if (throttleRecieved > 100 && handBreakRecieved > 100)


      drive = 90;


    if (throttleRecieved < 100 && handBreakRecieved < 100)


      drive = 90;