Great robots deserve a great remote controller. A proper, well designed controller can speed up project development and in some cases can even improve robot performance. In this post I will describe how I design, make, test and improve a customized RC remote controller.
I call this project “Omote” – Oscar’s Remote controller. (Just to clarify, it has nothing to do with the Japanese word Omote which in Aikido, it could mean the act of throwing your opponent in front of them, thanks to John Matsson pointed that out, haha)
The Omote Goal!The goal of this project is to create a remote controller that can be alternative to a RC transmitter or similar commercial controllers. The remote controller we build would be able to control, manipulate our robots, flying planes like quadcopter, even can be used for PC gaming like car racing games. There are quite a lot of existing commercialcontrollers like RC transmitters, but they tend to be very expensive and probably not optimized to the project we are doing.
We are going to focus on
- operation distance
I will divide this project into these tasks. And hopefully at the end we will have a reliable working remote controller.
- Hardware and Software
- Communication Protocol Design
- Max Performance Testing
Remote Controller Hardware And ElectronicsI tried to use parts that are as simple and cheap as possible. But what components to pick largely depend on what kind of project or robot you are trying to control. For example for a simple robotic tank, you might want to be able to make it go forward and backward, turn left and right. So four push buttons would be enough to accomplish this. But if you want to have better user experience, a joystick would be better. If there is a canon on the tank, you probably also want a button for shooting. If there is a head light, you will need a toggle switch. You should see where this is going.
For my remote controller, I am not designing it narrowly for some particular projects, but for more general usage. Therefore I used a combination of different types of control components. This is what it looks like on drawing.
Here are the parts I used:
- Toggle Switch x 4
- 2-Axis Joystick x 2
- Potentio Meter x 4
- Push Button x 6
- LED x 3
- LCD x 1
- Arduino Mega x 1
- Cables x many
- Small Breadboard x 2
- Ciesco XRF Wireless Modules x 2
I picked the Arduino Mega because I know Arduino very well. The Mega provides more enough Analogue and Digital pins, which the UNO failed.
I was thinking of getting a 3 Axis Joystick, but they are shockingly expensive! The cheapest one I found was 30 Euros which is literally just a 2 axis joystick with a potentiometer. So I went for the cheap option of getting these two parts separately and it costs me only 3 pounds.
Inputs of These ComponentsToggle Switch, Push Buttons return true when pressed (1) and false when it’s not (0). Potentiometer has a max resistance of 10K which give a value between 0 to 1023. 2-axis joysticks are basically just two potentiometers, which gives you two values between 0 to 1023 for X and Y axis. It might be a good idea to test and make sure you understand how these components work before doing any further. The picture shows the testing setup I had.
Soldering and AssemblingAssembling wasn’t particularly difficult as everything went quite smoothly as planned, though I had to turn some parts around to fit the actual dimension. Here are some soldering work I did on the parts:
Male to Female cable made by myself, they are very handy to have.
The Arduino Mega is attached to the base board. And the white front panel finished using Polystyrene.
This is what happened when I put every components on the panel, it’s a mess! But when I turned it over, I felt much better, LOL.
It took me about 2 to 3 hours to finish the final hardware testing after the assembling. And that’s it! All the parts are working and ready for programming!
Some Assembling AdviceMake sure you have all sorts of jumper cables ready: Female to male, male to male and female to female. And make sure they are long enough, generally you want them to be twice as long as the width of your remote controller, so you can have the panel and base laid down naturally side by side while you are connecting the components. Otherwise you will have a really painful time doing that. For trouble shooting, it’s even worse when short cables are used.
Carry out testing right after you connect a component. It would be a nightmare to have all the parts connected and realize nothing works!
Software OverviewSoftware for this project consists two parts, one for the remote controller (which I call “Host” later on), and the other for the robot (“Client”).
As for software for the remote controller, the idea is quite simple (see state flow chart). But I can foresee to achieve what is required, the programming can get very sticky and complicated. It is responsible for initializing connection, re-establishing broken connection, encoding commands and provide feedback from client to the user. There will also be a LCD menu system to provide current state information of the controller, allow real time parameter adjustment, calibration and so on.
On the client side (robot side), I will be writing a library for it which will act as an interface between the robot and the controller. It is responsible for accepting connection, decoding commands and communicating back.
Arduino Function For Fundemental CommunicationAs for sending data, because we are using the serial pins on the Arduino, I will be using Serial.write() for sending data. This function sends one byte of data which means the max value we can transmit is 255 each time we call this function.
You might be wondering what we should do about the inputs from the potentiometers and joysticks, as they have a max value of 1023. We have two options, one is to downgrade resolution to map the value between 0 and 1023 to a new value between 0 and 255, which can be fit in one byte. Second option is to treat the number in term of bits (1024 can be represented with 10 bits), which can be send separately as two packets. When they arrived at the client side, we put them back together as one number.
As you might know, for a single value, sending two bytes would take longer than one byte. Although it’s less accurate, we sometimes don’t need that level of accuracy and prefer smaller latency. So I am planning to adopt both methods into the remote controller communication, so user can select which way to go depends on the situation.
And that takes us into the next section – the protocol. How do we design and put together a command from these raw input values for transmission? It’s going to be a wordy topic, so I will talk about this in the next post.
If you want to discuss or share your ideas, you can post something in our forum here.