Please teach me how to simplify this code

So I basically want to define positions for a robot arm so I can write "Position1" or "Position2" etc without having to write a long code. And in these "Positionx" defintions I want the robot arm to return to the starting position at the end of each action.

Like this:

"Position1"=

myspeed=100;
for(pos = 0; pos <=myspeed; pos += 1)
{
myservoA.write(int(map(pos,1,myspeed,85,70))); // move from starting position to pick up little piece of paper

}
myspeed=500;
for(pos = 0; pos <=myspeed; pos += 1)
{
myservoC.write(int(map(pos,1,myspeed,40,34))); // lower the robot arm to pick up the piece of paper

delay(1);

}
myspeed=500;
for(pos = 0; pos <=myspeed; pos += 1)
{
myservoC.write(int(map(pos,1,myspeed,34,40))); // bring back robot arm to original height
delay(1);
}

{
Starting position
delay(1);
}

(and of course the starting position would have to be defined as well, but I hope you get the point)

Then I could have say 50 possible positions defined to cover the work space and then write:

{
Position1
}

And it would execute all of the above.

How do I write this? What are the commands? I'm new to programming. It's meant for a simple program for picking up small pieces of paper from a table and I intend to introduce vision later with the pixycam 2.
Then I could make a program that says something like ifBluepaper=true then move to Position(blue) or something like that.

I reckon you need to rethink your description and list ONLY the items that are different for a position. Don't include in your list things that will be same for all positions.

Without knowing the items that differentiate a position it is difficult to suggest a solution.

Read up about struct in the C++ language. I suspect you will be able to define the items for one position in a struct and then have an array of structs for the N positions.

...R

You have written blocking code. It cannot do anything else while moving. You may want to check collision sensors or a "stop" button while moving.

Look for a tutorial on state machines.

Also read about arrays in the Arduino reference.

Robin2:
I reckon you need to rethink your description and list ONLY the items that are different for a position. Don't include in your list things that will be same for all positions.

Without knowing the items that differentiate a position it is difficult to suggest a solution.

Read up about struct in the C++ language. I suspect you will be able to define the items for one position in a struct and then have an array of structs for the N positions.

...R

Well I thought that bringing back the C servo to original height before moving back to original position would make the robot run smoother so that's why that position is sort of repeated I guess. I also want the starting position to be repeated after each and every action.

Basically all I want is a way to be able to write that blabla1=codecodecode and then put in blabla1 instead of the code, surely there must be some command for this? I checked out your link but I'm really new at this and didn't see how to be able to use that for this.

I have recently been experimenting with a meArm robotic arm and I wanted to be able to move each of the 4 servos to any reasonable angle

First I wrote an input routine that would accept commands such as /b120 which commands the base to move to angle 120 and /s25 which commands the shoulder to move to angle 25. Linefeed was used as the input terminator.

Next I wrote a function that would accept the commands as strings (lowercase s), interpret them and move the relevant servo to the commanded position. I could now enter commands from the Serial monitor and cause a servo to move as commanded.

Like you I wanted to send sequences of commands to the servos so I put those in an array of which this is an example segment. b is base, s is shoulder, e is elbow and g is gripper

  //sequence 1
  {
    "1 block at 90 main commands only",
    "g120", //gripper open

    "b90", "e40", "s160", "g170", "s90", //forward, grip, retract

    "b150", "s160", "g120", "s90", //forward, release, retract
    "e40", "s160", "g170", "s90", //forward, grip, retract

    "b120", "s160", "g120", "s90", //forward, release, retract
    "e40", "s160", "g170", "s90", //forward, grip, retract

    "b90", "s160", "g120", "s90", //forward, release, retract
    "e40", "s160", "g170", "s90", //forward, grip, retract

    "b60", "s160", "g120", "s90", //forward, release, retract
    "e40", "s160", "g170", "s90", //forward, grip, retract

    "b30", "s160", "g120", "s90", //forward, release, retract
    "e40", "s160", "g170", "s90", //forward, grip, retract

    "b90", "s160", "g120", "s90", //forward, release, retract

    "end"
  },

This worked OK but was tedious to enter and many command sequences were repeated.

The next step was to use what amounts to subroutines of the movements, for example

  //sequence 8 - grab
  {
    "grab sequence",
    "g90","e40",  "s155", "g170", "s90", //forward, grip, retract
    "end"
  },
  //sequence 9 - drop
  {
    "drop sequence",
    "s160", "g140", "s90", //forward, release, retract
    "end"
  }

I changed the input routine and parser to allow it to accept lift and drop commands which cause the base to move as commanded and the lift or drop sequence to be called. An example of which would be

  {
    "lift block at 90 drop at 110",
    "L90",      //lift at 90
    "D110",     //drop at 110
    "end"
  },

The L and D commands trigger the sequences to move the 3 servos to lift or drop the target and the number indicates the base angle to do it at.

When running a sequence of commands if a servo is already in the commanded position the command to move there is ignored because it is not necessary.

I have also added a random move command which picks up an object from a random position in a previously defined map of blocks (held in an array of structs), drops the block in an available space and updates the map of blocks and spaces. Needless to say you can specify how many random moves should be made. At the end of the random sequence the blocks are put back on the same pattern as they started and at the end of any sequence of commands the special /a command is executed to move all of the servos to a home position, usually 90 degrees but it can be specified.

I am not sure whether any of this will help you but you should take lessons from it.

Write code incrementally and test small functions independently
Think ahead so that you have a picture of how your small pieces of code will fit together.
Give variables and functions meaningful names so that when you go back to the code you have a fighting chance of reading and understanding it.
Separate the data and the program. For instance my list of sequences and the map of the block positions are each in separate .h files which makes finding and amending them easier.
Print out what is going on when the program is running so that you can see what is happening in the program as well as what the servos are doing.
Do not run the servos at full speed because when anything unexpected happens there is potential for chaos and damage and I have the broken servos to prove it.

MorganS:
You have written blocking code. It cannot do anything else while moving. You may want to check collision sensors or a "stop" button while moving.

Look for a tutorial on state machines.

Also read about arrays in the Arduino reference.

The code that I posted was just a cut out, the robot works in a loop fine with no collisions. I'm basically just asking if there's an easy way to shorten code but all the tutorials that I've seen have to do with simple number calculations etc. Haven't seen anything thus far that actually takes a long string of code and gives it a short name that one can reuse. Surely there must be an easy fix for just shortening code?

Haven't seen anything thus far that actually takes a long string of code and gives it a short name that one can reuse.

You mean like a function ?

UKHeliBob:
You mean like a function ?

Yes, how would I write it? like Position1 = (a90, b60, c50)
I don't know how to formulate it.

Then I could just put

(
Position1
)

and use these stored positions in a program, thanks.

What I did was to put the positions in an array. The function to actually do the movement is passed the index number to the list of positions which it runs through until it finds the "end" and it exits. That way each set of commands could have a different number of commands in it.

If you want to give each set of commands a name rather than a number your could use an enum so that you could call the function like this

runCommandList(PICKUP123);  //pickup object at base angle 123

What I chose to do was to pass the base angle as a separate parameter, something like this

runCommandList(PICKUP, 123);  //pickup object at base angle 123

This makes the movement function more flexible

UKHeliBob:
What I did was to put the positions in an array. The function to actually do the movement is passed the index number to the list of positions which it runs through until it finds the "end" and it exits. That way each set of commands could have a different number of commands in it.

If you want to give each set of commands a name rather than a number your could use an enum so that you could call the function like this

runCommandList(PICKUP123);  //pickup object at base angle 123

What I chose to do was to pass the base angle as a separate parameter, something like this

runCommandList(PICKUP, 123);  //pickup object at base angle 123

This makes the movement function more flexible

So how would you change this code:

myspeed=500;
for(pos = 0; pos <=myspeed; pos += 1)
{
myservoC.write(int(map(pos,1,myspeed,33,40))); //
delay(2);
}

into "Position1"? so I could just write (position1) and it would contain all of the above? Thanks

Ok. 50 positions numbered. Each position has a specific value for servo A, B and C.

const int numPositions = 50;
int servoAPositions[numPositions] = {0, 123, 5 };  //fill in the rest
int servoBPositions[numPositions] = {0, 123, 5 };  //fill in the rest
int servoCPositions[numPositions] = {0, 123, 5 };  //fill in the rest

void moveToPosition(int position) {
  servoA.write(servoAPositions[position]);
  servoB.write(servoBPositions[position]);
  servoC.write(servoCPositions[position]);
}

Servo servoA, servoB, servoC;

void setup() {
  //attach servos etc
}

void loop() {
  for(int i=0; i<numPositions; i++) {
    moveToPosition(i);
    delay(2000);
  }
}

Of course you want to control the speed too. I will leave that up to you to do in your best non-blocking method.

it goes like this:

( guy who does not know better )

( declare variables, void setup )

void loop()
{
do this
do that
do something else

and in no time you get a void loop() so big it won't all fit on the screen

( guy who knows better:)

void loop()

{
  FeedGpsParser();                                      // decode incoming GPS data
  SyncCheck();                                          // synchronize to GPS or RTC
  UpdateDisplay();                                      // if time has changed, display it
  readSensors();                                        // monitor sensors & take action 
}

each of those functions are called every pass through the loop. the loop is compact.
each function is very busy, but each function is a compact bit of code that can be cut and pasted into a different project:

void UpdateDisplay()                                    // called from void loop

//  Call this from the main loop
//  Updates display if time has changed
{
  time_t t = now();                                     // get the current time
  if (t != displayTime)                                 // has time changed?
  {
      UpdateDST();                                      // check DST status
      ShowDateTimeUTC(t);                               // Display the current UTC time
      ShowDateTimeLocal(LocalTime());                   // Display the current local time
      displayTime = t;                                  // save current display value
      //PrintTime(t);                                   // for diagnostics
  }

}

this function calls other functions. note that this function sends information to - "passes a parameter to" - another function:

ShowDateTimeUTC(t);                               // Display the current UTC time

"t" is the current system time, passed to function ShowDateTimeUTC

large blocks of code get written this way, void loop() calling functions which call other functions.

function names can not have spaces, so we typically capitalize the first letter in the second and subsequent words in the function name:

readSensors();

and I prefer to leave a // note saying what called this function, to simplify trouble shooting.

arduinorookie100:
So how would you change this code:

myspeed=500;
for(pos = 0; pos <=myspeed; pos += 1)
{
myservoC.write(int(map(pos,1,myspeed,33,40))); //
delay(2);
}

into "Position1"? so I could just write (position1) and it would contain all of the above? Thanks

void position1()
{
    myspeed=500;
    for(pos = 0; pos <=myspeed; pos += 1)  
  {
    myservoC.write(int(map(pos,1,myspeed,33,40))); // 
    delay(2); 
  }

}

Then call position1() when you want to execute the commands in the function

Note, however, that you would need a separate function for each set of movements, which is not very desirable. There are better ways

arduinorookie100:
Well I thought that bringing back the C servo to original height before moving back to original position would make the robot run smoother so that's why that position is sort of repeated I guess.

That comment is not an appropriate response to the comment that you quoted. There is nothing in my comment that would prevent any movement that you should wish.

The comments by @UKHeliBob in Reply #4 illustrate what I was suggesting.

...R