Introduction: 3D Printed Arduino Based RC Transmitter
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:
- 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.
- 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.

Runner Up in the
Arduino Contest 2020
21 Comments
Question 2 years ago
Hello Dear SIr/Madam
I want to ask that I watched this video (15) DIY Arduino based RC Transmitter - YouTube actually I want to make a drone using an Arduino Uno R3 flight control and I really wanted to use DIY transmitter but I don't have any idea how to connect it and what type of coding I have to do to make it work with my Arduino uno R3 based drone which consist of 4 brushless motors with 30A ESC.
Question 3 years ago
Very cool project. I tried hooking things up on a Breadboard, but the receiving nRF24L01 seemed to only Serial.print zeros for each value of the data[11], not even the 512 values that you declare in the setup of the receiver code. I am trying to troubleshoot, but I thought I would ask in case you already knew what might be the problem. I tried the GettingStarted_HandlingData example of the RF24.h library and that worked. I also get the data to display on the OLED of the transmitter, so the hardware seems to be working. I running on Arduino IDE 1.8.13. Any ideas why I am not getting the actual data to the receiver?
Answer 3 years ago
I don't recall running into this exact problem when I was working on this project, but I have a few ideas on what it could be:
If the receiving nRF24L01 is printing out zeros instead of the values defined in the setup of the receiver code, then the transmitter is probably transmitting those values (the data[11] array is only updated if the radio signal is available). If this is the case, chances are you may have an error in your circuit. I once had a problem where I was creating a button panel and I forgot to ground the buttons back to the Arduino. I went to code, and the Arduino was printing out zeros no matter what state the button was in. I would first double check to make sure you have everything wired up correctly.
If that's not it, it is probably the code itself. If the library worked, then your actual NRF modules are okay. I would try editing the example code, starting by sending the data from one potentiometer. When I was going through the process of getting my nRF24L01 modules to communicate, I followed a lot of different tutorials, and only some worked for me. I am just speculating here, but it might be possible that these modules were all build slightly different and code that worked for one person may not work for another.
I hope I was able to help. Let me know if you have any success.
Reply 2 years ago
Hi BasementMaker,
This was months ago, and I am not sure what I did, but it seems to be working now. Thanks for your advice. JD
Question 2 years ago
Hi,
I'm trying to print/assemble this remote. All goes fine, but the nrf24 enclosure is a single solid in my software (freeCAD). What software did you use? Or can you upload this component separately (body & 2 lids). This would be super helpful. Keep up the good work!
Answer 2 years ago
Hello.
I used Fusion 360 to design this controller and was unaware there would be an issue transferring my .step file to another program. I will add those .stl files to this project for you.
Here is another thought. I haven't used freeCAD, but you might be able to define a plane between the separate parts of the nrf24 enclosure and split the body along that plane.
If this doesn't help, please let me know and I can try something else. I would love to know how it goes.
- BasementMaker
Reply 2 years ago
Thank you,
I downloaded the stl files and they work. So I'll print them soon.
I only started 2 days ago with printing my pieces. So it'll take a while before I have a functioning remote.
I also designed a bigger handle, for my big hands.
Take care
Jan
3 years ago
I have not used a controller like this before. What purpose do the variable resistor use? I have been trying to design something along this line for someone with use of only the left hand for the game of Tanks. Suggestions?
Reply 3 years ago
Thanks for taking the time to view my project.
I wanted this controller to be universal between all my future projects, so I included as many different interface devices as I could, thus the inclusion of the potentiometers.
I am assuming when you say the game of Tanks you are referring to a computer video game? If so, I would suggest bypassing the radio transmission complications and going with something connected directly to the computer. I built a computer game emulator for a school project once (in 8th grade, so it was about as simplistic as it could get), and I used a joystick and a few buttons. I used an Arduino Micro for the keyboard emulation, and it worked pretty well. I would have to know more about your project criteria before I could go more in depth with my suggestions, but hopefully this gives you a few ideas to get started. Good luck!
- BasementMaker
Reply 3 years ago
The game is World of Tanks. The tank moves forward/backward, left/right. The turret must move circular and the gun must raise and lower. Plus firing controls. They make some for right-handed people but not for left handed. He had a stroke and his right side is paralyzed. But I'm not really sure where to start. I build circuit cards.
3 years ago
This looks to be really cool project, but if you would indulge me for a
moment, I would like to offer a few pointer and suggestions to help
give a cleaner overall finished project. The first thing I would do is
de-solder the pins off of the addons boards, (joy sticks, nano, rf), and
solder the wires directly to the boards. I would use DuPont connectors
to give a cleaner assembly to the wiring.This gives you a cleaner more
experienced look to the boards when someone inspects or scrutinizes
them, (much like I am doing, Sorry!). Next, I would add shrink tubing to
the wire connections on the switches and any other exposed wired areas
that have a potential for either contact or flexible disconnect areas.
The potentiometers, I would solder the wires to the pin instead of the
through holes. The heat tends to loosen the contact point between the
rivet and the resistor wafer. The flux can also cause the wiper to
become stuck when the flux dries out and create a barrier between the
restive pad and the wiper creating intermittent contacts. Just a few
pointer for a cleaner, less troublesome build down the road. I offer
these suggestions from experience over the last 30+ years of electronics
and hobby crafts. I have also added sample pics of how I do this.
Reply 3 years ago
As an engineer, I do not like separate wires. Using solid connectors and color coded wire is an excellent way to make a neater setup.
Amazon: https://www.amazon.com/Glarks-1191Pcs-Housing-Conn...
is a connector kit.
Question 3 years ago
DO you know whether there is any way of making an Arduino Transmitter that could b used to replace a lost controller for an rc car that i have found in the loft, plz?
Answer 3 years ago
Remote control uses pulse width modulation so it's all a matter of timing. I did make a simple servo tester with a PIC chip so as long as you can follow the theory it's not that difficult to use the hardware described here with a RF stage. The rest depends on the RF frequencies you need.
Reply 3 years ago
Sorry for the late reply. I have never actually done this, but I know the theory behind it. Most higher end RC cars will have a brush-less motor, an ESC (electronic speed controller) to control the brush-less motor, and a servo motor for the steering mechanism. Normally, both the ESC and the servo motor would be connected to the receiver for whichever controller you were using. If you have lost the controller for the receiver, you can replace the receiver in the car with another receiver that works with this transmitter. This receiver will need to consist of an Arduino and a NRF24L01 module. I am not sure of the specifics, but you can interface the Arduino with the ESC to control the brush-less motor and controlling a servo motor with an Arduino is fairly straightforward.
In other words, you will need to switch out the receiver that goes with the lost transmitter for a receiver that will work with this controller.
https://www.youtube.com/watch?v=tzNROquPEHQ - This is a link to a video that should answer your question in more detail.
I hope this helps,
BasementMaker
3 years ago
Nice but could be a little more tidy with the soldering by twisting the copper ends before soldering, also a bit of heat shrink tubing would avoid the whisker seen in the switch wiring (step 8). I tend to use 7/0.2 wires, nice and thin.
BTW I've just completed a project using an Arduino to remote-control a 70mm film projector from a TV controller.
3 years ago
This is incredible. I would be nervous to trust it with my bigger tech long distances, but its awesome and looks super clean. Really well done.
Question 3 years ago on Step 25
Well done! So what are YOU using it for?
Reply 3 years ago
Thanks. To answer your question, the idea for this project grew out of the need of something to control a 4 axis robotic arm (3D printed and Arduino based, of course). My original plan was for the controller to only have 4 potentiometers (one for each axis), but I decided, since I was at it, I might as well give the controller the ability to interface with any future projects.
3 years ago
Very nice project!