My task here is to build and program an elbow joint using the SparkFun Inventors Kit and the Arduino IDE. There are a number of things to figure out before jumping in to building and coding this project. First off I have to select an appropriate motor for this task. A servo motor is perfect for this job! For one, they have a limited amount of movement (most servo's have a 180 degree turn radius), which is just like a human arm. The best thing about servo motors is that they have a position sensor that track how much the motor is turning and in what direction, which allows you to move the motor to a particular position.
In order to simulate a robotic elbow joint I cut some paper and taped one side of it to the plastic attachment I added to the servo motor. I cut another piece of paper and taped it to a wire which I secured to the base of the servo. I bent the wire so that the paper attached to it was floating near the center of the servo (where the elbow joint was to be) so that it wouldn’t interfere with the other piece which was taped to the servo to simulate the lower arm (forearm). This was a quick and easy method and allowed me to demonstrate my program.
I had a few challenges with coding the elbow joint. The instructions in the Instructors Notebook read: “Your program should take as input a number of degrees to move the elbow from an arbitrary starting position.”. To accomplish this I figured that I would have to write a number into the serial monitor which would represent a number of degrees for the arm to move to on command. I borrowed concepts from 3 of the projects that we did in the SIK (v4.0a). To start I first brought up the code from the Circuit 3A: Servo Motors. This was helpful since it already had the code needed for the servo object library, how to write to the servo and how to use the map function. It also showed me everything I needed to hook the servo back up to the Arduino in the SIK guide. The map function I used to invert the values so that if I wrote 170 for example it would simulate a straight arm (180 degrees) and if I wrote 10 it would show a fully bent arm etc. Because of this I chose to set the default write angle of the servo to approximately 45 degrees so that I could show fully bent or straight arm more easily.
The second part of SIK guide that I borrowed was from the very first circuit that I created: Circuit 1A: Blinking an LED. All I wanted to achieve here was to create an LED that blinked to show that the servo was in standby mode waiting for a command. This was an unnecessary feature but helped a bit with debugging and choosing how long to set my delays.
The third concept I borrowed from the SIK guide was how to write to the Arduino from the Serial Port monitor. This was from Circuit 5B: Remote-Controlled Robot. This was the hardest part of the program because I was repeatedly receiving errors because of how I set my variables. I created a variable named ServoAngle which I assigned as a String. The problem I had was when I read the value from the serial monitor and tried to write a mapped value to the servo, I kept getting an error saying:
cannot convert 'String' to 'long int' for argument '1' to 'long int map(long int, long int, long int, long int, long int)'
It took me a long time to figure out how to fix this since I didn’t really have a good understanding of the variable types. I thought I had a fix at first by making my ServoAngle variable both ‘Int’ and ‘Long’ types, but neither of these worked as intended. I kept seeing the servo motor move the exact same amount every time I wrote to it! I think this ended up being because the value would always be the same since it would only write to the servo using the first read variable value, so a 10 and 170 would only use the 1, at the start of that number. I also was reading the value using the function: Serial.read instead of Serial.readStringuntil since I had the variable set as an Int at that point. I could be wrong on this but I think I proved this by using Serial.println to start printing to the serial monitor the value that it thought I had written. I kept seeing the same value printed every time. Eventually I set the ServoAngle variable back to a ‘String’ type, I changed the serial read line to: ServoAngle = Serial.readStringUntil(' '); and I had to use the toInt function in order to convert the string to an integer in order to write that to the servo. This toInt function was new to me and I luckily found it on the Arduino forums (https://forum.arduino.cc/index.php?topic=50834.0).
Video on how my Elbow joint circuit functions:
________________________________________________________________________________
Here’s my Code:
#include <Servo.h> //include the servo library
//int potPosition; //this variable will store the position of the potentiometer
int servoPosition; //the servo will move to this position
Servo myservo; //create a servo object
String ServoAngle; //Servo angle
void setup() {
myservo.attach(9); //tell the servo object that its servo is plugged into pin 9
Serial.begin(9600); //begin serial communication with the computer
//prompt the user to enter a command
Serial.println("Enter a number between 10 and 170");
Serial.println("Note: This represents the angle of the lower arm relative to the upper arm. If the angle of the");
Serial.println("servo is 10, that means that the elbow is fully bent (this would be approximately 20 degrees on ");
Serial.println("a human arm. An angle of 170 represents a straight arm (180 degrees on a human arm). ");
Serial.println("The flashing blue LED means that the arm is in standby waiting for a serial command.");
pinMode(13, OUTPUT); // Set pin 13 to output
}
void loop()
{
if (Serial.available() > 0) //if the user has sent a command to the RedBoard
{
ServoAngle = Serial.readStringUntil(' '); //Read the value written to serial
Serial.println((ServoAngle)+(' = ')+(ServoAngle.toInt())); //write the value of ServoAngle as a String and converted to an Int
servoPosition = map(ServoAngle.toInt(),170,10,10,170); //convert the potentiometer number to a servo position from 20-160
//Note: its best to avoid driving the little SIK servos all the
//way to 0 or 180 degrees it can cause the motor to jitter, which is bad for the servo.
myservo.write(servoPosition); //move the servo to the 10 degree position
delay(1800);
}
else {
myservo.write(80);
digitalWrite(13, HIGH); // Turn on the LED
delay(750); // Wait
digitalWrite(13, LOW); // Turn off the LED
delay(750); // Wait
}
//potPosition = analogRead(A0); //use analog read to measure the position of the potentiometer (0-1023)
}
______________________________________________________________________________
Here’s my hookup guide (wiring) on the breadboard (BB) and Arduino Red Board (RB):
Blue LED: 5d (negative(-) / Flat side) to 6d (positive (+) on BB)
330 Ohm Resistor: 5e to 5f (on BB)
Jumper wire 1 (Blue): 5g (on BB) to D13 (on RB)
Jumper wire 2 (green): 6e (on BB) to GND (-) (on BB)
Jumper wire 3 (Red): 5V (+) (on BB) to 5V (on RB)
Jumper wire 4 (Red): 5V (+) (on BB) to Servo Red wire
Jumper wire 5 (white): D9 (PWM out (~) on RB) to Servo White wire
Jumper wire 6 (black): GND (-) (on BB) to GND (on RB)
Jumper wire 7 (black): GND (-) (on BB) to Servo Black wire
The Landing is a social site for Athabasca University staff, students and invited guests. It is a space where they can share, communicate and connect with anyone or everyone.
Unless you are logged in, you will only be able to see the fraction of posts on the site that have been made public. Right now you are not logged in.
If you have an Athabasca University login ID, use your standard username and password to access this site.
We welcome comments on public posts from members of the public. Please note, however, that all comments made on public posts must be moderated by their owners before they become visible on the site. The owner of the post (and no one else) has to do that.
If you want the full range of features and you have a login ID, log in using the links at the top of the page or at https://landing.athabascau.ca/login (logins are secure and encrypted)
Posts made here are the responsibility of their owners and may not reflect the views of Athabasca University.