Aaron’s Three-Jointed Robotic Arm
My project is a three-joint robotic arm, which uses one servo motor to rotate the base, two servo motors to control the joints of the arm, and one servo motor to open and close the gripper. A Python program running on a Raspberry Pi 4 single-board computer accepts inputs from two analog joysticks and moves the arm’s servos accordingly.
| Engineer | School | Area of Interest | Grade |
|---|---|---|---|
| Aaron E | NorthStar Academy & CCU Academy | Mechanical Engineering/Robotics | Incoming Junior |

First Milestone
My first milestone involved assembling and testing the Cokoino robotic arm using assembly guides and sample code provided by Cokoino. Before assembling the arm, I used sample code to test the servo motors and realign their angles to 90°.
As I worked through this process, I encountered my first issue. After I tested two of the four servos, my computer stopped recognizing the Arduino Nano that is used in this project. I fixed this issue by restarting my computer, which allowed my Windows operating system to correctly identify the Nano again.
After I finished testing and aligning the servos, I continued with the assembly of the structure of the arm. Due to the small size of some of the parts, the assembly was at times difficult, but I can now control my robotic arm using the attached joysticks.
The Arduino Nano runs a program provided by Cokoino that accepts the potentiometer input of two joysticks and converts the input to the proper angles for the servos to rotate to. I will modify my project so that I can control the arm using a Raspberry Pi 4 rather than the Arduino Nano. To accomplish this, I will write a custom Python program for interfacing with the servos and joysticks.
Second Milestone
For my second milestone, I reconfigured the setup of my robotic arm to use a Raspberry Pi as the controller. I encountered some issues along the way, but I have made great progress toward being able to control the robotic arm using the Raspberry Pi. My general process for this milestone was as follows.
Interfacing Between the Raspberry Pi & Servo Driver Board
My first step was to get the Raspberry Pi interfacing properly with the servo driver board. I first downloaded the necessary libraries (specifically the Adafruit CircuitPython ServoKit library), then I connected all of the proper wires and looked at an online tutorial to help me write a simple test program to try controlling the arm. This particular servo driver board uses the I2C communication protocol. This communication protocol allows the Pi to interface with multiple devices over just two wires.
Later, I realized that the servo driver board was not properly driving the servos because I had not yet configured the external power supply to supply a voltage. I was using this external power supply to supply power for driving the servos. I then ran my program to manually input different angles to move the servos, and the servos responded correctly.
Setting Up The Joysticks & Analog-To-Digital Converter
My next step was to incorporate the joysticks into the system. This required setting up the analog-to-digital converter, or ADC. Since the Raspberry Pi cannot read the analog outputs of the joysticks itself, the Raspberry Pi needs a separate board to convert the analog output of the joysticks to a digital input for it. Both the ADC and servo driver board that I used communicate with the Pi using the I2C communication protocol.
The methods of using the ADC were not immediately intuitive for me, but I took my time, checked my wiring multiple times, did research, and asked questions. So, in the end, I succeeded. Before this point, however, I realized that there was an undefined variable in my code, but this was easily fixed by adding a line to my code that defined the analog input pin that I was using on the ADC to read the values from the joystick.
After I fixed this, I encountered another issue where the ADC kept outputting the same value over and over again. I solved this issue by reconfiguring the power and ground wires for the ADC and joysticks so that they were all on the same circuit. After I made this change, the test program worked properly, outputting different values as I moved the joystick.
Putting It All Together
My final step was to integrate the servo driver board and ADC together. Once I completed the wiring for this, I wrote a test program that uses the input of one axis of one of the joysticks to control one of the servos in the arm. The analog output of the joystick goes to the ADC, which converts it to a digital input for the Raspberry Pi. My Python program then uses a piecewise function to convert the value provided by the ADC to an angle to send to the servo driver board, which in turn tells the servo the correct angle to rotate to.
The piecewise function conversion step was necessary to correctly translate the position of the joysticks to the position of the servos. The output range of the joysticks is from 0 to 255, while the movement of the servos is restricted to 0 to 180 degrees. This meant that some function was necessary to translate the input of the joystick to the proper angle for the servos. However, the physical middle position of the joystick outputs a value of about 211. This meant that the conversion from the input of the joystick to the output angle of the servo could not simply be a linear function, because two different conversions were necessary to account for the uneven range of values above and below the center of the joystick.
Next Steps
My setup now works as expected, with the position of the joystick being correlated to an angle for the servo. Moving forward, I will first finish integrating the remaining axes of the joysticks. Then I will potentially alter my code to have the position of the joysticks determine the speed at which the servos rotate, rather than determining the exact angle of the servo. If I have time, I may also incorporate a pressure sensor to allow the gripper to automatically stop closing when it has sufficiently grasped an object.
Final Milestone
My final milestone was software-focused, with the major improvement to my project being that I changed my code so that the joysticks control the rotational speed of the servos rather than their exact positions. I am excited to say that I succeeded in accomplishing this modification.
I started my final milestone by correlating the position of the joysticks to angles for the servos. Once I got this code working properly, my focus shifted to altering my code so that the position of the joysticks would control the directional speed of the servos, rather than their exact angles. It was very challenging to get this code working, as the new method of control is vastly different than the previous one, which led to a multitude of syntax and logic errors in my code. However, by persevering through systematically eliminating errors, I am excited to say that I was able to make my code operational. I can now properly control my robotic arm using a Raspberry Pi instead of an Arduino.
In the process of completing this project, the biggest challenge I faced was working with the I2C communication protocol because the Raspberry Pi was not consistently recognizing my I2C devices. I overcame this challenge by doing research and thoroughly thinking through the situation.
My biggest triumph was getting my final code working. I spent many long hours trying to debug the code, so I was very excited when it finally worked.
Fundamental topics in this project included the translation of analog outputs to digital values, the use of pulse width modulation to control servo motors, and the communication between I2C devices. Of these, I think that my experience with interfacing between I2C devices will prove the most useful to me in future projects because I can comfortably add I2C boards to my projects to extend their functionality.
One concept that I hope to learn more about in the future is the use of microcontrollers in projects, especially for Internet of Things, or IoT, applications. I look forward to being able to use the base skills I learned in my time at BlueStamp Engineering to explore this concept further.
Schematics

Code
Here is the code used to test the joysticks with the Arduino Nano.
Here is the code used to test the servos with the Arduino Nano.
Here is the code used to align the servos with the Arduino Nano.
Here is the code used to control the completed arm using the Arduino Nano. (Note: the src folder must be in the same directory as the main code for the main code to upload to the Arduino Nano correctly.)
Here is the code used to test the servo driver board with the Raspberry Pi 4.
Here is the code used to test the analog-to-digital converter with the Raspberry Pi 4.
Here is the first program I wrote to use both the servo driver board and the analog-to-digital converter with the Raspberry Pi 4.
Here is my final code for controlling the robotic arm with the Raspberry Pi 4.
Bill of Materials
| Part | Note | Price | Link |
|---|---|---|---|
| Robot Arm Kit | Includes all parts for the structure of the arm, as well as the original electronics | $49.99 | Link |
| Servo Shield | Board used to connect the servos to the Arduino | $10.99 | Link |
| 9V Batteries | Provide power to system | $8.99 | Link |
| 9V Battery Barrel Jack Connector | Connects 9V batteries to system | $5.99 | Link |
| Screwdriver Kit | Used for assembling parts | $7.99 | Link |
| Electronics Kit | Spare electronics parts | $13.99 | Link |
| Digital Multimeter | Used to test various circuit parameters | $16.23 | Link |
| Raspberry Pi 4 Model B Starter Kit | Includes Raspberry Pi 4 Model B computer and necessary peripherals | $93.00 | Link |
| Servo Driver Board | Used to drive servo motors | $9.99 | Link |
| Analog-To-Digital Converter | Used to convert analog output signal of joysticks to digital input values for the Raspberry Pi | $9.99 | Link |
| Portable Battery For Raspberry Pi | Used to power the Raspberry Pi without connection to wall outlet | $29.99 | Link |
Other Resources/Examples
- Original Assembly Guide & Code
- Tutorial for Using Servo Driver Board
- Data Sheet for External Power Supply
- Pin Diagram for Raspberry Pi
- Tutorial for Using Analog-To-Digital Converter
- Tutorial for Installing adafruit_blinka Library on Raspberry Pi
- Fritzing Part File for External 5V Power Supply
- Fritzing Part File for Analog-To-Digital Converter
- Circuit Diagram Tool
- Proofreading Tool
- Screen Recording Tool
- Useful AI Chatbot for Help with Engineering Troubleshooting