How I Made a Radio Controlled Roomba Using Arduino

Charlie Gray
The Startup
Published in
12 min readMar 7, 2020

One day, I was browsing the cursed website that is Twitter when I stumbled upon a video from a man named Michael Reeves. Michael had modified a Roomba to scream in pain when it runs into things. I thought this idea was pretty cool, and I wanted to mod my own RC Roomba (with less screaming).

Michael Reeves and his modified Roomba

As luck would have it, I was browsing eBay the next day and I found a cheap, broken Roomba for sale.

This was my destiny.

I had so many great ideas of what I could make with this Roomba.

I decided to create a base that could be used for future projects. I wanted a device like a Raspberry Pi to be able to interact with an Arduino over USB serial and control the Roomba. For example, this would allow the Arduino to be controlled by a Raspberry PI using Machine Learning to drive the Roomba to a specific location or object.

I also wanted to change out the motors on the Roomba with better ones to make it run faster. Finally, just for fun, I wanted to be able to control the Roomba with an RC controller.

This post is a log of the steps I took to build the prototype. Please know that this is not the only way to mod your Roomba nor is it even the best way. This is just how I went about modding my Roomba. If you would like to recreate this project for yourself, I would highly recommend branching off and improving from what I did.

Materials Used

1x Roomba: You can buy cheap broken Roombas on eBay, or use your own! I used a broken Roomba 650 I found on eBay. If you do buy a used Roomba, be sure to clean it out thoroughly.

1x Arduino: This is the brains for our robot. I used an Uno, but you could also use a Nano or a Mega if that’s what you have on hand.

2x 12V DC Motors: I used these motors on amazon, but you can use cheaper ones too. I recommend checking your local hobby store.

1x DC Motor driver: You can find these on Amazon or at most hobby stores. I used these drivers, but you can find them for much less at Micro Center.

1x RC Transmitter & Reciever: This is used to control the Roomba. I have a Fly Sky i6 transmitter, and I’m also using the Fly Sky-iA6 Receiver that came with it.

1x 13V Power supply or 1x 13V battery: We need 13 Volts to power our DC motor driver, our DC motors, and our Arduino. I had an extra power supply on hand, so I just used the Roomba plugged into an extension cord. You could also add a battery to make the Roomba wireless. The battery that came with my original Roomba was dead, so I couldn’t repurpose it.

WaGo Lever nuts or a soldering iron: I use WaGo lever nuts to connect wires in small projects like this. A soldering iron or wire nuts will work just as well. I just used these because I had them on hand.

Punch and mallet or hammer

A heat gun or hairdryer

Dremel or hand saw

Hot glue gun

Screw Driver

Sandpaper and/or a File

Zip ties

Duct tape

Jumper cables and/or a crimp set

Wire

Safety glasses

Clamps (optional)

Velcro tape (optional)

Masking tape (optional)

Step One: Disasemballing the Roomba

Unfortunately, I cannot be much help here as I lost the images of my Roomba disassembly. However, I can direct you to this great guide that could be some help.

Essentially the main goal is to remove the vacuum assembly. This will give us enough room to put our electronics in. Then be sure to clean out your Roomba, especially if you bought a broken one on eBay like I did.

Step Two: Removing the Tires

Our next step will be to remove the tires from the wheel assembly. I want to try to use as much of the Roomba as possible so that I’m not wasting parts. If you want to make your own tires you may skip this step, though I would advise against it

First, remove the tire assembly from the Roomba by unscrewing the three Phillips head screws holding it to the body.

Source: IFixit

Next, remove the suspension spring from the wheel assembly. This will make it a lot easier later on. I just used a pair of pliers to unhook the spring from the plastic shell.

Plastic wheel assembly

Next, we need to remove the pin holding the wheel and the gear assembly housing to the blue plastic. To do this, I found the most effective method was to use a punch and mallet. Remember to use safety glasses while using the punch.

Pin (circled) that needs to be punched out

After you removed the pin, you should be left with just the gear assembly housing.

The gear assembly separated from the main wheel assembly

Next, we need to access the gears. Unscrew the six Phillips head screws and remove the cover.

The open gear assembly

After we gain access to the internals of the gear assembly, we need to remove the gears. I pried the top three gears off with a flat head screwdriver.

The gear assembly with most of the gears removed

Next, we need to remove the big gear adhered to the wheel axel. To do this we can use a hairdryer or heat gun to soften the adhesive.

Try to aim the heat gun close to where the gear meets the axel. Once the adhesive has softened, use a flathead screwdriver to pry the gear and wheel off of the axel.

Prying the wheel off with a flathead screwdriver

Then, slide the wheel and axel away from the plastic housing. Once the wheel has been removed, we need to cut the axel to fit inside of the wheel profile. This will allow us to use a 3D-Printed adapter to connect the wheel axel to the motor. To cut the axel, I just used a saw. A Dremel should also work just fine.

Step Three: Printing and Installing the Wheel Adapter

The next step is to print two of the wheel adapters mentioned earlier.

I designed the wheel adapters with a very low tolerance so I could press fit them into the wheel with minimal glue. Here is the link to the Fusion 360 file if you need to make any modifications to the design

Wheel Adapter

Next, I put a little bit of hot glue inside the wheel. I then used two clamps to press-fit the adapter into the wheel. Then slide the motor into the other end of the Roomba.

Press fitting the wheel adapter into the wheel

Step Three: Printing the Motor Mounts and Installing the Motor

Now, let’s turn our attention back to the Roomba. We need to print the mounts that will allow us to attach the motors to the Roomba base. Here is the link to the Fusion 360 file for the mount.

Place the motor inside of the mount. Then, use a zip tie to secure the motor to the mount. I also wrapped the motor with duct tape for extra friction. Later in the build, I added another motor mount on the back half of the motor. This will not be pictured below, but it will add a lot more stability.

The motor attached to the motor mount

Step Four: Attaching the Motors to The Roomba

Next, we need to cut two small holes across from each other. This is so the wheel can sit in the former location of the wheel assembly while the motor sits where the vacuum was. First, I lined up where I would make the two cuts with masking tape.

Lining up the cuts

Next, I used a saw to cut out around a 15 mm x 12 mm hole in the plastic, or just enough so that the axel can pass through the plastic while allowing the motor mount so sit flush with the base.

Cuts in the Roomba before being sanded + filed

Then, be sure to sand down and/or file your cuts until they are smooth. This is to prevent injury and damage to the electronics.

After our holes are cut, it’s time to install the motor mounts to the Roomba. First, I scuffed up the Roomba plastic, and the motor mount, with some sandpaper in the areas I wanted to glue. This was to ensure that the glue would stick.

Next, I used hot glue to secure the motor mount to the Roomba.

Hot gluing the motor to the Roomba

Repeat these steps with the other motor.

After gluing the mount, I realized the Roomba was quite unstable with only one motor mount, so I added another one to both sides.

Step Five: Installing the Electronics

As I mentioned before, this project runs off of an Arduino and is controlled by a FlySky RC transmitter/receiver combo. You may also choose to control the Roomba by another means via serial. If you do, just ignore the mentions of the RC receiver.

The first step is to mount the electronics to the Roomba. For this, I used velcro tape for easy removal. You may also choose to glue your components.

Here is how I configured my components.

Components in the Roomba (poor photoshop of the receiver aside)

Next, wire up the components according to this diagram.

Fritzing diagram of the electronics

For my Roomba, I wired my electronics to an external power source rather than a battery. This was only because I did not have a battery on hand. However, you can wire your Roomba to a battery if you wish.

Step Six: Programing (RC)

If you would like your Roomba to run off an RC controller, the next step is to upload the code for it.

First, we need to calibrate the controller. Open this code in the Arduino IDE.

//Define pins
#define pin 12
void setup() {
//Pour a bowl of serial (Yum!)
Serial.begin(9600);
//Set pin to input mode
pinMode(pin, INPUT);
}
void loop() {
//Print pulse in
Serial.println(map(pulseIn(pin, HIGH), 1100, 1900, 0, 255));
delay(20);
}

We are using two separate inputs from the RC receiver, our X-axis pin, and our Y-axis pin. Each pin on the receiver corresponds with one transmitter input. You can play around with the receiver and determine which controller configuration works best for you.

First, find the pin on the receiver you want to calibrate. Then, change the “pin” variable in the code to the pin number of the corresponding pin on the Arduino. Connect a wire from that pin on the Arduino to the RC Reciever pin that you want to calibrate. Finally, upload the code to your Roomba and open the serial monitor.

Once the code has been flashed, move the stick you’re calibrating to the maximum position. Then log the corresponding value shown in the serial monitor. Repeat these steps to find the neutral position of the stick. Then, do the same for the other inputs you wish to use.

Once you finish getting the calibration values, we can plug them into the main script below. This will be the script to actually control the Roomba.

/*
RC Roomba Arduino code :)
Made with <3 by Charlie Gray
medium.com/@charliegray.dev
*/
//Define Y axis
#define ch1 13
#define maxValy 279
#define midy 124
//Define X axis
#define ch3 12
#define maxValx 282
#define midx 123
// Motor A connections
int enA = 2;
int in1 = 7;
int in2 = 6;
// Motor B connections
int enB = 3;
int in3 = 4;
int in4 = 5;
//Power going to motors (-255 to 255)
int leftPower;
int rightPower;
void setup() {
// Set all the motor control pins to outputs
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
//Set Radio pin to in
pinMode(ch1, INPUT);
pinMode(ch3, INPUT);

// Turn off motors - Initial state
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
// Set speed to 0
analogWrite(enA, 0);
analogWrite(enB, 0);
}void loop() { //Get RC
leftPower = clampInt(getRCValue() - getTurnMod()*2,-255,255);
rightPower = clampInt(getRCValue() + getTurnMod()*2,-255,255);


//Left motor
//Set L Direction
if (leftPower > 0){
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
}
else{
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
}
//Right motor

//Set R Direction
if (rightPower > 0){
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
}
else{
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
}
//Set R Power
analogWrite(enB, abs(leftPower));

//Set L Speed
analogWrite(enA, abs(rightPower));
}
//Get speed from RC Reciever
int getRCValue(){
int zero = map(pulseIn(ch1, HIGH), 1100, 1900, 0, 255)-midy;
float current = (float)zero/(maxValy-midy);
if(current > 0.7){
return 255;
}
if(current < -0.7){
return -255;
}

return (0);
}
//Get turn multiplier
int getTurnMod(){
int zero = map(pulseIn(ch3, HIGH), 1100, 1900, 0, 255)-midx;
float current = (float)zero/(maxValx-midx);

return (current*255);
}
//Clamp intint clampInt(int value, int minClamp, int maxClamp){
if(value>maxClamp){
return maxClamp;
}
if(value<minClamp){
return minClamp;
}
return value;
}

Before we flash the code to the Arduino, we need to change the maximum and neutral calibration for both inputs. You can change those variables at the top of the script. Finally, flash the code to your Roomba, and you’re done! :)

Step 6.5: Programing (Serial)

For me, the main purpose of building this Roomba was to be able to use it as a base for future projects, so I added a script for optional control over USB Serial. This will make it much more scalable if I decide to make future projects involving the Roomba. It will also allow me to interact with the Roomba using a more powerful microcontroller like a Raspberry Pi or a Jetson Nano. Here is the code to control the Roomba with serial.

/*
Serial Controlled Roomba arduino code :)
Made with <3 by Charlie Gray
medium.com/@charliegray.dev
*/
// Motor A connections
int enA = 2;
int in1 = 8;
int in2 = 7;
// Motor B connections
int enB = 3;
int in3 = 5;
int in4 = 4;
//Serial stuff owo
String serialData;
//Power going to motors (-255-255)
int leftPower;
int rightPower;
void setup() {
// Set all the motor control pins to outputs
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);

// Turn off motors - Initial state
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
// Set speed to 0
analogWrite(enA, 0);
analogWrite(enB, 0);
//Open serial stuff
Serial.begin(9600);
Serial.setTimeout(10);
}
void loop() {
// put your main code here, to run repeatedly:

}
//on serial event
void serialEvent(){
//Get Serial string
serialData = Serial.readString();
if (serialData.charAt(0) == '!'){
return;
}

// Parse Speeds
leftPower = parseSerialL(serialData);
rightPower = parseSerialR(serialData);
Serial.print("!" + String(leftPower));
Serial.print("!" + String(rightPower));

//Left motor
//Set L Speed

analogWrite(enA, abs(leftPower));
//Set L Direction
if (leftPower > 0){
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
}
else{
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
}
//Right motor//Set R Power
analogWrite(enB, abs(rightPower));

//Set R Direction
if (rightPower > 0){
digitalWrite(in3, HIGH);
digitalWrite(in4, HIGH);
}
else{
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
}

}
//Gets L value in string
int parseSerialL(String serialData){
serialData.remove(serialData.indexOf(","));
return serialData.toInt();
}
//Gets R value in string
int parseSerialR(String serialData){
serialData.remove(0,serialData.indexOf(",")+1);

return serialData.toInt();
}

To use the script, send the Arduino two integers separated by a comma. The first value will be the power sent to the left motor while the second value will be the power sent to the right motor. Make sure that the values are between -255 and 255.

And you’re done!

Thank you so much for reading about my project. I look forward to seeing your own creations and feedback in the comments below \ (•◡•) /

--

--

Charlie Gray
The Startup

Computer Engineering + Entrepreneurship Student @ SCU 🧑‍🎓 Software Developer 🧑‍💻 Audio Technician + Engr. 🎧 Interested in Digital Media and Startups 📊