In the third and final part of this series, we will add the last part our robot: a remote control. In addition, minor improvement has been made to the legs so they’re more stable on any surface of the substrates. First, we’ll go over slightly modified leg mechanism then connect HC-05 Bluetooth to Arduino for wireless control. Lastly, we’ll write a Processing app so that we don’t have to use written commands for every movement of the ArduPod.
If you’re new to this project, please refer back to Part 1 and Part 2 of the project before you proceed further: Arduino Hexapod PART 1- Mechanics and Wiring and Arduino Hexapod PART 2: Programming.
The biggest problem I personally faced with the hexapod was that the legs were really unstable on smooth surface. This would usually be easily fixed by adding some sort of non-slipping material to the leg, however, the surface that is touching the ground is too small. Making the area where the leg touches the ground larger would help greatly against slipping and also improve overall leg stability.
Figure 1. The old leg (left) and the new one (right)
In the above picture you can see a sort of bottom support added to the leg. Just as the rest of the parts, this was printed on a 3D printer using black ABS. The model can be found with the rest of the parts on my GitHub.
Figure 2. The new part that was added to the leg. Notice the dark green non-slipping layer at the bottom.
Now we can add non-slipping layer to the feet. I used a green gel pad. It doesn’t slip even when under very light load. If you don’t have access to this exact material, there are few other options (e.g. rubber). Try and see which one works the best for your robot. Then cut six circles out of the stuff and glue them to the feet and we’re done!
The next improvement I made is tad bit more complicated than the feet. With the current system, the servos are only connected to the leg parts in one place. This creates a weak spot in the structure that will have to bear most of the load and is likely to break at some point. In Figure 3, you can see the current attachment system and next to it, the new one.
Figure 3. The old attachment system (left) and the new one (right)
Notice that the new part allow the servo to be attached in two places: in the axis shaft (as it was before) and at the opposite side of the servo. When the small pad with a knob is glued to the servo, it will provide additional support to the servo. Now the servo is connected at two points, distributing the load between them. The result is much better movement control.
Now that we got the legs out of the way, let’s connect HC-05 Bluetooth module which enables wireless control of the robot. Since all the controls are already being handled by the Arduino, our main task here is to send commands to it.
There are several major options on how to communicate with Arduino wirelessly:
So, we’re going with Bluetooth for this project. I used HC-05 Bluetooth module, mainly because it’s the most affordable and most common one out there. Since the module acts like a serial COM port, connecting HC-05 to Arduino is super easy, as you can see in the following Fritzing schematic.
Figure 4. Wire diagram of HC-05 Bluetooth module and Arduino Mega
Figure 5. Connecting HC-05 Bluetooth module to Arduino Mega.
The module is powered from the Arduino. The HC-05 TX pin is connected directly to RX1 pin on Arduino. However, since the HC-05 logic level is 3.3 V and the Arduino runs on 5 V, there has to be a simple voltage divider on the HC-05 RX pin to lower the voltage. The value of R1 should be 1 kΩ and the value of R2 can be either 1.8 kΩ or 2.2 kΩ. I used 2.2 kΩ since I couldn’t find any 1.8 kΩ resistors, but the module should work just fine with either of them.
At this point, Arduino has no idea that it’s communicating through a Bluetooth module. From its point of view, this is the exact same situation as when connected by a cable. This is why we don’t need to set anything up on Arduino as the module will take care of everything – at least in the most common situations.
The next step is to set up HC-05 Bluetooth module. The PC I’m using doesn’t have a built-in Bluetooth interface, so I’ll have to use a USB Bluetooth adapter.
For Windows 10, please refer to the past tutorial which provides step-by-step guide on connecting HC-05 to PC: Make Your Own Arduino RFID Door Lock – Part 2; Step 1:Connecting the bluetooth)
First, we’ll have to pair the PC with the Bluetooth module.
At this point, it’s a good idea to verify that everything is connected properly. Start the Arduino IDE, and upload the following sketch:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
void setup() { Serial1.begin(9600); while(!Serial1); Serial1.println("Hello world!"); } String input; void loop() { if(Serial1.available() > 0) { input = Serial1.readString(); Serial1.println(input); } } |
After the uploading is finished, go back to “Devices and Printers” and find the HC-05 module we paired with the PC before. Right click on the HC-05 icon and go to the tab “Hardware”. There, you’ll find the COM port number Windows assigned to the module. This will be the COM port we’ll use to communicate with ArduPod. Return to Arduino IDE, select the correct COM port in Menu > Tools > Ports and start the Serial Monitor. Type a few characters and press Enter. These characters will be sent to the COM port you just specified and should appear back as a response from Arduino.
Everything working so far? Great job! Now that we’re done with the “difficult” stuff, let’s move onto something more fun: writing a graphical app in Processing.
Since you’re reading this article, I will assume that you already have basic understanding of Processing language. Even though Processing looks very similar to Arduino language – even the setup and loop/draw main functions are the same – they’re NOT the same. Arduino language is almost identical to C++, whereas Processing is based on Java. Therefore, even though the syntax is similar, there are major differences between the two. I’ll try to describe the app I created to the best of my abilities below.
Obviously, we want the app to have a nice Graphical User Interface (GUI). Since Processing is heavily focused on drawing shapes (hence the name of the main loop function – draw), this would be really easy for a graphics designer. However, my skill in this field is almost non-existent, so I’ll resort to using a library to help me create a cool looking GUI.
There a few libraries for Processing which offer different designs, but the one I personally like the most is the controlP5 library. You can check out this website that details more information about the library here. Also, the library is filled with examples on almost everything. Another useful thing you can find on the site is the complete JavaDoc reference. The download version on the site is a bit outdated, so I would strongly suggest you use Processing Library manager. We’ll be using the newest Processing version at the time of writing, Processing 3.2.3. The app as well the source code are available on my GitHub.
Now let’s take a look at what the app actually looks like.
Figure 6. ArdupodRemote Processing app
Well, that’s quite a few controls, isn’t it? There’s the big grey mystery box on the left, and lots of buttons to press and a weird thing that looks a bit like radar on the right. As you can see I marked all the parts with a red number, this is what each control does:
Figure 7. Example scan output. The scanned area was a narrow hallway.
This is a quick and easy way to get an idea about the surrounding environment, even without a camera.
As you might have guessed, this app is much more complex than it really needs to be. I simply can’t go line after line trying to explain everything, so instead we’ll take a look at the most important chunks of the code: control event handling, the serial communication, and the Arduino side.
One of the first thing we need to ask when programming an app with GUI is “what happens after you click a button?” Luckily, the controlP5 library takes care of most things for us. Let’s take a look at a simple scenario in the following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
import controlP5.*; ControlP5 cp5; void setup() { size(400,400); cp5 = new ControlP5(this); cp5.addButton("click me!") .setValue(0) .setColorForeground(color(215, 0, 0)) .setColorBackground(color(175, 0, 0)) .setColorActive(color(255, 0, 0)) .setPosition(100,100) .setSize(200,200) ; } public void controlEvent(ControlEvent theEvent) { if(theEvent.getController().getName().equals("click me!")) { println("Why would you trust a big red button?!"); } } void draw() {} |
Figure 8. controlP5 example
First, we have to import the library and create an instance of the controlP5 class. Then, inside setup function we create new button called “click me!”. The final part is the controlEvent function. This function will be called every time any of the controlP5 elements create an event – in our case, every time the button is clicked. Then we can check which element caused the event and in case it was our “click me!” button, it will print some text. The controlP5 library is full of examples on how to use the many control elements it offers, so we’ll just take a quick look at what is actually in the remote control app.
The basic event handling is done exactly as in the example above – by using controlEvent function. Added to that are two functions – keyPressed and keyReleased that handle input for keys W,A,S and D to allow movement control with keyboard. You might notice that unlike the example, none of the control elements are set up inside the setup function. All of these were moved to the second tab called guiElements and are called with setupGui function. Therefore, there is less code in the main ardupodRemote tab. Usually, it’s a good programming practice to separate chunks of code that handle different things, because it’s easier to read and understand the code.
Now that we have a basic understanding of how the graphics and the controls work, we can try to figure out how to make sense of all the data that will be going through the serial port.
We already set up the Bluetooth on both sides, but we still need to create some sort of “protocol” for both sides to follow, and we need it to be as short and quick as possible. Since all the data that come through serial port are interpreted as String data type on both sides, I created an extremely simple “packet” structure. The structure of the “in” packets (the packets that Arduino sends to PC) looks like this:
XYpayload
The first two characters, X and Y are the status codes for that packet, and they let the app know what sort of information the payload contains. For example, if the app receives packet “82Starting PWM … “, it will write the following to the serial output box: “[INFO] [SETUP] Starting PWM … “. All the currently implemented codes are in the following table.
0 | |
1 | [ECHO] |
2 | [SETUP] |
3 | [TRACE] |
4 | [SR04] |
5 | [PWM] |
6 | [ERROR] |
7 | [WARN] |
8 | [INFO] |
9 | > |
10 | [CMD] |
11 | [APP] |
Note that in the app, code 40 is reserved for scanning data and code 41 for single distance measurement.
The structure of the “out” packets (the ones that the app sends to Arduino) is bit simplified:
Xpayload
Just as before, the first character X will determine how the payload will be processed. This time, however, we will only use a few commands.
t | turn the sensor to the position specified in payload |
m | measure distance |
n | start the scan |
w[s] | walk/step forward |
a[s] | turn/step left |
s[s] | walk/step backward |
d[s] | turn/step right |
So far we managed to connect Bluetooth to both the Arduino and the PC. We also wrote an app with a cool GUI and created a protocol to communicate with the Arduino, but there’s still something missing: we may be sending data but the Arduino isn’t listening, yet. We need the Arduino to run a sketch that will periodically check the serial port and if there are data available, then process them. Let’s take a look at the sketch we used before to verify the Bluetooth connection.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
void setup() { Serial1.begin(9600); while(!Serial1); Serial1.println("01Hello sir!"); } String input; void loop() { if(Serial1.available() > 0) { input = Serial1.readString(); switch(input.charAt(0)) { case ‘n’: //ultrasonic scan case ‘m’: //measure distance //and so on... } } } |
Once we have the data in the input variable, we can do all sorts of thing with it. For example, if we want to check which type of command just arrived, we can use input.charAt(0). This built-in function will return the first character of the string input, which will correspond to one of the commands in the table above.
Note that usually, you would have to disconnect the HC-05 module every time you want to upload a new sketch to Arduino, However, since we’re using Arduino Mega, we have a total of 4 separate hardware serial ports available! So, we can just connect the Bluetooth to one of the remaining ones and we can use them simultaneously.
Another thing to keep in mind is that connecting Arduino to the PC via Bluetooth might not always reset the Arduino, unlike connecting by USB. To start up properly, you have to manually push the RESET button on the Arduino!
Hexapod is a fairly complex project. As always, there’s room for improvement. Right now the only sensor on board is the ultrasonic rangefinder, but since we have so much free processing power with Arduino Mega we can add other sensors for more advanced functionalities.
That’s it–you made it through the last tutorial of ArduPod! The three-part tutorials are supposed to be as comprehensive as possible. If you have any questions or suggestions for improvements, please feel free to share your thoughts on my GitHub. You can go to the ‘Issues’ tab in the ArduPod repository and open a new issue. While you’re at it, you can leave a star there if you liked this project. And of course, you decide to build your very own ArduPod, remember to share your creations with the world!