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