So I am running code to operate a few servo motors, and things weren't working correctly so I began to debug it.
The line:
Serial.print("In Do loop.\n");
Prints out as:
In D
After the line doesn't print correctly, the program stops entirely. So my partners and I thought that was weird so we were hoping someone here has seen something like this before. Any thoughts?
The thing about Serial is that when you call print it puts it in the buffer and then it gets sent out via interrupts. So by the time you actually see anything on the screen, the code is a little beyond that point. It's something shortly after that print line that is buggering things up.
I'd hazard a guess that something in that do loop is locking things up.
If you posted the code here I might be able to help you figure it out. But you didn't so you're kind of on your own with it.
You'll have to post it here. I went to your link and it asked me to download. Not going to do that from someone I don't know for reasons that I hope are fairly obvious. No offense intended.
I'm going to upload the code in 3 parts as it's individually much more than 9000 characters.
//Things to do:
//1) Write function to ensure that arm is within 2 degrees of theta1, theta2, theta3.
#include <math.h>
#include <Servo.h>
Servo baseServo; //Motor that pivots entire arm. [2]
Servo servo1; //First joint motor. [3]
Servo servo2; //Second joint motor. [7]
Servo servo3; //Third joint/hand motor. [8]
Servo servo4; //Hand swivel motor. [9]
Servo servo5; //Claw open/close motor. [10]
double fin_ang1 = 0.0; //Stores value of actual angle of motor 1 from algorithm calculation.
double fin_ang2 = 0.0; //Stores value of actual angle of motor 2 from algoirthm calculation.
double fin_ang3 = 0.0; //Stores value of actual angle of motor 3 from algoirthm calculation.
double fin_ang2_math = 0.0; //Stores value of angle of motor 2 from algoirthm calculation (This is relative to vertical NOT actual motor angle).
double fin_ang3_math = 0.0;//Stores value of angle of motor 3 from algoirthm calculation (This is relative to vertical NOT actual motor angle).
int parallel_algo = 0; //When moveArm function is called, 0 represents parallel calculation, 1 represents values pulled from algorithm calculation.
//Stores the feedback values for each motor.
int feedback_1;
int feedback_2;
int feedback_3;
int feedback_4;
int feedback_5;
int feedback_0; //Base motor.
//Feedback pin assignments.
int feedback_pin1 = 1;
int feedback_pin2 = 2;
int feedback_pin3 = 3;
int feedback_pin4 = 4;
int feedback_pin5 = 5;
int feedback_pin0 = 0; //Base motor.
//Feedback pin angles calculated from best fit linear regressions.
double feedback_angle1;
double feedback_angle2;
double feedback_angle3;
double feedback_angle4;
double feedback_angle5;
double feedback_angle0;
//Stores lengths of each arm (in cm).
double D1 = 5.0;
double D2 = 6.0;
double D3 = 19.0;
//Stores the values of the angles.
double ang1 = 90.0;//Stores the actual value of the angle. This goes to the motor.
//This also stores the vertical value as it's independent of other joints.
double ang2 = 0.0;//Stores the value of angle 2 according to the diagram.
double ang2r = 0.0;//Stores the real value of angle 2. This goes to the motor.
double ang3 = 0.0;//Stores the value of angle 3 according to the diagram.
double ang3r = 0.0;//Stores the real value of angl3 3. This goes to the motor.
double angBase = 0.0;//Stores the angle of the base.
double angHand = 5.0; //Default value (5 degrees).
double angWrist = 0.0; //Angle of the wrist.
double oldAng1 = 90; //Stores old value of angle1.
double oldang2r = ang2r; //Stores old value of actual angle2.
double oldang3r = ang3r; //Stores old value of actual angle3.
double oldbaseAngle = 0.0; //Stores old value of the actual base angle.
//Xdn and Ydn are the coordinates of the location
//of the base of the arm. Dx and Dy store the location of point
//D which is located at (0,0) and represents the endpoint of
//the arm where it terminates at the origin. Ax and Ay store the
//new location of the base of the arm.
double Xdn = 0.0;
double Ydn = 0.0;
//Stores the CURRENT location of the base of the arm.
double Xd = 0.0;
double Yd = 0.0;
//Stores the value of the new coordinates to move to.
double newX, newY, newZ;
double Axn, Ayn;
double loopcode = 2; //Since I2c hasn't yet been implemented, if loopcode is 2, the loop() section of the code
//will function only when loopcode is 2.
double theta2;
double theta1;
double theta3;
void setup()
{
Serial.begin(9600); //Allowing there to be serial monitor output.
/***Pin Assignments***/
baseServo.attach(2); //Base Servo
servo1.attach(3); //motor 1
servo2.attach(7); //motor 2
servo3.attach(8); //motor 3
servo4.attach(9); //swivel
servo5.attach(10); //claw
OpenCloseHand(0); //if 0, goes to 5 degrees. If 1, goes to 60 degrees.
do
{
moveToDefault();
}while (compareAngles(40,75,10,90)==false);
Serial.print("\n**Asking for input**\n");
calculateCurrentBaseLocation();
//do
//{
Serial.print("In Do loop.\n");
enterCoordinates();
// } while (inRange() == false);
calculateXYProjection();
algorithm(Xdn, Ydn);
parallel_algo = 1;
moveArm();
}
void loop() //Runs over and over. This is why I have loopcode
//set to 2 initially and then set to a different value so it won't run over and over.
{
/*
while (loopcode == 2)
{
do
{
enterCoordinates();
} while (inRange() == false);
calculateXYProjection();
algorithm(Xdn, Ydn);
parallel_algo = 1;
moveArm();
loopcode = 1;
}
*/
}
//This function moves the arm.
void moveArm()
{
feedback(); //Calculating feedback.
//From feedback values, set feedback angles to old values.
oldang2r = feedback_angle2;
oldAng1 = feedback_angle1;
oldang3r = feedback_angle3;
oldbaseAngle = feedback_angle0;
//If parallel, set values of angles TO move to.
if (parallel_algo == 0) //Parallel angles.
{
ang2r = ang2 + ang1 - 90; //Real value of angle of joint 2.
ang3 = 180 - ang1;
ang3r = ang3 + ang1 - ang2r; //Real value of angle of joint 3.
}
//If non parallel values and algorithm used, set values of angles TO move to.
if (parallel_algo == 1) //Non parallel angles. Values pulled from algorithm.
{
ang2r = fin_ang2;
ang1 = fin_ang1;
ang3r = fin_ang3;
}
//If non parallel values and algorithm not used, values are already set from setup or loop function.
if (parallel_algo == 2) //Non parallel angles. Values pulled directly from manually setting
//the values of the angles from the setup() or loop() functions.
{
}
//Set incremental movement of servo. Still need to make this more efficient.
double servo1Dir = abs(oldAng1 - ang1) / 100;
double servo2Dir = abs(oldang2r - ang2r) / 100;
double servo3Dir = abs(oldang3r - ang3r) / 100;
double baseDir = abs(oldbaseAngle - angBase) / 100;
//If movement of angles is in negative direction, set them to be -1 x their value.
if (ang1 < oldAng1)
{
servo1Dir *= -1;
}
if (ang2r < oldang2r)
{
servo2Dir *= -1;
}
if (ang3r < oldang3r)
{
servo3Dir *= -1;
}
if (angBase < oldbaseAngle)
{
baseDir *= -1;
}
/*
Serial.print("**Moving servo 1**\n");
Serial.print("Moving from ");
Serial.print(oldAng1);
Serial.print(" to ");
Serial.print(ang1);
Serial.print("\n");
Serial.print("**Moving servo 2**\n");
Serial.print("Moving from ");
Serial.print(oldang2r);
Serial.print(" to ");
Serial.print(ang2r);
Serial.print("\n");
Serial.print("**Moving servo 3**\n");
Serial.print("Moving from ");
Serial.print(oldang3r);
Serial.print(" to ");
Serial.print(ang3r);
Serial.print("\n\n");
*/
double i = oldAng1, j = oldang2r, k = oldang3r, l = oldbaseAngle;
//Begin process of moving by checking conditions of if any of the motors are not within .001 of their desired end point, it will keep moving until
//they all are. May be possible point of contention for the code to where it "spazzes" because it may fall outside of the range and continue moving.
while ((abs(i - ang1) > .001) || (abs(j - ang2r) > .001) || (abs(k - ang3r) > .001) || (abs(l - angBase) > .001))
{
if (abs(i - ang1) > .001)
{
servo1.write(i);
i += servo1Dir;
}
if (abs(j - ang2r) > .001)
{
servo2.write(j);
j += servo2Dir;
}
if (abs(k - ang3r) > .001)
{
servo3.write(k);
k += servo3Dir;
}
if (abs(l - angBase) > .001)
{
baseServo.write(l);
l += baseDir;
}
delay(30);
}
feedback(); //Diagnostic purposes.
}
void OpenCloseHand(int i)
{
if (i == 0)
{
servo5.write(5);
}
if (i == 1)
{
servo5.write(60);
}
}
void rotateWrist(double myAng)
{
feedback();
double inc = 10;
double delay_value = 100;
double dirMove = abs(myAng - feedback_angle4) / 20;
angWrist = feedback_angle4;
if (dirMove <= 1)
{
delay_value /= .5;
}
Serial.print("**Wrist Rotation**\n");
Serial.print("Rotating to angle ");
Serial.print(myAng);
Serial.print(" from angle ");
Serial.print(feedback_angle4);
Serial.print("\nMoving by ");
Serial.print(dirMove);
Serial.println("");
if ((myAng <= 180) && (myAng >= 0))
{
if (myAng < angWrist)
{
for (int i = angWrist; i > myAng; i -= dirMove)
{
Serial.print(i);
Serial.print(" ");
servo4.write(i);
delay(delay_value);
}
}
if (myAng > angWrist)
{
for (int i = angWrist; i < myAng; i += dirMove)
{
Serial.print(i);
servo4.write(i);
delay(delay_value);
}
}
Serial.print("**Done Moving**\n\n");
feedback();
angWrist = feedback_angle4;
}
else
{
Serial.println("Error. Not in range.");
}
}
Anytime you are using floating point constants in an expression, use decimal notation (e.g., 2.0, not 2) in the expression. Also, division is a relative slow operation so expression like where you divide a bunch of numbers by 9900 would be slightly more efficient if you multiplied by .00010101.