Simple moves code for Lynxmotion Botboarduino robot arm

Hello.

I need help, the teacher of the robotic lab of my school bough a Lynxmotion Botboarduino robot arm but he don’t knw how to use it, so he asked to me if I can research how to use it because we use this kind of stuff to talk to the kids about robotics and technology and we have to make a speech in two days.

I have research a lot, but I only have found sample code to control the arm with a PS2 controller, but we don’t have the PS2 controller adapter.

For this reason I want to ask you if you sample code with predefined moves that not requiring the PS2 controller, and that we can use this examples to develop our own movement codes.

Thanks for the help :slight_smile:

I tried to run the following code based on an example that I found with this pin configuration the following pin configuration, but when I uploaded to the Botboarduino just the TX and RX LED blinked a momento and nothing else happens.

Could you help me? Am I missing something?

base joint 2
shoulder joint 3
elbow joint 4
wrist (y axis) 10
gripper 11

[code]void setup() //initializing serial communication baud rate
{
Serial.begin(9600);
}

/* Procedures to be used in the Demo.
Move the object from the ground onto the platform.
*/

void homes()//returns to initial position
{
Serial.println("#11 P1000 T500");
delay(1000);
Serial.println("#10 P2350 T500");
delay(1000);
Serial.println("#3 P1000 T500");
delay(1000);
Serial.println("#2 P500 T500");
delay(1000);
}

void foward()//moves the arm forward
{
Serial.println("#4 P1200 T1000");
delay(1000);
Serial.println("#3 P1300 T1000");
delay(1000);
Serial.println("#10 P1800 T1000");
delay(1000);
}

void back1()//moving the arm backwards
{
Serial.println("#3 P1000 T500");
delay(1000);
Serial.println("#10 P2350 T500");
delay(1000);
}

void back2()//moving the arm backwards
{
Serial.println("#10 P2330 T500");
delay(500);
Serial.println("#2 P1500 #3 P1000 #4 P1200 T1000");
delay(500);
}

void lift()//lifts the robot arm
{
Serial.println("#2 P2400 #3 P1300 #4 P1700 T1000");
delay(1000);
}

void grip()//Gripping the object
{
Serial.println("#11 P1550 T500");
delay(1000);
}

void drop()//Drops the object
{
Serial.println("#10 P1900 T500");//moves wrist servo to position 1900
delay(1000);
Serial.println("#11 P1000 T1000");
delay(500);
}

void turnC()//turns the arm clockwise
{
Serial.println("#2 P500 T1000");
delay(1000);
}

void turnA()//turns the arm anticlockwise
{
Serial.println("#2 P2400 T1000");
delay(1000);
}
void halfturn()//turns the arm clockwise
{
Serial.println("#2 P1500 T1000");
delay(1000);
}

void loop()
{
//Pick the object and place it on platform
homes();
delay(1000);
foward();
delay(1000);
grip();
delay(1000);
back1();
delay(1000);
halfturn();
delay(500);
lift();
delay(2000);
drop();
delay(1000);
back2();
delay(500);
}[/code]

I attached some pics of the configuration of my Botboarduino. I think all is connected correctly.



Hi,

The code you posted is meant to be used by a BotBoarduino connected to an SSC-32U board which would be itself connected to the servo motors of the arm.

You can use the example code for the BotBoarduino / PS2 found on the Lynxmotion GitHub. This example here should be enough to get you started.

What you can do then is simply remove the PS2 initialization code in the Arduino setup() function and replace the PS2 button code in the loop() function with input from the serial port (you can use the serial monitor in the Arduino IDE). All the code required to make the move arm (including basic inverse kinematics), rotate and grab objects is available in this example. You simply need to code in a new interface to be used instead of the PS2 controller setup used in the example code.

Sincerely,

So, let me see if I understand:

  • At the begging I have to remove all the declared related to the PS2, that would be this:
    **//PS2 pins #define DAT 6 #define CMD 7 #define ATT 8 #define CLK 9 //PS2 analog joystick Deadzone #define Deadzone 4
    **
    **//Onboard Speaker #define Speaker_pin 5
    //PS2X Variables PS2X ps2x; int error = 0; byte type = 0;

**

  • On the setup function, I have to remove this code:

**error = ps2x.config_gamepad(CLK,CMD,ATT,DAT, true, true); //setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error #ifdef DEBUG if(error == 0) Serial.println(“Found Controller, configured successful”); else if(error == 1) Serial.println(“No controller found”); else if(error == 2) Serial.println(“not accepting commands”); else if(error == 3) Serial.println(“refusing Pressures mode”); type = ps2x.readType(); switch(type) { case 0: Serial.println(“Unknown”); break; case 1: Serial.println(“DualShock”); break; case 2: Serial.println(“GuitarHero”); break; } #endif
**

  • On the loop() function I dont understand what you said about replace the PS2 button code in the loop() function with input from the serial port (you can use the serial monitor in the Arduino IDE).

In the loop() function, you will find two types of code that are specific to the PS2 interface:

]ex: if(RSY > Deadzone || RSY < -Deadzone)/:m]
This type of code is executed when the analog sticks are moved. The dead zone (or dead band) is the values for which the analog control is not used.

Motions on those sticks are used to drive the inverse kinematics by supplying a X/Y position for the hand in the **Arm()** function.

]ex: if(ps2x.Button(PSB_R1))/:m]
This type of code is executed when a button on the controller is pressed.

It is used mostly to trigger different movement, such as base rotate, wrist rotate and gripper open/close.

We recommend that you carefully read the code in each of those if{} blocks to understand what they do and then decide how you want to use them.

Sincerely,

and how can I replace this kind of code with a code to move the arm in a preset sequence of moves?

Hi,

There are many approaches that would be correct.

One could be to setup an array containing all the parameters for the Arm() function for the various preset moves.

Then, your loop simply iterates through this array using a counter (that increments every pass / moves to the next set of parameters) and calls the Arm() function with the appropriate parameters. You would probably want to add delays also to allow enough time for the movements to complete.

Sincerely,

Hi Scharette!

I remove all the code referenced to the PS2 controller all left the code for the initial values of the position variables just to test if the code works with the initial position. The code compilate fine but when I uploaded to the Arduino, nothing happens. Could you help me? I attached the modified code

[code]
//#if ARDUINO >= 100
#include “Arduino.h”
//#else
//#include “WProgram.h”
//#end if

#include <Servo.h>
#include <math.h>

//comment to disable the Force Sensitive Resister on the gripper
//#define FSRG

//Select which arm by uncommenting the corresponding line
//#define AL5A
//#define AL5B
#define AL5D

//uncomment for digital servos in the Shoulder and Elbow
//that use a range of 900ms to 2100ms
//#define DIGITAL_RANGE

#ifdef AL5A
const float A = 3.75;
const float B = 4.25;
#elif defined AL5B
const float A = 4.75;
const float B = 5.00;
#elif defined AL5D
const float A = 5.75;
const float B = 7.375;
#endif

//Arm Servo pins
#define Base_pin 2
#define Shoulder_pin 3
#define Elbow_pin 4
#define Wrist_pin 10
#define Gripper_pin 11

//Onboard Speaker
#define Speaker_pin 5

//Radians to Degrees constant
const float rtod = 57.295779;

//Arm Speed Variables
float Speed = 1.0;
int sps = 3;

//Servo Objects
Servo Elb;
Servo Shldr;
Servo Wrist;
Servo Base;
Servo Gripper;

//Arm Current Pos
float X = 4;
float Y = 4;
int Z = 90;
int G = 90;
float WA = 0;

//Arm temp pos
float tmpx = 4;
float tmpy = 4;
int tmpz = 90;
int tmpg = 90;
float tmpwa = 0;

//boolean mode = true;

void setup()
{
Base.attach(Base_pin);
Shldr.attach(Shoulder_pin);
Elb.attach(Elbow_pin);
Wrist.attach(Wrist_pin);
Gripper.attach(Gripper_pin);
}

int Arm(float x, float y, float z, int g, float wa) //Here’s all the Inverse Kinematics to control the arm
{
float M = sqrt((yy)+(xx));
if(M <= 0)
return 1;
float A1 = atan(y/x);
if(x <= 0)
return 1;
float A2 = acos((AA-BB+MM)/((A2)M));
float Elbow = acos((A
A+BB-MM)/((A*2)*B));
float Shoulder = A1 + A2;
Elbow = Elbow * rtod;
Shoulder = Shoulder * rtod;
if((int)Elbow <= 0 || (int)Shoulder <= 0)
return 1;
float Wris = abs(wa - Elbow - Shoulder) - 90;
#ifdef DIGITAL_RANGE
Elb.writeMicroseconds(map(180 - Elbow, 0, 180, 900, 2100 ));
Shldr.writeMicroseconds(map(Shoulder, 0, 180, 900, 2100));
#else
Elb.write(180 - Elbow);
Shldr.write(Shoulder);
#endif
Wrist.write(180 - Wris);
Base.write(z);
#ifndef FSRG
Gripper.write(g);
#endif
Y = tmpy;
X = tmpx;
Z = tmpz;
WA = tmpwa;
#ifndef FSRG
G = tmpg;
#endif
return 0;
}

void loop()
{

if(Arm(tmpx, tmpy, tmpz, tmpg, tmpwa))

if(tmpx < 2 && tmpy < 2)
{
tmpy = tmpy + 0.05;
Arm(tmpx, tmpy, tmpz, tmpg, tmpwa);
}
else if(tmpx < 1 && tmpy < 2 )
{
tmpx = tmpx + 0.05;
Arm(tmpx, tmpy, tmpz, tmpg, tmpwa);
}
delay(30);
}[/code]

Hi,

A clarification will be provided tomorrow.

Sincerely,

Hi,

Please have a look at our newest code available here.

It now includes three examples using the modified PS2 BotBoarduino code you provided in your last post. We have re-added the “wrist rotate” code to it for people who may have this upgrade in their arm. Since it is not critical to the inverse kinematics, you can simply ignore it if you do not have the wrist rotate upgrade.

The examples are the following:

]Basic rotation and extension of the arm. This is a very simple example to show how to use the tmp***x,y,z,wa,g,wr] variables./*:m]
]Basic sequence follower. You can pre-programmed positions in 2 setup arrays (make sure to set how many positions are in total) and an array for the delays. The example makes the arm follow those positions and waits at each step an amount of milliseconds based on the delay array./:m]
]Keyboard control example. In this one, keys are sent by serial to the BotBoarduino to make the arm move. The keys used can be found in the code before the Arduino loop() function./:m]

Sincerely,

I am really desperate. I tested the code that you gave to me but still nothing happens.

Hi,

From your last picture, your setup looks like it is done properly and the jumper for power on the BotBoarduino is set to USB, so examples 1 & 2 should create movement of the arm as soon as you power it.

In your picture you do not show the power adapter (wall mounted) connected to the wiring harness. When you tested the code, did you connect it to the harness?

Also, which code example(s) did you try? Did you change anything in your setup since the last picture you showed us?

If this still does not work, please provide us with a video of your attempt following all the steps from programming the board with the example (#1 or #2) to showing the response of the arm once programmed.

Sincerely,

I tested all the examples that you shared with me.

So, are you telling me that the arm needs two power supplies? The USB cable supplies power for the programming functions of the Arduino, and I need an aditional AC wall adapter that supplies power to the servos of the arm?

Hi,

The servo motors require a lot of current (up to 2 A or more @ 6 V DC when in motion). The USB port only provides 5 V DC and up to 500 mA of current at maximum. This will not be enough to power the arm. The shoulder servomotor by itself can use more than the available current from the USB port when raising the arm.
Please see the attached image for details. This external power source is required for all of our robotic arms.

All of our Lynxmotion AL5 robotic arm kits come with a wall adapter (6 V DC, 2 A) with a standard barrel connector output. If you do not have one, you can purchase one such as this one or that one.

Sincerely,

Hi Scharette,

Thank you very much for your help! You were right the problem was I was missing the cable. My teacher gave me the AC power cable and now the arm works fine.

I have test the 3 examples that you shared with me and all of 3 worked.

Now I want to modify those examples but I have some questions:

  1. I dont know exactly what model of robot arm I am using (AL5A, AL5B AL5D), I know that the model is based on the size, but what dimensiones exactly I have to measure to identify the model of my arm?

  2. About the “basic sequence follower” example, I understood that the positions are defined on the following code lines:

// XYZ position of the gripper in relation to the base & wrist angle
float posListXYZWa][4] =
{
{5,8,90,0},
{8,3,90,0},

But exactly in what measure units are defined this positions ({5,8,90,0}) cm, inches…?

  1. I am really interested on use this example. I tested it and it worked fine, but I found a problem. The amount of movements that the arm can do is limited by the available serial space, and when there is no more space the arm doesn’t do more movements, and if I close and open again the serial window, the arm returns to its initial position. How can I modify the code to have no limit on the amount of movements that the arm can do? Maybe errasing the previous values saved on the serial memory.

Thanks for the help!

Hi,

Here are some answers to your questions:

Please have a look at the following blog post. The second section defines the size of the three models and where they are taken. The measurements are in inches and are taken from the shoulder to the elbow and also from the elbow to the wrist.

All units are either inches or degrees, similarly to the definitions in the code for the arm sizes (see the answer to question #1).
As for the order of the parameters, they are the same as the variable name. Therefore, in posListXYZWa, we have the X position of the wrist, followed by the Y position and then the Z angle (base angle) and ending with the wrist angle.

We do not understand the issue you mention. Please provide more details (maybe with some screenshots). The only use of the serial port that is done is to output the current position of the arm at every movement step.

Sincerely,

About my question 3:

I press the keys for the movements on the Serial window as I shown on picture 1 and the movements of the arm works exactly as the keys that I press. But when the window is full (according to what I research when the Serial memory is full as shown on picture 2 the arm doesnt do more movements. And if I close and open again the Serial window, the arm returns to its initial position. So, my question is how can I clear the Serial memory to have unlimited movements by this method.


Hi,

We tried to reproduce this issue but the arm did not stop responding.

Also, whenever you open the serial monitor window, it causes a reset of the Arduino board (hence why it returns to the default position). This also happens when you change the baud rate.

If you keep having issues with your serial monitor window, we recommend that you use a dedicated telnet/SSH software, such as Putty. As a bonus, you won’t have to press enter everything time you enter a new key.

Please let us know if using this software solve your issue.

Sincerely,