Advertisement
Guest User

simple-as220-drawbot

a guest
Oct 12th, 2018
185
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <AFMotor.h>
  2. // REad about AFMotor here: https://learn.adafruit.com/afmotor-library-reference/af-stepper-class
  3.  
  4. int stepType = INTERLEAVE;
  5. // If you're using INTERLEAVE stepping style, then you get an "in between" step, so can double your resolution.
  6. // Double your physical steps per revolution number:
  7. int motorStepsPerRev = 400; // 400 not 200
  8.  
  9. AF_Stepper stepper1(motorStepsPerRev, 1);  // left hand motor
  10. AF_Stepper stepper2(motorStepsPerRev, 2);  // right hand motor
  11.  
  12.  
  13. //how can i change this to cm or metric instead?
  14. //    Don't need to change anything, as long as everyhting is in the same unit then it'll work out
  15.  
  16.  
  17. // Work out the amount of thread that would be let out per revolution
  18. float mmPerRev = 8 * PI;   // = 8mm * pi = 25.13274
  19.  
  20. // Work out the amount of thread that would be let out per step.
  21. // This is your native unit size, the smallest movement that can be expressed.
  22. float mmPerStep = mmPerRev/motorStepsPerRev;     //  25.13274/400 = 0.062831
  23.  
  24.  
  25.  
  26. //   Not sure how he did it, but that's how I'd do it. Alternatively you could measure one full loop of thread around your drum and hard-code the value.
  27.  
  28. // The measurement shouldn't be from the motor centre, rather it's from the outer surface of the bobbin.
  29. // Look at the layout diagram on http://www.polargraph.co.uk/setup/polargraphsd-building-the-machine/ for an example of "machine width".
  30. // Approximate dimensions of the total drawing area, measured in motor steps,
  31. // If your surface is 405m wide and 420mm tall.
  32.  
  33. // To stop yourself from getting confused about which coordinates system, or whether it's measured in steps or mm, give your
  34. // variables descriptive names and stick to conventions like X&Y ALWAYS refers to cartesian space and A&B ALWAYS refers to the native coordinates space.
  35. int mmWidth = 405;
  36. int mmHeight = 420;
  37. int stepsWidth = mmWidth / mmPerStep;    // If your physical machine is 405mm wide (40.5cm), so 405/0.062831 = 6445 steps wide.
  38. int stepsHeight = mmHeight / mmPerStep;  // 420/0.062831 = 6684 steps tall.
  39.  
  40.  
  41.  
  42. /*   Cartesian coordinates of current (starting) point
  43.  *   The cartesian coordinates system looks like this I think:
  44.  *
  45.  *
  46.  *  O---------------O
  47.  *  |0,0         5,0|
  48.  *  |               |
  49.  *  |               |
  50.  *  |               |
  51.  *  |               |
  52.  *  |0,5         5,5|
  53.  *  |-------*-------|
  54.  */
  55. int currentX = stepsWidth / 2;  // halfway across - 3222 steps across
  56. int currentY = stepsHeight;    // the bottom edge of the surface - 6684 steps down
  57.  
  58.  
  59. // Approximate length of strings from pen to top corners
  60. // YEs, this works out the length of the thread at the start position.
  61. int currentA = sqrt(pow(currentX,2)+pow(currentY,2));  
  62. int currentB = sqrt(pow((stepsWidth-currentX),2)+pow(currentY,2));
  63.  
  64.  
  65. // Don't worry about paper size right now, that's just a way of fitting the artwork to the page.
  66.  
  67.  
  68. void setup() {
  69.  
  70.   Serial.begin(9600);
  71.  
  72.   Serial.print("Cartesian position in steps: X: ");
  73.   Serial.print(currentX);
  74.   Serial.print(", Y:");
  75.   Serial.print(currentY);
  76.   Serial.println(".");
  77.  
  78.   Serial.print("Thread lengths: A: ");
  79.   Serial.print(currentA);
  80.   Serial.print(", B: ");
  81.   Serial.print(currentB);
  82.   Serial.println(".");
  83. }  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91. void loop(){
  92.  
  93.  
  94.   /* to draw a square in the middle of the machine...
  95.    *  Your starting position is x:3222, y:6684.
  96.    *  The exact centre of the surface is x3222 y3342, so lets say you want to draw a square starting there.
  97.    *  
  98.    *  For ease of maths, lets make the square 1000 steps per side, and make the top-left corner in the centre of the page.
  99.    *  
  100.    *  Top left corner:    x3222 y6684
  101.    *  Top right corner:   x4222 y6684
  102.    *  Bot right corner:   x4222 y7864
  103.    *  Bot left corner:    x3222 y7864
  104.    *  
  105.    * 1000 steps is 1000 * mmPerStep = 1000 * 0.062831 = 62.831mm
  106.    *  
  107.    *  
  108.    */
  109.  
  110.   moveToCartesianSteps(3222, 6684); // move to the first point, top-left
  111.   delay(1000);
  112.   moveToCartesianSteps(4222, 6684);  // top right
  113.   delay(1000);  
  114.   moveToCartesianSteps(4222, 7684); // bottom right
  115.   delay(1000);
  116.   moveToCartesianSteps(3222, 7674); // bottom left
  117.   delay(1000);
  118.   moveToCartesianSteps(3222, 6684); // back to the beginning again
  119.  
  120.   // in this model, negative numbers are off the left-hand side of the machine, and off the top. They aren't physically possible to get to.
  121.  
  122.   }
  123.  
  124. void moveToCartesianSteps(int targetX, int targetY) {
  125.  
  126.   // Turn the stepper motors to move the marker from the current point (x1,
  127.   // y1) to (targetX, targetY)
  128.   // Note: This only moves in a perfectly straight line if
  129.   // the distance is the same in both dimensions; this should be fixed, but it
  130.   // works well
  131.  
  132.  
  133.   // targetA and targetB are the final lengths of the left and right strings
  134.   int targetA = sqrt(pow(targetX,2)+pow(targetY,2));   //these are the kinematics math to get length of new positon x2,y2
  135.   int targetB = sqrt(pow((stepsWidth-targetX),2)+pow(targetY,2));
  136.  
  137.   // For each axis, whether we need positive, negative or no step to get to the target
  138.   int stepA;
  139.   int stepB;
  140.  
  141.   if (targetA>currentA) {
  142.     stepA=1;
  143.   }
  144.   if (currentA>targetA) {
  145.     stepA=-1;
  146.   }
  147.   if (targetA==currentA) {
  148.     stepA=0;
  149.   }
  150.  
  151.   if (targetB>currentB) {
  152.     stepB=1;
  153.   }
  154.   if (currentB>targetB) {
  155.     stepB=-1;
  156.   }
  157.   if (targetB==currentB) {
  158.     stepB=0;
  159.   }
  160.  
  161.   // Change the length of currentA and currentB until they are equal to the desired length
  162.   while ((currentA != targetA) || (currentB != targetB)) {
  163.    
  164.     if (currentA != targetA) {
  165.       currentA += stepA;
  166.       stepper1.onestep(stepA, stepType); // this is the step command which only steps once could i change this to put my own high low instead?
  167.  
  168.       // Yes - this is where the motor gets stepped. IF you are using a stepper driver that has a simple step+direction pins, then that'll be easy.
  169.     }
  170.    
  171.     if (currentB != targetB) {
  172.       currentB += stepB;
  173.       stepper2.onestep(-stepB, stepType);  // here i get a bit confused as the -stepB suggests to me that it will alwasy step left yet it doesnt so whats the - bit about?
  174.  
  175.       //  It just inverts the value, so converts 1 to -1, or -1 to 1.
  176.       //  I guess this is because the right-hand motor must turn in the opposite direction to the left-hand one in order to let thread out.
  177.     }
  178.   }
  179.  
  180.   currentX = targetX; //making current positon current position
  181.   currentY = targetY;
  182. }
Advertisement
Advertisement
Advertisement
RAW Paste Data Copied
Advertisement