Let's Make Robots!

Read GCODE and parse CoOrdinates

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.

#include <SD.h>
#include <AFMotor.h>

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;

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:
  // 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);
   while (digitalRead (button) == HIGH){   // stops script. Its waiting for a button press (LOW on "button")
  delay (1000);
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
      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 
        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(" Y: ");
        Serial.print(" Z: ");
        Serial.print(" penDown Boolean: ");
        //        delay (1000);
      stringIndex = 0; // clear the String index value for the next cycle