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:
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();
}
|