Read GCODE and parse CoOrdinates

Posted on 03/12/2013 by ollyr
Tags: Legacy

So my polargraph had come to a halt, i had it running a processing sketch on a pc, and extracting shade data from images one pixel at a time. it had some cooool effects, im really happy with it but its time to move on.

I found i can convert a line/vector drawing to GCode in Inkscape, and as GCode is pretty much THE standard for opensource CNC it seems like the logical thing to use!

As before, this is a project for myself so im CERTAIN i havent gone about this the most effecient way (using a pre existing sketch would be the easiest option!) but its a learning process!

also, i am limited by what i know, so i may have done things in a slightly round about way!

Having said all that, this code took me maybe 20 hours (most of that spend trawling the internet for functions i could get it to do). Ignoring all the guff about motors (which i will use next), the sketch reads a GCode(saved as *.txt) file and extracts X values, Y values and Z position as a boolean value (pen up and pen down). (i have not bothered with curved motions yet, i will add that in the future! one objective at a time!)

if you want to use it feel free of course, but be aware that the SD card isnt on its normal pins (my motor shield is already using them) so i have had to modify my SD library to allow me to reassign the pins to the remaining analogue pins.

I hope it is as impressive as it was a pain to work out!

Thanks to Oddbot and Birdmun for forum assistance.

//LIBRARIES
#include <SD.h>
#include <AFMotor.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 motorL(200, 1);  // Left Motor, M1 & M2
AF_Stepper motorR(200, 2);  // Right Motor, M3 & M4 // Forward is Up on both motors.
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;

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

double x;
double y;
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); 
  motorL.setSpeed(20);  // 10 rpm   
  motorR.setSpeed(20);  // 10 rpm   

  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")
   }
   */
  delay (1000);
  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  
    {
      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; 

      //******processing of Gcode here*****
      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 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  x = 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 y = atof(carrayY); //convert the array into an Integer 
        // 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;
        }

        Serial.print("X: ");
        Serial.print(x);
        Serial.print(" Y: ");
        Serial.print(y);
        Serial.print(" Z: ");
        Serial.print(stringZ);
        Serial.print(" penDown Boolean: ");
        Serial.println(penDown);
        //        delay (1000);
      }
      stringIndex = 0; // clear the String index value for the next cycle
    }
  }
  myFile.close();
}

LikedLike this to see more

Spread the word

Flag this post

Thanks for helping to keep our community civil!


Notify staff privately
It's Spam
This post is an advertisement, or vandalism. It is not useful or relevant to the current topic.

You flagged this as spam. Undo flag.Flag Post