Phone Controlled Robotic Arm and Car
A robotic arm mounted on top of a car, the entirety of which can be controlled by a phone application. The multi-jointed arm contains a claw with which it can pick up objects.
Area of Interest
Mechanical and Electrical Engineering
Final Phone Application
Final Arduino Code – Click here to open in GitHub
Final Breadboard Wiring
My fourth and final milestone entailed adding the car controls to my phone application, writing the App Inventor and Arduino code for the car, and testing everything to confirm that the phone app could properly control the car. Although I had plenty of experience with App Inventor from creating my robotic arm controller, it took me some time to add the car controls to my preexisting app, simply because I was experimenting with more complex controls that I thought would be useful and interesting to have. For example, I wanted to implement a way to link and unlink the motors’ speeds; this would allow users to easily drive straight forwards and backwards without having to change both motors’ speeds in exactly the same way.
At first, I wanted to create a button that would toggle the linkage, but I later decided to create a small switch instead, which would make it easier for users to see whether or not the linkage was active. When the switch is on, the right motor’s speed mirrors the left motor’s speed, which allows users to easily drive straight. Additionally, since the left motor’s speed is not affected by the right motor’s speed, users can make the car drive straight at a set speed, then make slight adjustments and turns using the right motor controls. Another feature that I wanted to add was a text field into which users could input degree measurements to turn the car a specific number of degrees. For instance, if a user entered 20 into the text box, the car would turn 20° to the right, then stop.
Although I successfully coded this feature at first, I found that it was too difficult to time exactly how long it took the robot to turn, as the DC motors are somewhat inconsistent. This is partly because they are weak, low voltage motors and partly because the car is bearing more weight than anticipated by the car designers. As a result, I decided to remove this element of the app. Instead, I replaced it with buttons that would make turns in both directions, and these controls would adjust the right motor based on the left motor’s speed. For example, pressing the left turn button would change the right motor’s speed to a value 20 greater than the left motor’s speed. I also added a stop button that would stop the car.
Another issue I ran into when trying to create complex features was the limitations of how the HC-06 Bluetooth module establishes Bluetooth connections. The HC-06 sets up a master/slave (controller/controlled) system, where the HC-06, and hence the Arduino, is always the controlled device. This means that it can only receive signals from the phone and cannot send signals back. As a result, many of my ideas became impossible; the phone would be able to send commands to the Arduino to make the motors act as I wanted, but the Arduino would not be able to send signals back and update the app to the current situation.
After I finished the app, I had to update my Arduino program with the car controls. For this step, my main issue was ensuring that what was displayed on my app corresponded to what the motors were doing, which was difficult because I wanted my app to be as intuitive as possible. As a result, the app’s controls did not reflect the reality of how the Arduino and motor driver controlled the motors, so I had to code in multiple statements that would translate the app’s outputs into proper commands. For example, on the app, I had the motor speed sliders’ range as -100 to 100, when in reality, the Arduino would send speeds from 150 to 250 and switch the direction of the current when the slider was at a negative value. Besides the need for this kind of translation, I encountered very few problems, as I had already fixed many potential issues while coding the arm.
Finally, I had to test everything to confirm it worked. Here, I ran into a few issues with the motor speeds. The right motor was significantly weaker than the left motor, and both motors would stall if set to low speeds. To remedy these problems, I shifted the slider values to make them start from higher speeds, which made it impossible to set them to speeds that would stall the motors. I also shifted the right motor values higher than the left motor values in order to ensure that the motors’ relative speeds lined up with the app’s controls. I later encountered a more significant issue: the servos would sporadically stop running, which would cause the arm to collapse.
At first, I thought that I had made a mistake with my wiring, but after examining my work, I couldn’t find any errors. After further testing, I noticed that the Arduino’s on light would occasionally flicker, which made me think that a lack of sufficient power was the cause. Another reason that I thought that this was the issue was because the Arduino was only being powered by a 5V portable charger, and with the addition of the DC motors, this 5V was being used to power the servos as well as the motor driver. To test this theory, I rewired the servos and Bluetooth module with a separate battery pack, which allowed the portable charger to exclusively power the Arduino and motor driver, and this remedied the problem.
From working towards this milestone, I learned some valuable lessons about optimizing user interface in an app. Having little previous experience with building phone applications, I had never considered the difficulties of making an app easy to use while also having it function optimally, and it was an enjoyable challenge to balance the two. I also learned more about Bluetooth and the ways that different types of Bluetooth connections can affect the interactions between devices. Before researching this subject, I had no idea that there were multiple kinds of Bluetooth connections, and I found it interesting to examine the benefits and drawbacks of each of them.
Regular vs. Mini Breadboard
Simplified H-Bridge Circuit
My third milestone was to build the car chassis, connect the arm and the rest of the project to the car, and configure all of the necessary wiring. I had little trouble assembling the chassis, but attaching everything to the chassis was slightly more complicated. The challenges that I faced while trying to fasten everything to the chassis stemmed from the fact that it was far too small to fit the many parts of the robotic arm, which included the Arduino, breadboard, portable power supply, and the arm itself. I also had to attach the battery pack and motor driver that would power and control the motors for the wheels of the car. Additionally, I needed to ensure that all the parts could be properly wired without interfering with each other.
When first approaching the problem, I immediately tried to think of ways to eliminate unnecessary bulk, and I was able to come up with two solid methods to reduce the size of some of the parts. These two methods were to chop off the back half of the robotic arm’s base and to rewire everything onto a mini breadboard instead of the regular-sized one. I found these ideas to be optimal, as I realized that the back of the robotic arm base, which would normally hold the Arduino or breadboard, would be unnecessary with the implementation of the car. Additionally, I noticed that I was using less than half of the rows on the regular breadboard and would be able to fit everything onto a much smaller board even with the additional wiring for the car’s motors.
However, even with these changes, there were still too many parts to fit on the chassis. After looking at the available space, I devised a layout that incorporated the underside of the chassis. I decided to split the parts into two groups: those related to the cars’ DC motors and those related to the arm’s servo motors. I bolted the first group to the bottom and the second group to the top of the chassis, since the car motors had to be on the bottom and the arm had to be on the top. I also included the breadboard and Arduino in the second group, as this would make it easier to set up and modify the wiring.
Thanks to my planning, configuring the wiring was relatively straightforward. Since I had already hooked up the servos and Bluetooth module to the Arduino on the large breadboard, I simply rewired them onto the smaller breadboard in a more organized version. I then wired the DC motors with the Arduino, battery pack, and L298N motor driver, which required me to learn how the L298N works. The L298N uses two H-bridge circuits to control the motors’ directions, while the Arduino uses pulse-width modulation, which I discuss in my milestone 1 documentation, to control the motors’ speeds.
H-bridge circuits such as the one to the left are capable of manipulating the direction in which current flows through a DC motor. In this diagram, closing the bottom left and top right switches will cause current to flow from the right to the left side of the motor, and closing the top left and bottom right switches will cause current to flow through the motor in the opposite direction. This reversal changes the direction in which the motor spins.
As for the motor driver wiring, the L298N intakes power from both the battery pack and the Arduino, so I first connected their power outputs to the L298N’s designated inputs. The battery pack supplies the power to move the motors, while the Arduino powers the L298N itself and allows it to manipulate the motors’ speeds and directions. I then linked the battery pack and Arduino’s grounds by connecting both of them to the L298N’s ground pin, which is important because voltage only measures potential difference, not the specific electric potential of each side of a power supply. Therefore, the electric potential of the battery pack’s ground could theoretically be greater than the electric potential of the Arduino’s power, which would cause the motor driver to fail if current flowed from one to the other.
By linking the grounds, I ensured that the Arduino’s positive side is referenced against its own negative side (instead of the battery pack’s negative side), and vice versa. After connecting the motors to their designated pins on the motor driver, I connected the L298N’s six terminals that control the speed and direction of the motors to six of the Arduino’s pins. As a side note, it was necessary for me to connect the enable terminals, which control the motors’ speeds, to Arduino pins capable of using PWM.
The issues I encountered on the way to this milestone emphasized to me the importance of thinking creatively and taking some risks with my project. At first, I felt uncomfortable with attaching the motor driver and battery pack to the bottom of the chassis, as it would increase the difficulty of noticing issues with their wiring if wires snapped or were jostled loose. However, it was my only solution to the limited space problem, so I decided to use it and be extra careful about monitoring these parts. I also learned a lot about the L298N motor driver and how DC motors are controlled while working towards this milestone. Although I had already known a bit about how DC motors work, it was interesting to discover how they can be manipulated and controlled.
The reset button would send four commands as one.
Bluetooth messages would sometimes be truncated or separated.
Arduino program joining truncated commands and separating connected commands
Phone application in action
My second milestone was to create a working phone application that could thoroughly control the robotic arm; in other words, it was to complete the base project. To accomplish this, I programmed a phone application with sliders and buttons that would send a variety of instructions to the Arduino over Bluetooth. I then wrote an Arduino program that would allow the Arduino to interpret these instructions and use them to manipulate the servos in the arm.
Though I had little difficulty programming each of them individually, I ran into numerous problems when trying to integrate the two programs. As I state in the video, the servos made very twitchy movements when changing position during my initial testings of the phone app. By running simplified versions of the phone app and having the Arduino print the data it received from the phone, I was able to identify the Bluetooth connection as the problem, as the phone outputs and Arduino inputs were vastly different. After digging through my Arduino code and doing some research on Bluetooth, I found that I had set the wrong baud rate for the Arduino, which caused corruption in the data it received. After fixing the baud rate, it became significantly easier to identify other issues, both with the Arduino code and the phone app code, since the phone output now lined up with the Arduino input.
The limitations of Bluetooth caused the majority of my programs’ issues. The greatest of these issues caused the servos to sometimes move to a completely incorrect position when I moved the sliders or pressed a button. What made this error confusing was that it could occur during changes to any of the servos, sliders, and buttons, but it would happen randomly and infrequently. However, certain actions such as holding down a slider or pressing the reset button, which I designed to reset all of the servo positions back to their default/starting positions when pressed, would trigger this error more frequently. I once again printed the Bluetooth signals received by the Arduino to the monitor and went through the process step-by-step, and I discovered that the Arduino would sometimes either join together or truncate Bluetooth messages.
For example, when the reset button was pressed, the Arduino would read the commands for all of the servos as one command instead of four separate commands. I hypothesized that this issue occurred because the app was sending the data to the Arduino faster than it could distinguish between different commands. To further explain, the setTimeout method sets the amount of time that the Arduino will wait before cutting off the signal and waiting for a new command. Even though I had set this to one millisecond, the phone app would sometimes send multiple commands to the Arduino within this timeframe, which caused the Arduino to read them as one long command. This was the reason that holding down on the sliders would also cause this error to occur, since holding down on the sliders sends many commands in a short time frame. As for the truncation, I realized that this was happening because the Arduino would sometimes refresh the Bluetooth in the middle of receiving a signal, which would result in that signal being chopped in two.
To solve these issues, I first added a semicolon to the end of each Bluetooth output from App Inventor. I then wrote code into the Arduino program that would find the semicolons and use them to separate each Bluetooth message before executing them. If the program did not find a semicolon, it meant that the message was truncated, in which case the program would store the truncated command and join it with its second half. I have included pictures of what all of this looks like on the left (phoneOutput is the original Bluetooth message, outputN is what’s executed).
The issues I had with my code while working towards this milestone improved my debugging skills and taught me the importance of solving one problem at a time and analyzing each step of a program. I also learned a great deal about how Bluetooth works and how computers interact with it while working through these problems. In particular, I gained a much better understanding of how the computer treats and recognizes Bluetooth data from analyzing and solving the last problem that I discussed. Finally, I also learned how to use GitHub to upload and share code.
My first milestone was to assemble the robot arm with the servos, configure the wiring of the servos and Arduino, program the Arduino with test code, and run this code to ensure that the arm would move properly. I had no major issues with building the arm or wiring the servos and Arduino on the breadboard, but I encountered a few minor ones, which I highlight in the video. The greatest of these issues was overheating one of the servos while testing some programs that I was thinking of incorporating into my Arduino code. After the servo overheated, I realized that the servo was stalling as a result of a specific limitation of the mechanical design, not an issue with my code.
This mistake caused no permanent damage, but it served as an important reminder to be patient and not try to force progress and rush the problem solving process. If a program isn’t working, I now spend more time analyzing the issue before running it again, instead of continuously running the program while trying to quickly fix it. I also learned about pulse-width modulation (PWM), which is used to control the servos. First of all, Arduino uses digital signals, which can be set to 2 values: on or off. When using PWM, the Arduino simulates analog signals (which can be set to any value between on and off) by quickly switching on and off the voltage sent to each servo. This allows the Arduino to better control the voltage and current being sent to each servo, as it can increase the duty cycle (the ratio of on time to off time) in order to increase voltage/current and decrease the duty cycle to decrease voltage/current. By doing this, the Arduino can write the servos’ positions to precise degree measurements, instead of only being able to write them to 0 or 180 degrees.
Robot Arm – Right Side View hover for details
Robot Arm – Left Side View hover for details
Wiring as of Milestone One
Project as of Milestone One