Function to control steppers XY

Hi, Over the Christmas holidays, I've decided to attempt building a laser cutter. I have thought of probably the best way of controlling it, however I need some help coding it.

Basically, I was thinking of a function that uses points.

For example, a function like GoToPoint(x, y);

The X and Y values would be the number of steps on the table. ie, if it takes 1000 steps to get across the Y of the table, and 500 for the X, setting GoToPoint(1000, 500); will take it right to the back corner.

This is easy enough, however the problem I am having is making it move in a diagonal line. Because the Arduino can't multitask, it can only run 1 stepper at a time. I have found that if you step 1 stepper 1, then the next and have it go as fast as the loop, I get fairly smooth motion, however I'm not sure how I'd go from getting a XY coordinate to draw a diagonal line?

Regards, Dan

If the motion is deltaX, deltaY, then one stepper needs to move deltaX steps while the other moves deltaY. So, for each step in X, the other needs to move deltaY/deltaX steps.

So, create a loop to step deltaX times. On each pass, step 1 in X then deltaY/deltaX in Y. You'll want to compute deltaY/deltaX as a float, and multiply that by the number of steps, so that sometimes it moves 0 steps in the Y direction and sometimes in moves 1 step in the Y direction, since the steps must be in whole amounts.

Do your motors/motor drivers allow micro-stepping? You can smoother lines if they do.

Thanks, didn't think about it that way.

Yes, theses are microstepping motors, I am just using the Arduino stepper library to control them. They do 200 steps per revolution. I intend using them with a worm gear, and then using threaded rods to move the carriages, so it will be pretty damn precise.

Yes, theses are microstepping motors,

You probably want to create a function that computes values to the nearest 1/4 step, then (assuming 4 micro-steps per step). Step the whole amount, and micro-step the fractional amount, for each overall step.

Another question regarding serial.

How would I go about parsing numbers thru serial into the code?

For example, x,y - 20,30

I don't fully understand how serial works, so it's making it kinda complicated.

Cheers, Dan

Serial data is just a stream of bytes. If you are sending data as strings, each byte is a character. When sending the data, you need to include some kind of start marker and some kind of end marker, like “<20, 35>”.

I’ve posted a number of times about how to read serial data with start and end markers. Search phrase: “started && ended”.

I found this, as you suggested:

void loop()
{
 if(Serial.available() > 0)
  {
    char aChar = Serial.read();
    if(aChar == '<')
    {
      pos = 0;
      do{
          while(Serial.available() <1)
            ; // wait for a character
        aChar = Serial.read();
        if(aChar >= '0' && aChar <= '9')              
          pos = pos * 10 + aChar - '0';           
      }
      while(aChar != '>');
      Serial.println(pos);
      pos = 0;
    }
  }
}

It picks up the first number fine :slight_smile:

However, I’m stuck as to how to have it store the 2nd number (After the ,) to a different variable.

how about:

void loop()
{
 if(Serial.available() > 0)
  {
    char aChar = Serial.read();
    if(aChar == '<')
    {
        pos = 0;
        do {
          while(Serial.available() <1); // wait for a character
          aChar = Serial.read();
        if(aChar >= '0' && aChar <= '9')
          pos = pos * 10 + aChar - '0';
      } while(aChar != ',');
        Serial.println(pos);
        pos = 0;
        do {
          while(Serial.available() <1); // wait for a character
          aChar = Serial.read();
        if(aChar >= '0' && aChar <= '9')
          pos = pos * 10 + aChar - '0';
      } while(aChar != '>');
        Serial.println(pos);
        pos = 0;
    }
  }
}

That worked, thanks :)

Sorry, one more question. How would I go about having it handle negative integers too?
Like: <-12,-198>

Cheers,
Dan

Since the minus sign comes first, you'll need to create a sign variable (int, so it can go negative) and set it to +1 initially. Set it to -1 if the character is a -.

When the delimiter is received, multiply pos (or pos2) by sign.

I'd recommend renaming pos to posX and pos2 to posY, so that their purpose is clearer.