This Instructable will focus on how to give a dead Roomba a new brain (Raspberry Pi), eyes (Webcam), and a way to control everything from a web browser.
There are a lot of Roomba hacks that allow control via the serial interface. I have not been fortunate enough to come across a Roomba that has current firmware or working motherboard. Either the Roomba is too old or the Roomba is dead. I found the Roomba I used for this project in a local thrift store bargain bin for $5. It still had a decent battery, but a dead motherboard. (I also found the webcam at the same thrift store for around $5). All I'm using from the original Roomba are the motors, chassis, and battery. You do not have to use a Roomba for this project. You could use different motors, wheels, and chassis if you like. I just fancy turning a piece of junk into something usable.
For this build I used the Raspberry Pi Model 3 A+ and a Riorand motor controller. I am using code from the Dexter Industries Browser Controlled Robot that I modified. The Dexter Industries version sets up the Pi as a websocket server that allows you to control their robot (brick pi platform) from a client html file running another computer.
I have changed the code use the GPIO pins and added a way for the Pi to shutdown when a button is clicked / when the escape key is pressed in the browser. I also made some changes to the control web page to allow viewing a motion stream through an iframe, while controlling the robot all within a single page. I set the Pi up with a static IP to host the client file so I could connect using any computer or device on my network.
I am documenting the process here in the hope of showing how to create a simple, inexpensive base robot.
- Raspberry Pi 3 A+ (Adafruit Link) $30
- Riorand Dual Motor Driver Controller H-Bridge (Amazon Link) $22
- 12V Battery for Motors (Amazon Link) $19
- 5V Battery for the Raspberry Pi (Amazon Link) $10
- 8GB Micro SD Card (Amazon Link) $5
- Jumper Wires (Amazon Link) $7
- Roomba 500 series
.All together just under $100.
Step 1: Install Raspbian and Setup a Static IP Address
I used Raspbian Stretch Lite. I didn't see a need for the desktop, but you may install the desktop version if you prefer.
I am going to assume you already know how to install Raspbian. If you you need help, you can find the Raspberry Pi Foundation's guide here.
Once you have Raspbian up and running, login and run the raspi-config program.
pi@raspberrypi:~ $ sudo raspi-config
Setup your WiFi connection in raspi-config
2 Network Options
Select a Country, enter your SSID, and enter your passphrase
Setup SSH in raspi-config
Once I did the initial config, I used SSH to set everything up headless. (You could skip this if you use a monitor. It was easier for me to make changes to the code without having to stop the robot and plug it into a monitor.)
Back at the raspi-config main menu
5 Interfacing Options
Back at the raspi-config main menu select
Verify you are connected to your network
pi@raspberrypi:~ $ ifconfig
You should receive an output similar to this. (Note the IP address; you may need it later. e.g.192.168.1.18)
wlan0: flags=4163 mtu 1500 inet 192.168.1.18 netmask 255.255.255.0 broadcast 192.168.1.255 inet6 fe80::c74f:42ec:8cd3:2fda prefixlen 64 scopeid 0x20 ether b8:27:eb:6a:a4:95 txqueuelen 1000 (Ethernet) RX packets 44396 bytes 5847726 (5.5 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 30530 bytes 39740576 (37.8 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Verify you can reach the internet.
pi@raspberrypi:~ $ ping google.com
You should receive an output similar to this.
PING google.com (126.96.36.199) 56(84) bytes of data. 64 bytes from dfw06s48-in-f14.1e100.net (188.8.131.52): icmp_seq=1 ttl=54 time=18.2 ms 64 bytes from dfw06s48-in-f14.1e100.net (184.108.40.206): icmp_seq=2 ttl=54 time=19.4 ms 64 bytes from dfw06s48-in-f14.1e100.net (220.127.116.11): icmp_seq=3 ttl=54 time=23.6 ms 64 bytes from dfw06s48-in-f14.1e100.net (18.104.22.168): icmp_seq=4 ttl=54 time=30.2 ms ^C --- google.com ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3004ms rtt min/avg/max/mdev = 18.209/22.901/30.267/4.715 ms
Setup a Static IP
To be able to consistently connect to your robot using the same address on your network, you will want to set up a static IP.
Get your current network address e.g.192.168.1.18
I am using the address that was automatically assigned by DHCP when the Pi connected to my network. You can change this to whatever you like as long as it matches up with your network and doesn't conflict with any other assigned addresses.
Open dhcp.conf in a text editor. (I use nano)
pi@raspberrypi:~ $ sudo nano /etc/dhcpcd.conf
Scroll down to #Example static IP configuration and change the following lines.
#interface eth0 #static ip_address=192.168.11.13 #static routers=192.168.11.1 #static domain_name_servers=192.168.11.1 22.214.171.124
Change to match your network and remove the # at the beginning of each line.
interface wlan0 static ip_address=192.168.1.18 static routers=192.168.1.1 static domain_name_servers=192.168.1.1 126.96.36.199
Save and exit.
Reboot and connect to the Pi via SSH
pi@raspberrypi:~ $ sudo reboot
ian@computer:~$ ssh email@example.com
Enter your password (the default is raspberry).
You should be now be at your Pi's command prompt.
Step 2: Install and Configure Motion
Motion is a program used in a lot of security camera / webcam projects. Motion has a lot of features. However, we are setting it up to simply stream video from the webcam to port 8081.
Test Your Webcam
Plug in your webcam and list connected usb devices (You may need to reboot after connecting).
pi@raspberrypi:~ $ lsusb
You should get an output similar to this. Note the Logitech C210.
Bus 001 Device 002: ID 046d:0819 Logitech, Inc. Webcam C210 Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
If your camera doesn't show up, it might not be compatible or you may need to install additional drivers.
pi@raspberrypi:~ $ sudo apt-get update
pi@raspberrypi:~ $ sudo apt-get install motion -y
Once Motion is installed edit the config file.
pi@raspberrypi:~ $ sudo nano /etc/motion/motion.conf
Change the following lines to match below.
daemon on width 640 height 480 framerate 100 output_pictures off ffmpeg_output_movies off text_right stream_port 8081 stream_quality 100 stream_localhost off webcontrol_localhost off
Start the Motion Daemon at Boot
Open the /etc/default/motion file.
pi@raspberrypi:~ $ sudo nano /etc/default/motion
Save the file and exit
pi@raspberrypi:~ $ sudo reboot
After the Pi has rebooted open the browser and verify that you have video streaming into the browser on port 8081
Troubleshooting the Motion Daemon
I ran into problems getting the motion daemon to start at boot while I was trying out different options in the motion.conf file.
If you start motion before the motion daemon in Raspian Stretch, you will probably run into issues getting it to start at boot later on. Running "sudo motion" without configuring the daemon to do it first creates the directory /var/log/motion without granting write permission to the user.
Step 3: Install Apache and Setup Web Control Page
Apache is the web server for the robot's control web page. We are going to replace the default Apache index.html file with a file downloaded from github. You will also change a couple of lines of code to display the motion video stream and assign where to send the commands to control the robot.
Install Apache and Git
pi@raspberrypi:~ $ sudo apt-get install apache2 git -y
Once apache and git are installed download the files.
pi@raspberrypi:~ $ git clone https://github.com/stuntunicorns/roombarobot.git
Open the roombarobot directory.
pi@raspberrypi:~ $ cd roombarobot
Replace the index.html file in the /var/www/html folder with the index.html file in the /home/pi/roombarobot
pi@raspberrypi:~/roombarobot $ sudo cp index.html /var/www/html
Edit the index.html file
Open the index.html file with a text editor.
pi@raspberrypi:~/roombarobot $ sudo nano /var/www/html/index.html
Locate the these two lines
<iframe src="http://YOURIPADDRESS:8081" width=640px height=480px frameborder="0">
var host = "ws://YOURIPADDRESS:9093/ws";
Change "YOURIPADDRESS" to the static IP address you setup in Step 1 and save the file.
<iframe src="http://192.168.1.18:8081" width=640px height=480px frameborder="0">
var host = "ws://192.168.1.18:9093/ws";
On another computer, open up a browser and enter your Pi's IP address. You should see the control web page with a box on the left, streaming video from your webcam, and the web control buttons on the right.
Step 4: Setup and Test the Code
Install PIP and the Tornado Library
pi@raspberrypi:~ $ sudo apt-get install python-pip
Install tornado library
pi@raspberrypi:~ $ sudo pip install tornado
Start the Roombabot Program and Test the Connection
Start the roombabot.py program
pi@raspberrypi:~$ sudo python /home/pi/roombarobot/roombabot.py
Once running, you should see "Ready" in the terminal. Open the control web page in a browser and click connect. Then click any of the directional buttons on the page. You can also use the arrows keys on your keyboard as well.
You should see an output in the terminal similar to this.
Ready connection opened... connection opened... received: u 8 Running Forward connection opened... received: l 6 Turning Left connection opened... received: d 2 Running Reverse connection opened... received: r 4 Turning Right
Press ctrl+c to stop the program.
Once you are done testing power off the Pi.
pi@raspberrypi:~$ sudo poweroff
I have noticed a problem with the shutdown button on the control web page. Sometimes the shutdown button does nothing when it is clicked or tapped. I have not been able to figure what is causing this, but there is a workaround. If you are wanting to power off the robot and the shutdown button doesn't work, reload the page, click / tap the connect button and then click / tap the shutdown button. It should power off.
Step 5: Assembly
As mentioned before, you do not have to use a Roomba for this project. Anything with two motors, two wheels and a frame would work. I took the Roomba apart and removed everything except the wheel modules and the battery.
The Roomba's wheels and motors are housed together in a removable module. Each module has a blue outer housing containing the motor, gearbox, wheel, suspension spring, and interface board.
Each interface board has six wires running to it. There are two wires(Red[ + ], Black[ - ]) that rotate the motor, one data wire for a hall effect sensor, one wire for the wheel drop switch, one 5V wire, and one GND wire to power the sensor. You will have to take the module apart to access the interface board. I removed everything back to the motor and soldered new [ + ] and [ - ] wires to the motor (see photos). It is up to you whether you want to preserve the sensors or not.
Once you remove the vacuum portion, the Roomba's weight gets thrown off. If you do not remove the springs the Roomba will sit at an angle. I originally removed these, but then added them back when I found it was struggling to roll over carpet. Putting the spring back fixed the problem.
Wiring the motors to the Motor Controller
The motors are facing away from each other. That means that in order to drive the Roomba in a forward direction, one motor will have to rotate forward while the other rotates backward. I did not think much about this until after I wired everything up. I ended up just writing the code around how I initially wired the motors. This was a happy accident because whenever the Raspberry Pi powers on/off, there is voltage output to the GPIO pins. The way I have things wired up, the Roomba spins until the Raspberry Pi has booted up (about thirty seconds) and spins when shutdown until the power is removed. If wired differently, it would would potentially roll forward / backward which would be irritating. I plan to eventually fix this with a simple switch for the motor controller.
Wiring up the Motors and Battery to the Motor Controller
Power- - - - - - - - - - - - - - - - 12V [+]- - - - - - - - - - - - -Roomba Battery [+] Motor 2- - - - - - - - - - - - - - - Black- - - - - - - - - - - - - -Left Motor [-] Motor 2- - - - - - - - - - - - - - - Red- - - - - - - - - - - - - - -Left Motor [+] Motor 1- - - - - - - - - - - - - - - Black- - - - - - - - - - - - - -Right Motor[-] Motor 1- - - - - - - - - - - - - - - Red- - - - - - - - - - - - - - -Right Motor[+] GND- - - - - - - - - - - - - - - - - 12V [-]- - - - - - - - - - - - -Roomba Battery [-]
Wiring the Motor Controller to the Raspberry Pi
Motor Controller Pins Wire Color(see photos) Raspberry Pi Pins GND- - - - - - - - - - - - - - - - - Black- - - - - - - - - - - - - -GND PWM 2- - - - - - - - - - - - - - - - Blue - - - - - - - - - - - - - -GPIO 18 DIR 2- - - - - - - - - - - - - - - - Green- - - - - - - - - - - - - -GPIO 23 PWM 1- - - - - - - - - - - - - - - - Yellow - - - - - - - - - - - - -GPIO 24 DIR 1- - - - - - - - - - - - - - - - Orange - - - - - - - - - - - - -GPIO 25 5V - - - - - - - - - - - - - - - - - Red- - - - - - - - - - - - - - -5V
Mounting the Electronics
There isn't a lot that goes into putting everything together. I stripped the roomba down its chassis. With the cover removed, you can easily clip off the existing plastic standoffs and drill holes to mount the electronics. There are existing ports for running cables from the motors. If you are using the stock Roomba battery, there is already a cutout for access to the battery terminals.
I used separate batteries for the Raspberry Pi and the motor controller. The Pi's battery is just a 5V battery pack used to boost cellphones. For the motor controller I used the original Roomba battery that came with it. The battery terminals are not labeled, so it is best to check the the voltage with a voltmeter before you you wire it up to the motor controller. To attach the wires to the Roomba battery, I used four neodymium magnets (see photos). I soldered two of the magnets to the wires and the other two I stuck to the battery terminals. Soldering demagnetizes the magnets. However, the coating on the outside can still attach to the magnets on the terminals and conduct electricity. This makes connecting and disconnecting the battery a piece of cake.
Once you have everything together, verify that you have everything wired up correctly, prop your robot up on something (so it doesn't roll away), and power it on.
Login and start the roombabot.py program
pi@raspberrypi:~$ sudo python /home/pi/roombarobot/roombabot.py
Go to the web control page and test it out. If everything is wired up correctly, the wheels should rotate in the corresponding direction when the buttons are clicked / the arrow keys are pressed (don't forget to click connect).
Step 6: Starting the Python Code on Boot / Finishing Up
The last thing we need to do is tell Raspbian to start the python program on boot. To do this we are going to make script and schedule it to run at reboot using crontab.
Create the Script
Create a new script file called startrobot.sh in the pi user directory
pi@raspberrypi:~ $ sudo nano startrobot.sh
Copy the following lines into the file
#!/bin/sh #startrobot.sh cd / cd /home/pi/roombarobot sudo python roombabot.py cd /
Save the file and exit
Make the startrobot.sh file executable
pi@raspberrypi:~$ sudo chmod 755 startrobot.sh
Test it out (Press ctrl + c to stop)
pi@raspberrypi:~$ sh startrobot.sh
Edit the crontab file
pi@raspberrypi:~$ sudo crontab -e
Add the following line to the bottom the file
# m h dom mon dow command @reboot sh /home/pi/startrobot.sh
Save and exit
The roombabot.py program should now start when the Pi is rebooted or power cycled.
At this point you should have a functional robot that you can control using the browser from any device on your network. I have taken this a little further since the original build and setup a VPN to be able to access the robot when I am away from home. I intend to make some additional changes in the future. I plan to make it autonomous and possibly follow movement while still being able to take over the controls when I want.
Thanks for checking this out!