• Working Envelope

    agp.cooper3 days ago 0 comments

    Working Envelope

    I have been busy working through the design of the slew ring (i.e. Lazy Susan).

    Now that I am happy with this, I thought looking at the "required" envelope would be useful:

    I was targeting a rectangle two times arm length (width) by one time arm length (height).

    Also minimising the working area. The parameters where:

    • Arm 1: 125 mm
    • Arm 2: 125 mm
    • Arm 1:  -23 to 110 degrees
    • Arm 2:  20 to 145 degrees

    The 145 degrees on Arm 2 may be tricky for the current design:

    The maximum rotation is 113.5 degrees (red arm).


    After optimising the problem I get:

    The parameters where:

    • Arm 1: 169 mm
    • Arm 2: 169 mm
    • Arm 1:  3 to 129 degrees
    • Arm 2:  15 to 113.5 degrees (set range)

    The extra arm length means I can use a larger gear.
    Otherwise I can start moving the stepper motors apart.


    After working with the parameters for a while I can see an analytical solution to this.
    I coded a spreadsheet:

    D 125.00 Working Area Height
    L1 125.00 Arm 1 Length
    L2 125.00 Arm 2 Length
    A1Min -18.42 Calculated Motor 1 Range (Min)
    A1Max 103.45 Calculated Motor 1 Range (Max)
    A2Min 10.00 Motor 2 Range (Set Min)
    A2Max 140.00 Motor 2 Range (Set Max)
    Dx -116.91 Bottom Left Corner
    Dy 85.51 Bottom Left Corner

    Here is the image:


    Here is a design for 180mm length arms (rather than the 125mm length arms calculated above):

    The work area is 360mm x 180mm and the platform is 480mm x 480mm.

    Here is the design in section:

    All good!


  • Why Laser Cut MDF?

    agp.cooper02/11/2019 at 12:14 0 comments

    Material Mechanical Properties


    I often start a mechanical design with Aluminum (steel is too hard for my China CNC machine to cut (unless I am desperate). Aluminium is easy to cut if you use the right cutter (i.e. single flute). Aluminium angle is light and stiff, but cutting both sides of the angle accurately is an unresolved problem. Aluminium flat bar is a good compromise. It just becomes a design issue.

    Aluminium Mechanical Properties

    Alloy                          6061-T1

    Thickness                    3 mm

    Young's Modulus     69 GPa

    Ultimate Strength    210 MPa

    Yield Strength          110 MPa

    Working Stress         80 MPa

    Perspex (Acrylic)

    The stuff looks good and the "good" stuff lasts. I find most of the stuff I get stress cracks after a few months. So although I am keen to use it, I dare not as I don't know if I have the "good" stuff.

    Acrylic Mechanical Properties

    Thickness                    3 mm

    Young's Modulus     3.2 GPa

    Yield Strength          70 MPa

    Working Stress         45 MPa

    MDF (that cheap fibrewood board!)

    I use an online laser cutting service and the thickest they offer is 6mm.

    MDF Mechanical Properties

    Thickness                    6 mm

    Young's Modulus     4.0 GPa

    Bending Strength      18 MPa

    Working Stress          12 MPa

    So MDF is pretty weak but it is thicker. So why use it?

    Stress and Deflection

    There are lots of failure modes and serviceability requiements that real mechanical design needs to consider, but for toys only "stress" and "deflection" are important.

    For a canterlever flat bar (beam) of length (L), width (b), thickness (h) and a point load of (F):

    Young's Modulus     E

    Moment of Inertia    I=b*h^3/12   (m^4) 

    Section Modulus     Z=b*h^2/6   (m^3)

    Moment                   M=L*F           (Nm)

    Stress                       S=M/Z          (Pa)

    Deflection                d=F*L^3/I/E/3

    So what does all this mean?

    From a serviceability point of view, deflection is important.

    A "floppy" CNC machine is not much use.

    We can either use very stiff (high Young's Modulus (E)) materials or use thicker materials.

    The deflection equation tells us that if the material is twice as thick (6 mm versus 3 mm) then the deflection will be 1/8. So although Aluminium is 17 times stiffer than MDF,  as the MDF is twice as thick the deflection will only be twice that of Aluminium!

    One of the advantages of MDF is that you only need to glue two pieces together (for 12 mm thickness) and it will be much stiffer than Aluminium and just stiffer than 3 mm steel (E=210 GPa).

    The other reason to use MDF is that so long as it does not get wet it is dimensionally stable.


    Although I considered doubling up the thickness of the first arm of the SCARA, I have "another trick up my sleeve", I can epoxy fibreglass on both sides of the MDF to increase both strength and stiffness.


  • Prototype Hardware

    agp.cooper02/04/2019 at 04:38 0 comments

    Very Simple Hardware

    A simple laser SCARA:

    It uses 50mmx25mmx3mm aluminum bracket.

    The main downsides are:

    • direct drive (with micro-stepping)
    • single motor axles
    • canter-lever design.

    Still it should be useful for testing.

    Reworked the design

    Reworked the design away from 50mm x 25mm 3mm aluminum angle.

    Here is a 6mm MDF design:

    And the laser cutout (300mmx300mmx6mm MDF sheet):

    The bending moment calculations suggest less than 0.5mm deflection (assumes 2.5N end load). Maximum end load is 30N (~5mm deflection).

    I sent the design away to be cut by a professional laser cutting company.


  • gCode2SCARA GUI

    agp.cooper01/28/2019 at 12:40 0 comments


    Created a GUI version of gCode2SCARA, call SCARA2gCodeTest (I seem to have messed up the name!). The GUI has the added advantage of communicating via a serial port (real or USB) to talk directly to Grbl:

    Here is a typical input gCode file (that can been filtered using the input tolerance slider):

    And the output (SCARA) gCode (that can also be adjusted to smoothness):

    Note, I have deliberately set the offsets so that port of the file is out of bounds.

    Just for fun, the stepper motor steps per revolution can be reduced (from 19200 to 3200):


    Some minor bugs. with the filter code. Exporting some blank lines.

    More bugs!

    Implemented a Feed Speed control for the SCARA (it is a laser engraver after all). UV space is non-linear so need to issue an updated SCARA feed speed more often.

    I have assumed Grbl is set to 100 steps per mm for each axis, so his needs to be added to the GUI interface.


    If I abort Grbl while running, it locks it self. Even after soft-reset it needs a $X to unlock.


    Updated the serial code to accept ttyACM0-7 as the AtMega2560 Pro-mini uses a different RS232 chip.


    Otherwise, all good, AlanX

  • The Stepper Motor Driver Board

    agp.cooper12/14/2018 at 22:52 0 comments

    The Stepper Motor Driver Board

    Here is the Stepper Motor Driver  Board:

    Almost no documentation in the Internet on this board! It is cheap and I have used it before.

    Mapping/tracing the Nano pins I get:

    • RX - Serial Receive (pin provided but not used)
    • TX - Serial Transmit (pin provided but not used)
    • D2 - X Direction
    • D3 - Y Direction
    • D4 - Z Direction
    • D5 - X Step
    • D6 - Y Step
    • D7 - Z Step
    • D8 - Enable
    • D9 - +/- X End Stops (pin provided but not used)
    • D10 - +/-Y End Stops (pin provided but not used)
    • D11 - +/-Z End Stops (pin provided but not used)
    • D12 - Free (pin provided)
    • D13 - Free (pin provided)
    • A0 - Abort (pin provided but not used)
    • A1 - Hold (pin provided but not used)
    • A2 - Resume (pin provided but not used)
    • A3 - Coolant Enable (pin provided but not used)
    • A4 - SDA (pin provided but not used)
    • A5 - SCL (pin provided but not used)
    • A6 - Free (pin provided)
    • A7 - Free (pin provided)

    There are also:

    • +5v0 and ground pins
    • +3v3 and ground pins (uses an on board regulator)
    • Reset button (for Nano)
    • E-Stop pins (same as reset)
    • The power plug (Motor Power 8-12v):
      • Powers the Nano and via a shunt powers the A4988 stepper motor boards.
      • Otherwise the A4988 boards and the Nano are powered separately.
    • Under each A4988 stepper motor board are pins to shunt (S) the micro-stepping:
      • MS1 MS2 MS3 (up view)
      •      -        -       -  Full Step
      •      S       -       -  Half Step
      •      -       S       -    1/4 Step
      •      S      S       -   1 /8 Step
      •      S      S      S  1/16 Step   


    One fault with these boards is that the shunts to control the micro stepping does not work. I added these 10k pull-ups to fix the problem:


    Pre-processing "cartesian" gCode with gCode2SCARA allows the use of Grbl for a SCARA arm (UVZ type). This what I would recommend to get started.

    Not Grbl

    Is some code that I wrote that will also do the job.

    Motion Controller

    Is some more code that I wrote (but needs some work of the interpreter) that could also do the job. I intend to finish this code off to work with gCodeFilter and gCode2SCARA at some point of time.

    gCode2SCARA Command Line Options

    If you have not realised, gCode2SCARA is a command line program program designed to be used via a batch file. Here are the current options:

    • -i       Input File

    • -o     Output File

    • -t      XY Space Tolerance (mm)

    • -s     UV Space Tolerance (full steps)

    • -xc   gCode X Offset (mm)

    • -yc   gCode Y Offset (mm)

    • -L1   Arm 1 Length (mm)

    • -L2  Arm 2 Length (mm)

    • -M1  Motor 1 Steps

    • -M2 Motor 2 Steps

    This project could benefit from a "Visual Windows" programming approach, so probably time to look at what is available for Linux that is simple to use.


  • gCode2SCARA

    agp.cooper12/13/2018 at 00:08 0 comments

    gCode to SCARA

    The code is basically done, some check work remains.

    Here is the XY space (filtered from 45984 points down to 2029 points, i.e. -t 0.01):

    And here is the UV Space (-s 0.01 and 2029 points, no additional inserted point):

    The UV plot (i.e. the output) however does not consider the step resolution (i.e. UV space is floating point). The plot seems to be in the wrong quadrant (it is possible as I have changed the reverse kinematics mathematics).

    I will will have to create another plot window to show the effect of step resolution.

    So just some tidy up remains.

    Code Checks Out

    Yesterday I was helping my partner clean her house after the floor boards were sanded and varnished. So no work!

    The code checks out, need to do something better for when the arms will not reach, currently just set the location to (0,0). Better to make it obvious in the imagery.

    Checked that the reverse kinematics works in all quadrants. Here is an example with the arm movements shown:

    Added a Bressenham trace (yellow/green), in this case for M1 and M2 equal to 400 steps each (note, the image has been shifted to exceed the limits of the reach of the arms):

    Here is the case for M1 and M2 equal to 1600 steps (1/4 micro-stepping):

    And finally M12800 (1/32 micro stepping):

    Note that G0 (rapid movement is an arc rather than a straight line).

    So other than modifications required (discovered) when I actually use the code on a machine, it is done.


  • Short Cut - Converting gCode Cartesian to Polar

    agp.cooper12/12/2018 at 01:44 0 comments

    Short Cut

    Its a rather "long road" to write a Grbl replacement (perhaps later), but converting gCode from XYZ to UVZ is not. I have seen that someone has already done this on the Internet (sorry I have lost the link). So basically after conversion you can use Grbl instead.

    Perhaps I am wrong but Grbl does not appear to handle UVZ coordinate systems.

    I already have a gCode Filter project that can be co-opted into service.

    After filtering the gCode to remove "redundant" segments (i.e. the main function of gCode Filter), I only need map the UVZ space and to insert the critical points.

    I have made a start, set up two graphical results windows, one for XY space and the other for UV space. Still about a days coding left to complete (wishful thinking perhaps?).


    One of the issues for construction of a SCARA is the bearing. Nearly all the projects I have looked at are DIY. It would be nice to get something reasonalbe (lazy susan bearings are pretty bad!) off the self.

    For a big project a car one piece stub axle looks like an option (~AUD50):

    After a bit of searching I found good candidate, a bicycle front wheel hub:

    Are you excited yet? AlanX

  • Divide and Conquer Wins

    agp.cooper12/11/2018 at 12:44 0 comments

    Divide and Conquer (Option 1)

    After playing with the Options presented in my first post, I have decided Option 1 is the best. Why? It  should have the least number of the expensive reverse kinematic calculations. Consider a very coarse tolerance (=128):

    Note that the UV space (blue lines) has only 6 points (the straight lines between them are Bressenham lines).

    Now the medium tolerance case (=32):

    Here there is only 13 reverse kinematic calculations.

    Now the very fine tolerance (=8):

    Here there is only 25 reverse kinematic calculations.

    Finally ultra fine tolerance (=1), has 67 calculations:

    Fast Trigonometry

    Although the number of reverse kinematic calculations are a minimum, there still may be advantage is fast (integer?) methods. The CORDIC algorithm comes to mind, especially for the ATAN2() and sqrt() functions. ArcSin/ArcCos should also be possible.

    Here is my version of Rect2Polar (i.e ATAN2() and sqrt()) using short (i.e int16) integers:

    // Include libraries
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <string.h>
    #include <math.h>
    #include <stdbool.h>
    void rect2polar(short X,short Y,short *R,short *A)
      // ATAN_Table is the values of ATAN(1/(2^i))*400*32/2/Pi micro-steps
      short ATAN[12]={1600,945,499,253,127,64,32,16,8,4,2,1};
      short i,Xnew,Ynew;
      if (X<0) {
        (*A)=200*32; // 180 degrees
      } else if (Y<0) {
        (*A)=400*32; // =360 degrees
      for (i=0;i<12;i++) {
        if (Y<0) {
          // Rotate CCW
        } else {
          // Rotate CW
      // Adjust for gain (=X*0.607252935)
    int main(void) {
      short A,R,X,Y;
      // R=621*32 max
      printf("Rect2Polar x %8.3f y %8.3f ang %8.3f hyp %8.3f\n",X/32.0,Y/32.0,A*360.0/400.0/32.0,R/32.0);
      printf("atan2()    x %8.3f y %8.3f ang %8.3f hyp %8.3f\n",X/32.0,Y/32.0,360+atan2(Y,X)*180/M_PI,sqrt(X*X+Y*Y)/32.0);
      return 0;

    Here is the result:

    $ ./ShortCAtan
    Rect2Polar x -439.000 y -439.000 ang  225.028 hyp  620.812
    atan2()        x -439.000 y -439.000 ang  225.000 hyp  620.840

    So about  4 digits of accuracy with 16 bit integers.

    Reverse Kinematica

    I reworked the mathematics to suit CORDIC:

    • R=sqrt(X*X+Y*Y);
    • A0=atan2(X,Y);
    • A1=A0-PI/2+asin((L1*L1+R*R-L2*L2)/L1/R/2);
    • A2=PI/2-asin((R*R-L1*L1-L2*L2)/L1/L2/2);
    • X=cos(A1)*L1+cos(A1+A2)*L2;
    • Y=sin(A1)*L1+sin(A1+A2)*L2;

    ArcSin CORDIC

    Here is my ArcSin CORDIC:

    // This version works properly but has a multiplication in the main loop 
    short arcSin(short R, short S) {
      // ATAN_Table is the values of ATAN(1/(2^i))*400*32/2/Pi micro-steps
      short ATAN[12]={1600,945,499,253,127,64,32,16,8,4,2,1};
      // SEC[i]=(int)((1/COS(ATAN(1/(2^i)))-1)*(2>>14)+0.5);
      short SEC[15]={6787,1935,505,128,32,8,2,1,1,1,1,1,1,1,1};
      short i,Rnew,Y,Ynew,A;
      for (i=0;i<=11;i++) {
        if ((Y<S)&&(A<100*32)) { // 90 degrees
          // Rotate CCW
        } else {
          // Rotate CW
      return A;

     The down side of my ArcSin CORDIC is the multiplication inside the main loop. I remember I had to do the multiplication to avoid instability.


  • SCARA Reverse Kinematics

    agp.cooper12/10/2018 at 02:37 0 comments

    SCARA Model

    Here is an example of the type of SCARA that I want to model:

    Two X and Y arms and linear Z (say):

    L1 = 200mm

    L2 = 150mm

    Z = 150mm

    Two stepper motors:

    M1 = 400 steps (assume direct drive for the moment)

    M2 = 400 steps(assume direct drive for the moment)

    Also I want to use an Arduino Nano for the motion controller.

    Forward Kinematics

    Ignoring the Z axis for the time being, the forward kinematics represented by (U,V) to (X,Y), where (U,V) are polar motor steps and (X,Y) are the "real world" cartesian coordinates:

    • U is the polar (angular) position (steps) for motor 1
    • V is the polar (angular) position (steps) for motor 2
    • X is the "x cartesian" position in mm
    • Y is the "y cartesian" position in mm

    The forward mathematics is:

    • X=sin(2*Pi*U/M1)+sin(2*Pi*(U/M1+V/M2))
    • Y=cos(2*Pi*U/M1)+cos(2*Pi*(U/M1+V/M2))


    Ignoring the Z axis for the time being, the reverse kinematics represented by (X,Y) to (U,V):

    • R=sqrt(X*X+Y*Y)
    • U=atan2(X,Y)-acos((L1*L1+R*R-L2*L2)/L1/R/2)
    • V=PI-acos((L1*L1+L2*L2-R*R)/L1/L2/2)


    • V=acos((R*R-L1*L1-L2*L2)/L1/L2/2)

    I have reworked the equations to:

    • R=sqrt(X*X+Y*Y)

    • CosA=(L1*L1+R*R-L2*L2)

    • SinA=sqrt((2*L1*R-CosA)*(2*L1*R+CosA))

    • U=atan2(Y,X)-atan2(SinA,CosA)

    • CosA=(R*R-L1*L1-L2*L2)

    • SinA=sqrt((2*L1*L2-CosA)*(2*L1*L2+CosA))

    • V=atan2(SinA,CosA);

    The reason is that sqrt() and atan2() is a well known for embedded applications.

    Problems with Reverse Kinematics

    Two issues:

    1. The equations assume either left or right elbow operation. The mathematics is right elbow at the moment.
    2. The cartesian coordinates do not map neatly with polar coordinates. That is, x and y positions do not usually match (map) an exact stepper motor position.

    For example:

    Note how straight lines in XY space are curves in UV space, and motor step resolution (in UV Space) maps into jagged steps in XY space.

    (The plotted square is 125 mm x 125 mm, the arms are 200 mm and 150 mm, and the motors are both 400 steps.)

    Okay, the third problem is the need for gearing as the motor step resolution is too low.


    Mapping Options

    I have tried three methods for accurate XY space to UV space.

    Option 1

    Segment the UV space curves into straight lines (by inserting points) using a tolerance (i.e. if the tolerance is not exceeded then a point need not be inserted):

    This works well for feeding the mapped UV space directly into a Bressenham's Line Algorithm (i.e. Grbl).

    This option could be pre-processing or on-the-fly (i.e. on the motion controller).

    Option 2

    Nearest UV space point mapping (path search):

    The method seems to be efficient (with look up tables) and path search algorithm can certainly be improved. This algorithm would replace the Bressenham's Line Algorithm (i.e. exports to the motor controller hardware directly).

    This option would be on-the-fly (i.e. replaces Grbl).

    Option 3

    This options breaks the XY space lines into very small segments that are then mapped to UV Space. Duplicate UV space points can be removed. Simple but inefficient.

    Pre-processing only.