I love robot arms. I like that you just need some simple mechanical parts, some servos or motors a good software and you can get a device that is not just spectacular and fun but actually really useful, too. I wanted to build one since I had a robotics course that I really loved.
You can learn a lot when you build a robot arm, so I think this is a great intermediate level project to deepen your knowledge in robotics. Lets start!
You can buy robot arms from about 20$. For experimenting, I wanted to start with a cheaper one. Later I'll build or buy a more serious robot arm but for now I will work on this 25$ DIY robot arm from Banggood.
This is a 4DoF (Degrees of Freedom) robot arm, where 3 servos are used for moving and one is for the effector (I called it gripper in the project). It means that the gripper can be moved into any position in a specific area but its angles can't be changed. This is a significant limitation, but it's okay for now and it is still good for lots of things.
The DIY kit came with 4 servos, so actually you get every component to build the robot arm besides a controller. These servos are not bad, but I preferred these:
These servos are faster than the blue ones and these are using metal gears instead of plastic.
The robot parts came in 4 plastic sheets. You have to remove the parts from these sheets.
The robot arm kit made up of a bunch of parts. I recommend you to watch the following video. In this video a Russian guy is building the same type of robot arm. The building part starts at 7:43.
I got a link on the package about how to build the robot arm, but it was very low quality in both images and instructions. That video is way better. Possibly you can figure out what is what, but if you do this you'll end up in an almost infinite loop of assembly, disassembly, reassembly.
Be very very careful when you insert the servos. This design with this kind of plastic tends to break very easily when you are tightening the screws. The optimal tightness of the screws is also important on some other parts of the robot. Make them too tight and you can't move the segments of the robot arm with the servos.
After some building, you'll end up with your very own robot arm.
The positioning servos has a long enough cable, but the gripper needs a lot longer one. I disassembled that servo, desoldered the old cable and I used an at least twice as long cable.
All right, the robot arm is ready, but it is more than likely that you want to control it somehow. I needed a microcontroller for that and I chose my Arduino 101 for this job.
It is the only official Arduino board that uses an Intel microcontroller (Intel Curie). It has built-in gyroscope and accelerometer. It also has Bluetooth, so it leaves me the possibility to control the robot through BLE in the future. Another very useful feature of this board is how the serial communication works. Unlike most Arduinos, the USB serial and the UART on pin 1 and 0 (TX and RX) are not the same. It has its benefits like I don't have to disconnect any other communication circuits from pin 0 and 1 when I reprogram the Arduino. It is also useful for debugging purposes.
If you want to use the USB port's serial then you have to use 'Serial' and if you want to use the GPIO0 and GPIO1 pins then you've got 'Serial1'
The Arduino 101 has 4 PWM capable GPIOs (GPIO3, GPIO5, GPIO6 and GPIO9) and I used all of them to control the servos.
My robot arm can be controlled through serial (Serial1 to be specific). I used my newest communication module, the WIZ750SR for this purpose.
This is a small Ethernet module with a Cortex-M0 MCU. In its basic functionality it is a Serial to Ethernet module, but you can easily reprogram the module to satisfy your needs. You can turn this board into an I2C to Ethernet board if you want to.
A very cool feature is the onboard TCP server (or client). Using the TCP server, you can control the Arduino remotely, just like you would do through USB serial, but from anywhere in the world! On the Arduino's side it is completely transparent. You don't need to add any extra code to your sketch to use this module.
I also have a WIZ750SR-TTL-EVB evaluation board. I could power the WIZ750SR and has a debug USB port, but I didn't use it besides some early experimenting.
Both the Arduino 101 and the WIZ750SR are using 3.3V and thus I didn't have to use level shifting for the TX and RX pins. The Arduino is also powering the Ethernet module from its power supply. The circuit is very simple and you can find it in the Schematics section of this project. The servos have their own 5V power supply.
To use this board you have to configure it first. I won't re-document this part because the WIZnet guys already done that here and you can be sure that you always get the latest documentation there.
Their documentation is great but I have some good to know information and I had some (solved) issues that worth sharing.
Firstly, you can power the board from the evaluation board's USB port, but besides that, this port is used mainly for debugging and flashing. I believe that you can't communicate with the TCP server of the WIZ750SR using the USB port, but you'll receive debug information if you connect to this COM port. It caused me some confusion at the beginning as I didn't know what to expect.
Secondly, if the blue LED is turned on when the WIZ750SR is connecting to your network, then you're board should be working correctly, continue with the Configuration Tool, it should find the board.
My biggest issue happened at this point when I tried to search for the device in the Configuration Tool. At the first time it worked wonderfully, but then I didn't have time so I stopped there. After two weeks I tried to do it again, but it couldn't find the board anymore under multiple OS-es and computers on multiple networks.
I did a reflash through the debug USB port of the evaluation board with the latest firmware and it worked. My Windows PC still couldn't find it, but the Python version under Ubuntu could. I'm not sure what was the problem, but these steps finally solved my problem. After successfully configuring the WIZ750SR, my Windows PC could also find it again so I continued the work.
As I read, VMs with their virtual network adapters call also mess up the searching, so if you experience some problem with searching you should take a look at that.
A great tool for testing TCP communication is NetCat. Using this software you can connect to the TCP server on the WIZ750SR. After you install NetCat use this command to connect:
nc [tcp_server_ip] [tcp_server_port]
After that you can directly send and receive data from the WIZ750SR. I used this tool a lot.
To move a robot arm, you have to tell the controller what you want. The simplest way is to directly update all servos' angles. Updating the joint angles can be done with some trial and error and it can actually work well.
Trivia: there's an issue with controlling a robot arm using joint angles: it can be quite difficult to find the optimal joint angles for a specific X Y Z coordinate with optionally Roll, Pitch and Yaw angles (world coordinate). Getting the world coordinates from joint angles and segment length is a very simple calculation, but getting the joint angles from world coordinates is a much more complex process. A solution called Inverse Kinematics is the tool to do just that.
In my next robot arm project I'll use inverse kinematics to control the robot arm with world coordinates, but for now I'll control the robot using only joint angles.
The speed of the system is a key point here. The servos are very fast but they still need time to reach the received position. On the other hand, the jumper wires doesn't like very fast movements, so I had to slow things down. Both on the hardware and software part.
I made this by creating a path calculation to the system and inserting delay. When you send new joint angles for the robot arm, you have to provide an extra parameter: speed (mDelay). Basically you are telling the robot arm controller the minimum step time of the loop. The path calculator will calculate an optional step size for each positioning servos. It means that all servos will reach their goal at about the same time and the speed depends on the delay. The result is a very nice and smooth linear movement every time.
The effector works in a different way. Basically it can only have open or closed (with 3 different level of closed strength) state, without smooth transition. Obviously you'll want to grab the object as soon as possible, while moving should be smooth and nice.
There are 2 types of commands in this system currently. Here's an example for both of them:
- G 1 --> Closing the Gripper, lightly. 0 means open
- A 10 130 120 110 --> Moving the robot Arm with 10ms step time, 130º upper joint angle, 120º lower joint angle and 110º base rotator angle.
All right, so at this point I can control the robot arm from anywhere in the world, but I have to manually write every new command. It is not much fun this way. I needed a much more user friendly way to control the robot arm, so I made an Android application to do just that.
The app has a TCP client, so it can directly connect to the WIZ750SR's TCP server. The robot arm doesn't store the plot for old and future movements. It only knows a current goal position. It means that the application won't just send the whole movement plot to the robot arm, but rather it will periodically send a new positions to the robot arm, based on the position feedback. If you close the app or disconnect from the WIZ750SR, then the robot arm will stop moving as soon as it reaches its last received position.
After you connect to the robot arm, you will arrive to the Configure screen. It contains 3 pages. The first is Run (more on that later), the second is Init and the third is Loop. Init and Loop is basically the same, their only difference is where they save the position.
The screen contains 4 seek bars and a gripper button besides the save button. These sliders are used for setting the position and the speed of the movement, while the gripper button used to open or close the effector. All changes are instantaneous, so you'll see the new position on the robot arm immediately, however you have to click on to the save button to add it to the plot. Here's a short demonstration about it:
If you change both the gripper state and the robot arm position, then it will be saved as two different commands. The gripper command first and then the position command.
As you would expect, the running of the plot will be started with init. Init and loop are working just like Arduino's setup and loop functions. Init is good for movements that won't be repeated later. When the init commands are finished, the loop commands will follow. The loop commands will be repeated forever, or at least until you stop the plot. If you don't need either loop or init, you just leave that field empty.
These fields are EditText fields, meaning that you can edit or delete their content easily. If you don't want to use the sliders you can write the commands by hand. You can also copy and paste the plot. The application will remember the last plot that you ran for later use.
The first line under "Configure" is used as a visual feedback for testing. The left part shows you the latest goal position for the robot arm (S - sent), while the right field is the current position of it (R - received). The app will send a new goal position to the robot arm as soon as the goal and current positions are the same.
Received command explanation:
5 0 100 116 60 --> Speed: 5, Gripper: open (0), upper joint angle: 100, lower joint angle: 116, base rotator angle: 60
As you can see, when there was only init, the robot arm stopped as soon as it finished the init commands.
With my app, you can do quite a few things, but there are lots of possibilities for improvement in the future. I plan on using functions, conditional control, loops with arguments, etc in the plots.
If you want to build a similar robot, you can find both the Arduino code and the Robot Arm Controller application in the Code segment of this project.
I used both init and loop commands and it allowed me to do some moderately complex tasks. Here's a video about how my robot arm sets up some rubber ducks (init) then starts moving them one by one around itself, forever (loop).
As you can see if you take into consideration that this is a very cheap robot arm with serious hardware related limitations, the movements are very smooth, continuous and accurate.
My software works very well and in the future I'll definitely work on improving this robot arm, or I'll build a more advanced one. I achieved everything that I planned for this project and without any serious blocking problems.
The Arduino 101 is great for this purpose. The only limitation of the board is the only 4 PWM capable GPIOs. It might be a problem in the future if I build a new robot arm with more degrees of freedom, but the separate USB serial and GPIO serial is very useful during development and this board can also provide lots of computing power.
I think the Android application was a good idea, however I'll have to make it more robust, user friendly and increase its functionality. It is an alpha version at the moment.
The WIZ750SR was a very nice surprise. I feared that I'll have more issues with this board, but after the configuration, it worked perfectly. It was totally transparent and I had zero issues with it. This is a very easy to use device and the best Ethernet module that I've ever used with any of my microcontrollers.
Working with robot arms is extremely fun, so I'll definitely learn more about it and then share my knowledge with you in the future! Thank you for reading!