I use ARM-21N2 6DOF Robot Arm from https://www.thanksbuyer.com/arm-21n2-6dof-robot-arm-kit-metal-robotic-arm-mechanical-arm-unassembled-without-servo-frame-only-75929. Any idea how to move it in a straight line for X, Y, and Z axis? The value that I input on textBox_XStartingpoint will be the initial position of the end effector, and the value that will be input on textBox_XEndingPoint will be the final position of the end effector but it should move in a straight line, same will goes to Y, and Z axis.
Thanks Ahead! Here's my code for arduino
#include <Servo.h>
//Global Variable
char c;
String dataIn;
uint8_t servo1Degree, servo2Degree, servo3Degree, servo4Degree, servo5Degree;
int8_t indexOfA, indexOfB, indexOfC, indexOfD, indexOfE;
int speedDelay;
Servo baseServo;
Servo shoulderServo;
Servo elbowServo;
Servo wristServo;
Servo wristRollServo;
const int basePin = 5;
const int shoulderPin = 6;
const int elbowPin = 7;
const int wristPin = 8;
const int wristRollPin = 9;
void setup() {
Serial.begin(57600);
baseServo.attach(basePin, 500, 2500);
shoulderServo.attach(shoulderPin, 500, 2500);
elbowServo.attach(elbowPin, 500, 2500);
wristServo.attach(wristPin, 500, 2500);
wristRollServo.attach(wristRollPin, 500, 2500);
servo1Degree = 90;
baseServo.write(servo1Degree);
servo2Degree = 30;
shoulderServo.write(servo2Degree);
servo3Degree = 50;
elbowServo.write(servo3Degree);
servo4Degree = 90;
wristServo.write (servo4Degree);
servo5Degree = 180;
wristRollServo.write(servo5Degree);
delay(2500);
}
void loop()
{
// put your main code here, to run repeatedly:
Receive_Serial_Data();
if(c=='\n')
{
Parse_the_Data();
c=0;
dataIn="";
}
baseServo.write(servo1Degree);
shoulderServo.write(servo2Degree);
elbowServo.write(servo3Degree);
wristServo.write(servo4Degree);
wristRollServo.write(servo5Degree);
}
void Receive_Serial_Data()
{
while(Serial.available()>0)
{
c=Serial.read();
if(c=='\n') {break;}
else {dataIn+=c;}
}
}
void Parse_the_Data()
{
String str_servo1Degree, str_servo2Degree, str_servo3Degree, str_servo4Degree, str_servo5Degree;
indexOfA = dataIn.indexOf("A");
indexOfB = dataIn.indexOf("B");
indexOfC = dataIn.indexOf("C");
indexOfD = dataIn.indexOf("D");
indexOfE = dataIn.indexOf("E");
if(indexOfA > -1) { str_servo1Degree = dataIn.substring(0, indexOfA); servo1Degree = str_servo1Degree.toInt(); }
if(indexOfB > -1) { str_servo2Degree = dataIn.substring(indexOfA+1, indexOfB); servo2Degree = str_servo2Degree.toInt(); }
if(indexOfC > -1) { str_servo3Degree = dataIn.substring(indexOfB+1, indexOfC); servo3Degree = str_servo3Degree.toInt(); }
if(indexOfD > -1) { str_servo4Degree = dataIn.substring(indexOfC+1, indexOfD); servo4Degree = str_servo4Degree.toInt(); }
if(indexOfE > -1) { str_servo5Degree = dataIn.substring(indexOfD+1, indexOfE); servo5Degree = str_servo5Degree.toInt(); }
}
and here's the code to the UI
private void textBox_XStartingPoint_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Enter)
{
string theta1 = textBox_XStartingPoint.Text;
if(int.TryParse(theta1, out int horizon))
{
if(horizon >= 0 && horizon <= 180)
{
trackBar_BaseServo.Value = Convert.ToInt32(horizon);
textBox_XStartingPoint.Focus();
if(serialPort1.IsOpen)
{
serialPort1.Write(horizon + "A" + "\n");
}
}
else
{
MessageBox.Show("Value must be betwee 0 to 180");
}
}
else
{
MessageBox.Show("Please input valid integer only");
}
}
}
private void textBox_XEndingPoint_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
if (int.TryParse(textBox_XStartingPoint.Text, out int startBaseAngle) &&
int.TryParse(textBox_XEndingPoint.Text, out int endBaseAngle))
{
double L1 = 8.3; // Length from base to elbow
double L2 = 14.8; // Length from elbow to wrist
// Assuming Y is constant for a horizontal line (Replace Y with the actual height)
double Y = 0;
// Assuming X is a function of the base angle, calculate initial X
double initialX = 0; // Replace with a calculation or value based on startBaseAngle
for (int baseAngle = startBaseAngle; baseAngle >= endBaseAngle; baseAngle--)
{
// Update X based on baseAngle
double X = 0; // Replace with a calculation or value based on baseAngle
double theta1, theta2;
SolveInverseKinematics(X, Y, L1, L2, out theta1, out theta2);
if (serialPort1.IsOpen)
{
// Send angles to servos
serialPort1.Write(baseAngle + "A" + "\n"); // Send to Base
serialPort1.Write(((int)theta1) + "B" + "\n"); // Send to Shoulder
serialPort1.Write(((int)theta2) + "C" + "\n"); // Send to Elbow
// Add a delay for servo movement (optional)
System.Threading.Thread.Sleep(100);
}
}
}
else
{
MessageBox.Show("Please input valid integer only");
}
}
}
private void textBox_YStartingPoint_KeyDown(object sender, KeyEventArgs e)
{
}
private void textBox_YEndingPoint_KeyDown(object sender, KeyEventArgs e)
{
}
private void textBox_ZStartingPoint_KeyDown(object sender, KeyEventArgs e)
{
}
private void textBox_ZEndingPoint_KeyDown(object sender, KeyEventArgs e)
{
}