Forum

Welcome Guest 

Show/Hide Header

Welcome Guest, posting in this forum requires registration.





Pages: [1]
Author Topic: Curved "straight" lines
OllyR
Newbie
Posts: 7
Permalink
Post Curved "straight" lines
on: December 17, 2013, 21:13
Quote

Hi Guys!

So after a worryingly long period of effort i managed to get this thing plotting. One of those annoying jobs where each fix was incredibly simple once you knew it (thanks for your help over on Accelstepper Sandy)

I have plotted a basic "Hello World". the Font is Times new Roman:

Image

Also, the image is upside down, because it draws it upside down ( i need ot tweek that out in the sketch some time).

Notice how the straight edges are curved? most noticeable on the W, the Ls and the back side of the D.Interestingly not so evident on the H (but still there). I have fiddled with the AccelStepper settings, the sketch currently uses the distance of each motion, on the X and Y as the speeds so it SHOULD finish each move at the same time, but the accelerations appear to be out.
Also, there is still a noticible curve to it, i thought i had cut that out in my geometry calculations. I will have to double check them i think...
Any suggestions as to how i can sort these issues?
...I suppose i could force the Inkscape plot to make no points further than X pixels apart, resulting in lots of tiny straightish lines making up one bigger straight line..... I might give this a go now.
Thanks for looking!

Ol

Oh and here is the sketch:

//LIBRARIES
#include <SD.h>
#include <AFMotor.h>
#include <AccelStepper.h> // Accel stepper used to allow for Curves and angled lines
#include <Servo.h>

//CONNECTIONS
File myFile; // instance of a file
const int chipSelect = 15; // adafruit SD breakout, wired 15 - 18. must use modified SD library to allow for reassignment of pins.
AF_Stepper StepperL(200, 1);  // Left Motor, M1 & M2
AF_Stepper StepperR(200, 2);  // Right Motor, M3 & M4 // Forward is Up on both motors.
Servo Pen;

void forwardstepL() {  
  StepperL.onestep(FORWARD, SINGLE);
}
void backwardstepL() {  
  StepperL.onestep(BACKWARD, SINGLE);
}
// wrappers for the second motor!
void forwardstepR() {  
  StepperR.onestep(FORWARD, SINGLE);
}
void backwardstepR() {  
  StepperR.onestep(BACKWARD, SINGLE);
}

// Motor shield has two motor ports, now we'll wrap them in an AccelStepper object
AccelStepper stepperL(forwardstepL, backwardstepL);
AccelStepper stepperR(forwardstepR, backwardstepR);


const int button = 13; //button holds the sketch in setup, until pressed. This stops the motors from moving under USB power while uploading.
const int led = 14;
const int relay = 2;

// DIMENSIONS
int offset = 1300; // offset along X & Y axis, to 0,0 centre position, from pivots
int scale = 5; // scale the image?

// WORKING VALUES
char inputCharString [100];
char inputChar;
int stringIndex = 0; // String stringIndexing int;
String stringX;
String stringY;
String stringZ;

double readX;
double readY;
double prevhL;
double prevhR;
double hL;
double hR;
float ratioL;
float ratioR;

boolean prevPenPos; // previous pen position, for comparison.

boolean penDown = false;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  // setup
  pinMode (led, OUTPUT);
  pinMode (button, INPUT);
  pinMode (relay, OUTPUT);
  Pen.attach(9); 
  Pen.write(0);

  stepperR.setAcceleration(200.0);
  stepperL.setAcceleration(200.0);


  stepperL.setCurrentPosition(sqrt((sq(offset + readX))+(sq(readY-offset))));
  stepperR.setCurrentPosition(sqrt((sq(-offset + readX))+(sq(readY-offset))));



  Serial.print("Motors ready, Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(SS, OUTPUT);
  // see if the card is present and can be initialized:
  if (!SD.begin(15,16,17,18)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1) ;
  }
  Serial.println("card initialized.");
  //Open file to read
  myFile = SD.open("HELLO.txt");
  if (! myFile) {
    Serial.println("error opening datalog.txt");
    // If failed to open Wait forever 
    while (1) ;
  }
  digitalWrite (led, HIGH);
  Serial.println("Waiting...");
  //hold
  while (digitalRead (button) == HIGH){   // stops script. Its waiting for a button press (LOW on "button")
  }
  digitalWrite (relay, HIGH);

  Serial.println("....Running");
}
void loop() 
{
  while (myFile.available()) {
    inputChar = myFile.read(); // Gets one byte from serial buffer

    if (inputChar != 10) // Write to string until "end of line" ascii recieved
    {
      inputCharString[stringIndex] = inputChar; // Store it
      stringIndex++; // Increment where to write next
    }
    else  
    {
      { // in this bracket pair, 2dp cooridnates extracted from Gcode.
        inputCharString[stringIndex] = 0; // Add last char as ascii "void" to stop from reading the rest of the string (from prev lines longer than current one)
        String inputString = inputCharString; 

        if (inputString[0] == 'G') // if line starts with a G process it, if not discard it
        {
          int Xpos = inputString.indexOf('X'); //locate the position of X in the string
          int Ypos = inputString.indexOf('Y'); //locate the position of Y in the string
          int Zpos = inputString.indexOf('Z'); //locate the position of Z in the string

          if (Xpos > 0) { 
            stringX = inputString.substring(Xpos+1,Ypos-1) ; // value for X is located between X and Y. If it exists, cut it into a substring
          } // if it doesnt exist it will remain as previous
          if (Ypos > 0) { 
            stringY = inputString.substring(Ypos+1,Zpos-1) ; // value for Y is located between Y and Z. If it exists, cut it into a substring
          } // if it doesnt exist it will remain as previous
          if (Zpos > 0) { 
            stringZ = inputString.substring(Zpos,Zpos+10) ; // value for Z is located after the Z. no more than 10 chars needed. If it exists, cut it into a substring
          } // if it doesnt exist it will remain as previous

          // TRANSFER Z STRING INTO BOOLEAN PEN POSITION
          if (stringZ.charAt(1) == '1') { // Pen up pen down, Z1.000000 is pen in up position
            penDown = false;
          }
          else    if (stringZ.charAt(1) == '-') { // Z-0.125000 pen is in down position
            penDown = true;
          }
        } 
        if (penDown != prevPenPos) {// compare pen pos with previous. if different from prev update
          if (penDown == true){  
            Pen.write(50);
            delay (200);
          }
          else if (penDown == false){  
            Pen.write(0);
            delay (200);
          }
        }
        // TRANSFER X STRING INTO FLOAT (2dec place)
        char carrayX[stringX.length() + 1]; //determine size of the array
        stringX.toCharArray(carrayX, sizeof(carrayX)); //put readStringinto an array
        double  readX = atof(carrayX); //convert the array into an Integer 
        // TRANSFER Y STRING INTO FLOAT (2dec place)
        char carrayY[stringY.length() + 1]; //determine size of the array
        stringY.toCharArray(carrayY, sizeof(carrayY)); //put readStringinto an array
        double readY = atof(carrayY); //convert the array into an Integer 

        Serial.print("X: ");
        Serial.print(readX);
        Serial.print(" Y: ");
        Serial.print(readY);
        Serial.print(" penDown Boolean: ");
        Serial.println(penDown);

        readX = readX * scale;
        readY = readY * scale;
        double hL = sqrt((sq(offset + readX))+(sq(readY-offset)));
        double hR = sqrt((sq(-offset + readX))+(sq(readY-offset)));

        Serial.print(" hL: ");
        Serial.print(hL);
        Serial.print(" hR: ");
        Serial.println(hR);


        ratioL =((hL - prevhL));
        ratioR = ((hR - prevhR));     
        Serial.print("differenceL:");
        Serial.print(ratioL);
        Serial.print(" differenceR: ");
        Serial.println(ratioR);   
        if (ratioL < 0) ratioL = ratioL*-1;
        if (ratioR < 0) ratioR = ratioR*-1;
        if (ratioL == 0) ratioL = 1;
        if (ratioR == 0) ratioR = 1;

        Serial.print(" RatioL");
        Serial.print(ratioL);
        Serial.print(" RatioR: ");
        Serial.println(ratioR);

        stepperR.setMaxSpeed(ratioR*10);
        stepperL.setMaxSpeed(ratioL*10);

        stepperR.moveTo(hR);
        stepperL.moveTo(hL);

        while (stepperR.distanceToGo() != 0 || stepperL.distanceToGo() != 0) {
          stepperR.run();
          stepperL.run();
        }
        prevhL = hL;
        prevhR = hR;
      }
      prevPenPos = penDown; // update prev Pen Pos
      stringIndex = 0; // clear the String index value for the next cycle
      Serial.println();
    }
  }
  myFile.close();
}



OllyR
Newbie
Posts: 7
Permalink
Post Re: Curved "straight" lines
on: December 17, 2013, 22:59
Quote

So it appears that the curve to the overall image was BECAUSE the image is upside down. "Forward" on the motors on the Accelstepper library is the opposite to Forward on my previous sketchs which used the normal stepper library for some reason. I flipped the directions (forward now runs backward) and the image is the correct way up AND straight. i see now that the curve was a 2x exaggeration of the curve seen when you use the plotter without any compensation for the polargraphic angles. Now just to beat these bulges on the straight lines. The motors defiantly DON'T finish their moves in sync, i may need to work out a different plan of attack. to solve this

sandy
Administrator
Posts: 1317
Permalink
sandy
Post Re: Curved "straight" lines
on: December 17, 2013, 23:39
Quote

Oh that's a bit odd eh. Back in the day, I tried the same kind of approach (syncing motors) and gave up on it because I didn't really understand what I was doing - it didn't seem to do what I expected.

I think that cartesian straight lines will always need to be formed from multiple smaller lines though (each one with a little bulge). The native coordinates system is just too inherently curved to make for straight lines. For instance, a direct horizontal line from right to left should (in my head) be simple. Step motor a clockwise, step motor b clockwise. Pretty soon, the pen is at the right-hand-side of the page, that's great. However, the path it took to get there isn't straight at all, it's an arc. So this is the equivalent of a diagonal line in a cartesian space.

Actually what it needs to do in the first half of the line is step motor B slightly faster than A, and then in the second half, steps motor A faster than motor B.

So what I do is chop the line into segments, and draw each segment separately, like you're talking about. The acceleration becomes an issue then.

looks good!
sn

OllyR
Newbie
Posts: 7
Permalink
Post Re: Curved "straight" lines
on: December 18, 2013, 18:58
Quote

Hi Sandy. I sorted it. The problem was that while the motors max speed was correct (a ratio of the angle needed) the accelerations were identical, so the motor which moved further got up to speed slower (relative to the line length) than the shorter motor.
I mapped the ratio onto the accelerations too and its coming out pretty well! I think the only problems i can see are that at pen position changes, probably caused by the servo lifting the pen too roughly. It has run "hello world" really nicely, so i'm off to inkscape to get a better image!...

OllyR
Newbie
Posts: 7
Permalink
Post Re: Curved "straight" lines
on: December 18, 2013, 21:18
Quote

Image

Straight lines sorted (pretty much) as is the way-up and skewing, but now its losing track of where it is, each path starts a bit wonky off the correct position. again, this must be something to do with setting the accelerations according to the distances to be moved....

OllyR
Newbie
Posts: 7
Permalink
Post Re: Curved "straight" lines
on: December 18, 2013, 22:15
Quote

Looking into it, i think it might be that one spindle is slipping. All the misalignment is inline with the Right hand stepper motors axis.
Ive managed to get the offending spindle off, but it broke in the process. DOH! Now need to find another 15mm spindle/bobbin.

Pages: [1]
Mingle Forum by cartpauj
Version: 1.0.34 ; Page loaded in: 0.055 seconds.