Search code examples
arduinolineavr

Controlling 3 stepper to move on xyz direction


I am working on coding CNC. I can move x and y axes simultaneously to draw lines (Bresenham's algorithm). Now I want to add a 3rd axis but I do not have any idea how to move from (x0,y0,z0) to (x1,y1,z1).

Is there any algorithm for that purpose?


Solution

  • Use the Bresenham's again.

    Let DX = X1 - X0; DY = Y1 - Y0; DZ = Y1 - Y0; ... DЪ = Ъ1 - Ъ0;

    Let Dmax = max(|DX|, |DY|, |DX|, ..., |DЪ|); where |x| = modulus of x

    Let's init X = X0; Y = Y0; Z = Z0; ... Ъ = Ъ0;

    Let's init EX = 0; EY = 0; EZ = 0; .... EЪ = 0;

    for i := 1 to Dmax do 
      EX = EX + |DX|;
      if EX >= Dmax then
        EX = EX -Dmax;
        X = X + sign(DX);
        MOTOR_X_ONE_STEP(DX > 0 ? FORWARD : BACKWARD);
      end if 
    
      EY = EY + |DY|;
      if EY >= Dmax then
        EY = EY -Dmax;
        Y = Y + sign(DY);
        MOTOR_Y_ONE_STEP(DY > 0 ? FORWARD : BACKWARD);
      end if 
    
      EZ = EZ + |DZ|;
      if EZ >= Dmax then
        EZ = EZ -Dmax;
        Z = Z + sign(DZ);
        MOTOR_Z_ONE_STEP(DZ > 0 ? FORWARD : BACKWARD);
      end if 
    
      ...
    
      EЪ = EЪ + |DЪ|;
      if EЪ >= Dmax then
        EЪ = EЪ -Dmax;
        Ъ = Ъ + sign(DЪ);
        MOTOR_Ъ_ONE_STEP(DЪ > 0 ? FORWARD : BACKWARD);
      end if 
    
      // Now we are in the point (X, Y, Z, ..., Ъ);
    end for
    

    where sign(x) = (x < 0) ? -1 : 1;

    doesn't matter how many axis you have, Bresenham's algorithm still the same for all of them.

    As you can see the axis, which have the maximal |Dn| will increase each step.

    By the way. You can make the line looks better, if init all En values with half of Dmax:

    EX = Dmax / 2; EY = Dmax / 2; EZ = Dmax / 2; .... EЪ = Dmax /2;