Introduction: 3D Printed Arduino Based RC Transmitter

About: Currently designing, 3d printing, building, wiring, and/or programming robots.

This project will show you how I went about designing and building an Arduino based RC Transmitter.

My goal for this project was to design a 3D printable RC Transmitter that I could use to control other Arduino projects. I wanted the controller to be as permanent as possible, but I also wanted the ability to take it apart and redesign portions of it. This project is the result of a few weeks of hard work.

Supplies

To build this controller, you will need:

  • Analog Joystick x2
  • Analog Potentiometer x2
  • 128x32 0.91 inch OLED Display x1
  • Arduino Nano x1
  • NRF24L01 module with antenna x1
  • 3cm x 7cm perfboard x1
  • BRC 18650 3.7 v Li-ion battery x2
  • 2 cell 18650 battery case x1
  • AMS1117 3.3 voltage regualtor x1
  • 3 position toggle switch x1
  • 2 position toggle switch x2

Additional Items:

  • Multicolored standard 22 gauge wire
  • Multicolored solid core 22 gauge wire
  • Male + Female Pin headers
  • m3 pan head screws and nuts (assorted length)
  • m2 pan head screws and nuts (assorted length)
  • m2 standoffs (assorted length)
  • Access to:
    • 3D printer
    • Soldering Iron

Step 1: 3D Model

I began by modeling the controller in a 3D modeling software. There were a few things I took into consideration during the design process:

  • My 3D printer is relatively small, so my parts would need to be joined after the printing process. To solve this, I added holes throughout the design to attach parts using m2 screws.
  • I wanted to easily rearrange parts on my design without having to re-print, so I added uniformly spaced holes where the parts would be joined to allow for post-print design opportunities.
  • I avoided overhangs altogether in this design, resulting in high-quality prints.

This model doesn't contain all of the parts that make up the transmitter, but all of the parts required to 3D print are included. You can download the STEP file for this model by clicking download below.

*I included the .stl file for the nrf24 enclosure for those who were having trouble splitting it into three separate parts.

Step 2: 3D Printing

This is a fairly straightforward step. After all of the parts have been printed, you can begin preparation for assembly of the parts.

Step 3: Preparation for Assembly: Wires

In order to allow for changes to the design of this project, I soldered male pin headers to one end of all the wires.

Step 4: Preparation for Assembly: OLED Display

Before you begin assembly, you will need to prepare a few of the electronic components. The first thing to do is solder wires to each of the component's pins. (It is easier to use the standard wire in this situation because it is more flexible and therefore easier to assemble.) My OLED Display was without pin-headers, so I soldered the wires directly to the breakout board. However, it makes no difference weather or not you solder to the pin headers.

Step 5: Preparation for Assembly: Joysticks

The next step is to solder wires to the joysticks. In this case, I soldered the wires to the pin headers for a few reasons:

  1. If I had removed the pin headers and soldered to the holes, I would have had to feed the wires through the tops of the holes because the 3D printed mount is directly under the joystick's breakout board.
  2. Since I soldered to the pin headers, the wires drop straight down and make the top side of the transmitter more organized.

I used the same colors for the same types of pins on both joysticks:

  • Red for VCC
  • Black for GND
  • Blue for VRX
  • Yellow for VRY
  • Green for SW

This made it easier when connecting the wires to the proper ports on the Arduino.

Step 6: Preparation for Assembly: NRF24L01

For the NRF24L01 module, I removed the pin headers and soldered directly to the holes in order to have room for the perfboard. Once again, I took note of the colors I used for each pin for future reference.

Step 7: Preparation for Assembly: Potentiometers

For the potentiometers, solder wires to each of the three leads. The outer two leads are either ground or vcc pins (it doesn't matter in which order) and the middle lead is output.I soldered a red wire and black wire to the outer two leads and a white wire to the center lead for both potentiometers.

Step 8: Preparation for Assembly: Switches

Take the three position switch and solder a wire to each of the pin headers. I used black for the middle and two other colors for the outsides, which I took note of for future reference.

On the two position switches there are three pin headers. You will only be using two of these. A black wire goes in the middle and another wire goes on one of the two outside pin headers. Important: Do this for only one switch.

The next switch will be used as an on-off switch. For now, only solder a wire to the central pin of this on-off switch.

Step 9: Preparation for Assembly: Solder the Battery Case to the On-off Switch

Solder the red wire of the battery case to one of the outside pins on the on-off switch. If you have not already, solder a pin header on the black wire of the battery case.

Step 10: Preparation for Assembly: AMS1117 Voltage Regulator

For this step you will need the AMS1117 3.3 volt regulator. Here, I have one attached to a breakout board designed for the NRF24L01, so I will be showing how to complete this step using this part. If you have just the AMS1117 IC, there are plenty of tutorials out there that can help you with the wiring.

The first thing I did was desolder all of the pin headers from the board. I then soldered a red and black wire to the corresponding pins.

Continuing with the non-permanent design, I took a row of two female pin headers and attached them to the VCC and GND ports where the NRF24L01 module would sit.

Once you have done this, you can move on to the next step.

Step 11: Prepare the Perf Board: Arduino and Pin Headers

The last thing to do before assembly is to prepare the perfboard. To do this, you will need the Arduino Nano, the solid core wires, and the female pin headers.

Make sure your Arduino Nano has pin headers, and proceed to solder it to the perfboard. You will want to put it as far to one side of the board as possible to leave room for connection extensions, but you also will want to leave a row on each side of the Arduino for soldering the female pin headers. Make sure the USB connector is as close to the edge of the board as possible. My 3cm x 7cm board is 10 holes by 24 holes. This left me with two rows to the left side of the Arduino, one row to the right side, and about nine holes behind the Arduino.

Next take two rows of fifteen female pin headers and solder them next to the Arduino. I used standard female pin headers but I wished I had used stacking headers for this reason:

  • You will need to connect the leads on the pin headers to the leads on the Arduino. If you used the standard pin headers, a solder bridge will need to be make the connection, which is a little tedious and time consuming. If you used the staking headers, you can bend the leads to touch the Arduino leads to make the soldering task much easier.

Whichever way you choose to do this, the pin headers must be connected to the Arduino pin headers.

Step 12: Prepare the Perf Board: Pin Extensions

Once you have the Arduino and pin headers soldered to the board, the next step is to extend the 5v and ground pins to accommodate all of the electrical components.

Solder two rows of 10 pin headers on the perf board on the opposite end as the Arduino with one row of space between them.

Take a piece of solid core wire and run it from the 5V pin on the Arduino to one row of pin headers. Strip the insulation so the wire is exposed where it touches the leads on the pin headers. Solder the wire in place.

Do the same thing except with the GND pin on the Arduino and the other row of pin headers.

Once you have done this, the transmitter is ready to be assembled.

Step 13: Assembly: Attach the Joysticks to the Base

For this task, you will need eight m4 screws and the corresponding nuts, along with a few washers.

Place the nuts in the hexagonal holes on the bottom of the 3D printed part shown above.

Slide one washer onto each screw.

Push four m4 screws into the four holes on the joystick's breakout board.

Slide the joystick offset 3D printed part to act as a standoff between the breakout board and the joystick mount.

Slide the joystick with screws into its place on the base, holding the nuts in their slots as you fasten the screws.

Repeat this step for the other joystick.

Step 14: Assembly: Attach the Potentiometers and the OLED Display to the Potentiometer Rack

Slide the potentiometers into their places on the potentiometer rack. The potentiometers I have came with nuts to tighten them down, and I used these here to keep the potentiometers in place. To tighten the nuts inside the inset, I used a flat head screwdriver.

Next, feed the OLED Display wires through the slot on the left-hand side of the potentiometer rack. Tighten the cover over the display with a few m2 screws. You may need to add a few washers to accommodate for the display's protrusion.

Step 15: Assembly: Attach the Potentiometer Rack to the Joystick Base

Take the potentiometer rack and attach it to the joystick base using m2 screws so the pin-headers of the joystick are facing away from the rack.

Step 16: Assembly: Attach the NRF24L01 Enclosure to the Potentiometer Rack

The NRF24L01 enclosure is made up of three parts. Take the first part and feed the wires of the module itself through the slot in the back. The front end should sit in the slot and the solder joints protruding from the back of the board should sit in their respective slot as well.

Take the cap of the enclosure and line up the holes so that the flat side of the cover is flat against the enclosure. Slide two m2 screws through the holes and fit this assembly through the holes on the potentiometer rack. To complete this step, line up the holes on the second cap with the m2 screws so the small parabolic protrusion on the front of the part sits around the cylinder of the NRF24L01 module. Tighten it down with two nuts.

Step 17: Assembly: Attach the Handles to the Base.

Take both the handles and attach them to the base using m2 screws as shown in the images above.

Step 18: Assembly: Attach the Battery Case to the Base

Attach the battery case to the battery mount with countersink m3 screws.

Attach the battery mount to the base with m2 screws so the battery case is opening downwards.

Step 19: Assembly: Attach the Switches to the Handles

For this step you will need all of the toggle switches. Begin with the three position toggle switch.

Remove the fastener from the switch and slide the switch through the hexagonal hole on the right handle. It isn't crucial where this switch is located.

Take the two position toggle switch with two wires and push it through a hole on the left side of the handle, attaching it in the same way as the previous switch.

Choose another hole on the left handle to attach the final two position toggle switch, which should be the on-off switch.

Step 20: Assembly: Attach the Perf Board Assembly to the Joystick Base

Use m2 screws and m2 standoffs to attach the perfboard mount to the joystick base. Make sure the slot on the perf board mount fits around the NRF24L01 module. Once again, you may need to add a few washers in between the mount and base to account for the screw head protrusion (You can also use the 3D printed offset for this). You will want to make sure you slide the longer m2 screws through the tubes on the mount first, because you won't be able to do this once the mount is attached.

Step 21: Assembly: Attach the Perf Board to the Perf Board Mount

Use m2 screws to attach the perfboard mount to the perfboard so that the Arduino and pin headers are facing away from the mount. The length of your wires may drive the direction the USB port on the Arduino is pointing.

Step 22: Arduino Connections

Choosing this design of transmitter results in a seemingly disorganized underside. To make this seem like a less overwhelming task, I focused on one type of connection at a time. For example, I began by connecting all of the GND wires to the extended row for GND on the perf board. Here are the connections:

Digital Pins:

D4 - Joystick1 Sw

D5 - Joystick2 Sw

D6 - Outside pin of 2 Position Toggle Switch

D7 - Outside pin of 3 Position Toggle Switch

D8 - Other Outside Pin of 3 Position Toggle Switch

D9 - CE Pin of NRF24L01

D10 - CSN Pin of NRF24L01

D11 - MOSI Pin of NRF24L01

D12 - MISC Pin of NRF24L01

D13 - SCK Pin of NRF24L01

*Note: This is when color coding your wires will come in handy. The NRF24L01 enclosure restricts your view of the pin names. When you color code the wires, you can tell which pin is which without much effort, making it much easier to connect the wires to the Arduino.

Analog pins:

A0 - Center Pin of Potentiometer 1

A1 - Center Pin of Potentiometer 2

A2 - Joystick2 VRX Pin

A3 - Joystick2 VRY Pin

A4 - OLED SDA (DATA) Pin

A5 - OLED SCL (CLOCK) Pin

A6 - Joystick1 VRY Pin

A7 - Joystick1 VRX Pin

Voltage Regulator (AMS1117):

Connect the ground pin of the NRF24L01 module to the ground pin on the voltage regulator. Connect the 3.3 volt pin on the NRF24L01 to the voltage regulator.

Ground Pin Extension Pin Headers (Connect all of these pins to the ground pin headers):

  • Center Pin on 2 Position Toggle switch
  • Center Pin on 3 Position Toggle switch
  • Joystick1 GND Pin
  • Joystick2 GND Pin
  • Potentiometer 1 right pin
  • Potentiometer 2 right pin
  • OLED GND Pin
  • GND of Battery Case
  • GND Pin on voltage regulator

5v Pin Extension Pin Headers (Connect all of these pins to the VCC pin headers):

  • Joystick1 5v pin
  • Joystick2 5v pin
  • Potentiometer 1 left pin
  • Potentiometer 2 left pin
  • OLED VCC pin
  • VCC Pin on voltage regulator

Other Connections:

The final component to connect is the on-off switch. One lead of the switch should be connected to the positive terminal on the battery case. The center pin will be connected to the VIN pin on the Arduino.

Step 23: Transmitter Code

The final step to this controller is the code. I will do a small amount of explanation for this code, but if you would like a more in-depth explanation of exactly how the NRF24l01 module works and is used, visit this site:

Arduino Wireless Communication – NRF24L01 Tutorial

#include <Adafruit_SSD1306.h>
#include <splash.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
#include <Wire.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>


#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels


Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
RF24 radio(9, 10);
const byte address[6] = "00001";
int data[11];
const int onevrx = 7;  //variable for VRX on joystick 1
const int onevry = 6;  //variable for VRY on joystick 1
const int twovrx = 2;  //variable for VRX on joystick 2
const int twovry = 3;  //variable for VRY on joystick 2
const int pot0Pin = 0;        //variable for pot 1
const int pot1Pin = 1;       //variable for pot 2
const int ASwitch = 6;           //variable for two position toggle switch
const int BSwitch1 = 8;           //variable for position one of three position toggle switch
const int BSwitch2 = 7;           //variable for position three of three position toggle switch
const int CButton = 2;          //variable for optional push button 1
const int DButton = 3;          //variable for optional push button 2
int oneX;
int oneY;
int twoX;
int twoY;
int pot0;
int pot1;
void setup() {
  Serial.begin(9600); 
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();  
  pinMode(ASwitch, INPUT_PULLUP);        // set APin to output mode
  pinMode(BSwitch1, INPUT_PULLUP);        // set BPin to output mode
  pinMode(BSwitch2, INPUT_PULLUP);        // set CPin to output mode
  pinMode(CButton, INPUT_PULLUP);        // set DPin to output mode
  pinMode(DButton, INPUT_PULLUP);

	display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

  	delay(1000);

	display.clearDisplay();

	display.setTextSize(.25);
  	display.setTextColor(WHITE);
  	display.setCursor(0, 0);
  
  display.print("Power On");
  display.display();
  delay(10);
}

void loop() {
  oneX = analogRead(onevrx);
  oneY = analogRead(onevry);
  twoX = analogRead(twovrx);
  twoY = analogRead(twovry);
  pot0 = analogRead(pot0Pin);
  pot1 = analogRead(pot1Pin);
  
  
  
  
  data[0] = oneX;
  data[1] = oneY;
  data[2] = twoX;
  data[3] = twoY;
  data[4] = pot0;
  data[5] = pot1;
  data[6] = digitalRead(ASwitch);
  data[7] = digitalRead(BSwitch1);
  data[8] = digitalRead(BSwitch2);
  data[9] = digitalRead(CButton);
  data[10] = digitalRead(DButton);

	radio.write(&data, sizeof(data));    //send data to the receiver

  delay(100);
  
  display.clearDisplay();

 display.setTextSize(.25);
  display.setTextColor(WHITE);
  display.setCursor(5, 5);
  
  display.println(data[4]);
  display.print("Recieving power"); //add any additional information you would want to display on the OLED here
  display.display();  
}

Step 24: Receiver Code

#include <SPI.h>

#include  <nRF24L01>

#include <RF24.h>
RF24 radio(9, 10);    //cns, ce            // define the object to control NRF24L01
const byte address[6] = "00001";      // define the communication address which should correspond to the transmitter

int data[11] = {512, 512, 512, 512, 512, 512, 0, 0, 0, 0, 0};  // define array used to save the communication data

void setup() {
  radio.begin();                   
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();                         //set as receiver
  Serial.begin(9600);

}

void loop() {
  if (radio.available())  {
    radio.read(&data, sizeof(data));    

//printing a few data points from the controller to the serial monitor

Serial.print(data[0]);
    Serial.print("\t\t");
    Serial.print(data[1]);
    Serial.print("\t\t");
    Serial.print(data[2]);
    Serial.print("\t\t");
    Serial.print(data[3]);
    Serial.println("");

  } //Again, this is just the base code example for the receiver module.

Step 25: Conclusion

You can control virtually any Arduino project with this controller, and the its design allows for even more modification. You might decide you want two additional potentiometers instead of an OLED Display (If you would like the STEP file of a 4 potentiometer rack, I can send that to you. Just make a comment with the request). Or maybe you wish to add a few push buttons to the design. It is entirely up to you.

If you have any questions, comments, or concerns, don't hesitate to ask.

Thank you for taking the time to read through these 24 steps. I hope you were able to learn something or get a few new ideas about what can be accomplished with a 3D printer and an Arduino.

Arduino Contest 2020

Runner Up in the
Arduino Contest 2020