diff --git a/SphereBot Arduino/SphereBot/SphereBot.ino b/SphereBot Arduino/SphereBot/SphereBot.ino index 6a6fd06..36a4858 100644 --- a/SphereBot Arduino/SphereBot/SphereBot.ino +++ b/SphereBot Arduino/SphereBot/SphereBot.ino @@ -40,10 +40,10 @@ #define VERSIONCODE "Spherebot 2.0" -StepperModel xAxisStepper(XAXIS_DIR_PIN, XAXIS_STEP_PIN, XAXIS_ENABLE_PIN, XAXIS_ENDSTOP_PIN, XAXIS_MS1_PIN, XAXIS_MS2_PIN, XAXIS_VMS1, XAXIS_VMS2, - XAXIS_MIN_STEPCOUNT, XAXIS_MAX_STEPCOUNT, 200.0, 16); -StepperModel rotationStepper(YAXIS_DIR_PIN, YAXIS_STEP_PIN, YAXIS_ENABLE_PIN, YAXIS_ENDSTOP_PIN, YAXIS_MS1_PIN, YAXIS_MS2_PIN, YAXIS_VMS1, YAXIS_VMS2, - 0, 0, 200.0, 16); +StepperModel xAxisStepper(XAXIS_DIR_PIN, XAXIS_STEP_PIN, XAXIS_ENABLE_PIN, XAXIS_ENDSTOP_PIN, XAXIS_MS1_PIN, XAXIS_MS2_PIN, XAXIS_MS3_PIN, XAXIS_VMS1, XAXIS_VMS2, XAXIS_VMS3, + XAXIS_MIN_STEPCOUNT, XAXIS_MAX_STEPCOUNT, XAXIS_STEPS_PER_FULL_ROTATION, XAXIS_MICROSTEPPING); +StepperModel rotationStepper(YAXIS_DIR_PIN, YAXIS_STEP_PIN, YAXIS_ENABLE_PIN, YAXIS_ENDSTOP_PIN, YAXIS_MS1_PIN, YAXIS_MS2_PIN, YAXIS_MS3_PIN, YAXIS_VMS1, YAXIS_VMS2, YAXIS_VMS3, + YAXIS_MIN_STEPCOUNT, YAXIS_MIN_STEPCOUNT, YAXIS_STEPS_PER_FULL_ROTATION, YAXIS_MICROSTEPPING); SoftwareServo servo; boolean servoEnabled=true; @@ -53,7 +53,7 @@ volatile long intervals_remaining=0; volatile boolean isRunning=false; // comm variables -const int MAX_CMD_SIZE = 256; +const int MAX_CMD_SIZE = 64; char buffer[MAX_CMD_SIZE]; // buffer for serial commands char serial_char; // value for each byte read in from serial comms int serial_count = 0; // current length of command @@ -67,6 +67,8 @@ double currentOffsetY = 0.; boolean absoluteMode = true; double feedrate = 300.; // mm/minute double zoom = DEFAULT_ZOOM_FACTOR; +double xscaling = X_SCALING_FACTOR; +double yscaling = Y_SCALING_FACTOR; const double maxFeedrate = 2000.; @@ -74,7 +76,7 @@ const double maxFeedrate = 2000.; void setup() { - Serial.begin(256000); + Serial.begin(BAUDRATE); Serial.print(VERSIONCODE); Serial.print("\n"); @@ -257,178 +259,212 @@ void check_for_version_controll(char command) void process_commands(char command[], int command_length) // deals with standardized input from serial connection { - if(command_length == 1) - { - check_for_version_controll(command[0]); - } - if (command_length>0 && command[0] == 'G') // G code + + double nVal; + boolean hasNVal = getValue('N', command, &nVal); + //if(hasNVal) {Serial.println("linenumber detected");}; + + double getcs; + boolean hasCS = getValue('*', command, &getcs); + //if(hasCS) {Serial.println("checksum detected");}; + + // checksum code from reprap wiki + int cs = 0; + int j = 0; + for(j = 0; command[j] != '*' && command[j] != NULL; j++) + cs = cs ^ command[j]; + cs &= 0xff; // Defensive programming... + + if(cs == (int)getcs || hasCS == false) //continue if checksum matches or none detected { - //Serial.print("process G: \n"); - int codenum = (int)strtod(&command[1], NULL); - - double tempX = xAxisStepper.getCurrentPosition(); - double tempY = rotationStepper.getCurrentPosition(); - - double xVal; - boolean hasXVal = getValue('X', command, &xVal); - if(hasXVal) xVal*=zoom*1.71/2; //this factor is for correction to meet the unicorn coordinates - double yVal; - boolean hasYVal = getValue('Y', command, &yVal); - if(hasYVal) yVal*=zoom; - double iVal; - boolean hasIVal = getValue('I', command, &iVal); - if(hasIVal) iVal*=zoom; - double jVal; - boolean hasJVal = getValue('J', command, &jVal); - if(hasJVal) jVal*=zoom; - double rVal; - boolean hasRVal = getValue('R', command, &rVal); - if(hasRVal) rVal*=zoom; - double pVal; - boolean hasPVal = getValue('P', command, &pVal); - - getValue('F', command, &feedrate); - - xVal+=currentOffsetX; - yVal+=currentOffsetY; + //Serial.println("checksum match"); + j=0; + while (j < MAX_CMD_SIZE ) + { + if ((command[j] == 'G') || command[j] == 'M') {break;} + j++; + } - if(absoluteMode) + if(command_length == 1) { - if(hasXVal) - tempX=xVal; - if(hasYVal) - tempY=yVal; + check_for_version_controll(command[0]); } - else + if (command_length>0 && command[j] == 'G') // G code { - if(hasXVal) - tempX+=xVal; - if(hasYVal) - tempY+=yVal; - } - - switch(codenum) + //Serial.print("process G: \n"); + int codenum = (int)strtod(&command[j+1], NULL); + + double tempX = xAxisStepper.getCurrentPosition(); + double tempY = rotationStepper.getCurrentPosition(); + + double xVal; + boolean hasXVal = getValue('X', command, &xVal); + if(hasXVal) xVal*=zoom*xscaling; + double yVal; + boolean hasYVal = getValue('Y', command, &yVal); + if(hasYVal) yVal*=zoom*yscaling; + double iVal; + boolean hasIVal = getValue('I', command, &iVal); + if(hasIVal) iVal*=zoom; + double jVal; + boolean hasJVal = getValue('J', command, &jVal); + if(hasJVal) jVal*=zoom; + double rVal; + boolean hasRVal = getValue('R', command, &rVal); + if(hasRVal) rVal*=zoom; + double pVal; + boolean hasPVal = getValue('P', command, &pVal); + + getValue('F', command, &feedrate); + + xVal+=currentOffsetX; + yVal+=currentOffsetY; + + if(absoluteMode) + { + if(hasXVal) + tempX=xVal; + if(hasYVal) + tempY=yVal; + } + else + { + if(hasXVal) + tempX+=xVal; + if(hasYVal) + tempY+=yVal; + } + + switch(codenum) + { + case 0: // G0, Rapid positioning + xAxisStepper.setTargetPosition(tempX); + rotationStepper.setTargetPosition(tempY); + commitSteppers(maxFeedrate); + break; + case 1: // G1, linear interpolation at specified speed + xAxisStepper.setTargetPosition(tempX); + rotationStepper.setTargetPosition(tempY); + commitSteppers(feedrate); + break; + case 2: // G2, Clockwise arc + case 3: // G3, Counterclockwise arc + if(hasIVal && hasJVal) + { + double centerX=xAxisStepper.getCurrentPosition()+iVal; + double centerY=rotationStepper.getCurrentPosition()+jVal; + drawArc(centerX, centerY, tempX, tempY, (codenum==2)); + } + else if(hasRVal) + { + //drawRadius(tempX, tempY, rVal, (codenum==2)); + } + break; + case 4: // G4, Delay P ms + if(hasPVal) + { + unsigned long endDelay = millis()+ (unsigned long)pVal; + while(millis()0 && command[j] == 'M') // M code { - case 0: // G0, Rapid positioning - xAxisStepper.setTargetPosition(tempX); - rotationStepper.setTargetPosition(tempY); - commitSteppers(maxFeedrate); - break; - case 1: // G1, linear interpolation at specified speed - xAxisStepper.setTargetPosition(tempX); - rotationStepper.setTargetPosition(tempY); - commitSteppers(feedrate); - break; - case 2: // G2, Clockwise arc - case 3: // G3, Counterclockwise arc - if(hasIVal && hasJVal) - { - double centerX=xAxisStepper.getCurrentPosition()+iVal; - double centerY=rotationStepper.getCurrentPosition()+jVal; - drawArc(centerX, centerY, tempX, tempY, (codenum==2)); - } - else if(hasRVal) - { - //drawRadius(tempX, tempY, rVal, (codenum==2)); - } - break; - case 4: // G4, Delay P ms - if(hasPVal) - { - unsigned long endDelay = millis()+ (unsigned long)pVal; - while(millis()0 && command[0] == 'M') // M code - { - //Serial.print("proces M:\n"); - double value; - int codenum = (int)strtod(&command[1], NULL); - switch(codenum) - { - case 18: // Disable Drives - xAxisStepper.resetStepper(); - rotationStepper.resetStepper(); - break; - - case 300: // Servo Position - if(getValue('S', command, &value)) - { - servoEnabled=true; - if(value<0.) - value=0.; - else if(value>180.) + //Serial.print("proces M:\n"); + double value; + int codenum = (int)strtod(&command[j+1], NULL); + switch(codenum) + { + case 18: // Disable Drives + xAxisStepper.resetStepper(); + rotationStepper.resetStepper(); + break; + + case 300: // Servo Position + if(getValue('S', command, &value)) { - value=DEFAULT_PEN_UP_POSITION; - servo.write((int)value); - for(int i=0;i<100;i++) + servoEnabled=true; + if(value<0.) + value=0.; + else if(value>180.) { - SoftwareServo::refresh(); - delay(2); - } - servoEnabled=false; + value=DEFAULT_PEN_UP_POSITION; + servo.write((int)value); + for(int i=0;i<100;i++) + { + SoftwareServo::refresh(); + delay(2); + } + servoEnabled=false; + } + servo.write((int)value); } - servo.write((int)value); - } - break; - - case 400: // Propretary: Reset X-Axis-Stepper settings to new object diameter - if(getValue('S', command, &value)) - { - xAxisStepper.resetSteppersForObjectDiameter(value); - xAxisStepper.setTargetPosition(0.); - commitSteppers(maxFeedrate); - delay(2000); - xAxisStepper.enableStepper(false); - } - break; - - case 401: // Propretary: Reset Y-Axis-Stepper settings to new object diameter - if(getValue('S', command, &value)) - { - rotationStepper.resetSteppersForObjectDiameter(value); - rotationStepper.setTargetPosition(0.); - commitSteppers(maxFeedrate); - delay(2000); - rotationStepper.enableStepper(false); - } - break; - - case 402: // Propretary: Reset Y-Axis-Stepper settings to new object diameter - if(getValue('S', command, &value)) - { - zoom = value/100; - } - break; - default: - break; - - } - } + break; + + case 400: // Propretary: Reset X-Axis-Stepper settings to new object diameter + if(getValue('S', command, &value)) + { + xAxisStepper.resetSteppersForObjectDiameter(value); + xAxisStepper.setTargetPosition(0.); + commitSteppers(maxFeedrate); + delay(2000); + xAxisStepper.enableStepper(false); + } + break; + + case 401: // Propretary: Reset Y-Axis-Stepper settings to new object diameter + if(getValue('S', command, &value)) + { + rotationStepper.resetSteppersForObjectDiameter(value); + rotationStepper.setTargetPosition(0.); + commitSteppers(maxFeedrate); + delay(2000); + rotationStepper.enableStepper(false); + } + break; + + case 402: // Propretary: Reset Y-Axis-Stepper settings to new object diameter + if(getValue('S', command, &value)) + { + zoom = value/100; + } + break; + default: + break; + + } + } -//done processing commands -//if (Serial.available() <= 0) { -Serial.print("ok:"); -//Serial.println(command); -Serial.print("\n"); + //done processing commands + //if (Serial.available() <= 0) { + Serial.print("ok"); + //Serial.println(command); + Serial.print("\n"); //} + + } + else + { + Serial.print("rs "); + Serial.print((int)nVal); + Serial.print("\n"); + } } /* This code was ported from the Makerbot/ReplicatorG java sources */ diff --git a/SphereBot Arduino/SphereBot/StepperModel.cpp b/SphereBot Arduino/SphereBot/StepperModel.cpp index bb7fdda..f75ed70 100644 --- a/SphereBot Arduino/SphereBot/StepperModel.cpp +++ b/SphereBot Arduino/SphereBot/StepperModel.cpp @@ -22,7 +22,7 @@ /* * inEnablePin < 0 => No Endstop */ -StepperModel::StepperModel(int inDirPin, int inStepPin, int inEnablePin, int inEndStopPin,int inMs1Pin, int inMs2Pin, bool vms1,bool vms2, +StepperModel::StepperModel(int inDirPin, int inStepPin, int inEnablePin, int inEndStopPin, int inMs1Pin, int inMs2Pin, int inMs3Pin, bool vms1, bool vms2, bool vms3, long minSC, long maxSC, double in_kStepsPerRevolution, int in_kMicroStepping) { @@ -35,6 +35,7 @@ StepperModel::StepperModel(int inDirPin, int inStepPin, int inEnablePin, int inE endStopPin = inEndStopPin; ms1Pin = inMs1Pin; ms2Pin = inMs2Pin; + ms3Pin = inMs3Pin; minStepCount=minSC; maxStepCount=maxSC; @@ -44,12 +45,20 @@ StepperModel::StepperModel(int inDirPin, int inStepPin, int inEnablePin, int inE pinMode(enablePin, OUTPUT); if(endStopPin>=0) pinMode(endStopPin, INPUT); - if((ms1Pin >=0) && (ms2Pin >=0)) + if((ms1Pin >=0)) { - pinMode(ms1Pin, OUTPUT); - pinMode(ms2Pin, OUTPUT); + pinMode(ms1Pin, OUTPUT); digitalWrite(ms1Pin, vms1); - digitalWrite(ms2Pin, vms2); + } + if((ms2Pin >=0)) + { + pinMode(ms2Pin, OUTPUT); + digitalWrite(ms2Pin, vms1); + } + if((ms3Pin >=0)) + { + pinMode(ms3Pin, OUTPUT); + digitalWrite(ms3Pin, vms1); } digitalWrite(dirPin, LOW); diff --git a/SphereBot Arduino/SphereBot/StepperModel.h b/SphereBot Arduino/SphereBot/StepperModel.h index b317dec..99b163e 100644 --- a/SphereBot Arduino/SphereBot/StepperModel.h +++ b/SphereBot Arduino/SphereBot/StepperModel.h @@ -30,6 +30,8 @@ class StepperModel int enablePin; int ms1Pin; int ms2Pin; + int ms3Pin; + int endStopPin; long minStepCount; @@ -51,7 +53,7 @@ class StepperModel volatile long counter; double targetPosition; - StepperModel(int inDirPin, int inStepPin, int inEnablePin, int inEndStopPin,int inMs1Pin, int inMs2Pin,bool vms1,bool vms2, + StepperModel(int inDirPin, int inStepPin, int inEnablePin, int inEndStopPin,int inMs1Pin, int inMs2Pin, int inMs3Pin, bool vms1, bool vms2, bool vms3, long minSC, long maxSC, double in_kStepsPerRevolution, int in_kMicroStepping); diff --git a/SphereBot Arduino/SphereBot/config.h b/SphereBot Arduino/SphereBot/config.h index 45e708a..2de98e0 100644 --- a/SphereBot Arduino/SphereBot/config.h +++ b/SphereBot Arduino/SphereBot/config.h @@ -1,35 +1,40 @@ +#define BAUDRATE 256000 + /* * PINS */ - - //ms1 and ms2 are optional. You can simply make these settings by hardwiring the pins to high or low - - /* ms1 | ms2 - ---------------- - L | L -> Full Step - H | L -> Half Step - L | H -> Quarter Step - H | H -> Sixteenth Step - */ - -#define XAXIS_VMS1 HIGH -#define XAXIS_VMS2 HIGH -#define YAXIS_VMS1 HIGH -#define YAXIS_VMS2 HIGH - + +// Y-Axis #define YAXIS_DIR_PIN 14 #define YAXIS_STEP_PIN 15 #define YAXIS_ENABLE_PIN 21 -#define YAXIS_MS1_PIN -1 //ADC6 and ADC7 can not be used as a digital pin ( I made the pull up connection manually) +#define YAXIS_MS1_PIN -1 #define YAXIS_MS2_PIN -1 -#define YAXIS_ENDSTOP_PIN -1 //13 +#define YAXIS_MS3_PIN -1 +#define YAXIS_ENDSTOP_PIN -1 // -1 -> No Endstop +#define YAXIS_VMS1 HIGH +#define YAXIS_VMS2 HIGH +#define YAXIS_VMS3 HIGH +#define YAXIS_MIN_STEPCOUNT 0 // Travel limits +#define YAXIS_MAX_STEPCOUNT 0 +#define YAXIS_STEPS_PER_FULL_ROTATION 200.0 +#define YAXIS_MICROSTEPPING 8 +//X-Axis #define XAXIS_DIR_PIN 10 #define XAXIS_STEP_PIN 8 #define XAXIS_ENABLE_PIN 2 #define XAXIS_MS1_PIN -1 #define XAXIS_MS2_PIN -1 -#define XAXIS_ENDSTOP_PIN -1 // <0 0> No Endstop! +#define XAXIS_MS3_PIN -1 +#define XAXIS_ENDSTOP_PIN -1 // -1 -> No Endstop +#define XAXIS_VMS1 HIGH +#define XAXIS_VMS2 HIGH +#define XAXIS_VMS3 HIGH +#define XAXIS_MIN_STEPCOUNT 0 // Travel limits +#define XAXIS_MAX_STEPCOUNT 0 +#define XAXIS_STEPS_PER_FULL_ROTATION 200.0 +#define XAXIS_MICROSTEPPING 8 #define SERVO_PIN 13 @@ -38,8 +43,23 @@ */ #define DEFAULT_PEN_UP_POSITION 35 -#define XAXIS_MIN_STEPCOUNT -5.6*230000 //max and min Values are not used by the firmware right now -#define XAXIS_MAX_STEPCOUNT 5*230000 // + #define DEFAULT_ZOOM_FACTOR 0.1808 // With a Zoom-Faktor of .65, I can print gcode for Makerbot Unicorn without changes. // The zoom factor can be also manipulated by the propretiary code M402 +#define X_SCALING_FACTOR 1.71/2 //this factor is for correction to meet the unicorn coordinates +#define Y_SCALING_FACTOR 1 +/* + * Microstepping Information + */ + +//MS1, MS2 and MS3 are optional. You can simply make these settings by hardwiring the pins to high or low + + /* MS1 | MS2 | MS3 Microstepping Resolution + ----------------------- + L | L | L -> Full Step + H | L | L -> Half Step + L | H | L -> Quarter Step + H | H | L -> Eighth Step + H | H | H -> Sixteenth Step + */