diff --git a/COPYING b/COPYING index 3f9959fc5..3462706c1 100644 --- a/COPYING +++ b/COPYING @@ -10,7 +10,7 @@ the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. - 0. Additional Definitions. + 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU @@ -111,7 +111,7 @@ the following: a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked - Version. + Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the diff --git a/Makefile b/Makefile index 45e9b8951..a43b91be3 100644 --- a/Makefile +++ b/Makefile @@ -55,23 +55,23 @@ OBJECTS = main.o motion_control.o gcode.o spindle_control.o \ # $(ARDUINO_LIB)/PS2X_lib/PS2X_lib.o \ # ps2_controller.o \ # PS2Y_lib.o \ - + # FUSES = -U hfuse:w:0xd9:m -U lfuse:w:0x24:m FUSES = -U hfuse:w:0xd2:m -U lfuse:w:0xff:m # Tune the lines below only if you know what you are doing: -AVRDUDE = avrdude $(PROGRAMMER) -p $(DEVICE) -B 10 -F +AVRDUDE = avrdude $(PROGRAMMER) -p $(DEVICE) -B 10 -F COMPILE = avr-gcc -Wall -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE) -I. -I$(ARDUINO) -I$(ARDUINO_LIB) # symbolic targets: all: grbl.hex .c.o: - $(COMPILE) -c $< -o $@ + $(COMPILE) -c $< -o $@ .cpp.o: - $(COMPILE) -c $< -o $@ + $(COMPILE) -c $< -o $@ .S.o: @@ -116,4 +116,4 @@ disasm: main.elf avr-objdump -d main.elf cpp: - $(COMPILE) -E main.c + $(COMPILE) -E main.c diff --git a/config.c b/config.c index be50ee599..8cc490d76 100644 --- a/config.c +++ b/config.c @@ -1,5 +1,5 @@ /* - config.c - eeprom and compile time configuration handling + config.c - eeprom and compile time configuration handling Part of Grbl Copyright (c) 2009 Simen Svale Skogsrud @@ -48,18 +48,18 @@ void dump_settings() { printPgmString(PSTR(" (microseconds step pulse)\r\n$4 = ")); printFloat(settings.default_feed_rate); printPgmString(PSTR(" (mm/sec default feed rate)\r\n$5 = ")); printFloat(settings.default_seek_rate); printPgmString(PSTR(" (mm/sec G0 seek rate)\r\n$6 = ")); printFloat(settings.mm_per_arc_segment); - printPgmString(PSTR(" (mm/arc segment)\r\n$7 = ")); printInteger(settings.invert_mask); - printPgmString(PSTR(" (step port invert mask. binary = ")); printIntegerInBase(settings.invert_mask, 2); - printPgmString(PSTR(")\r\n$8 = "));printInteger(settings.backlash_x_count); - printPgmString(PSTR("(counts to compensate for backlash in x)\r\n$9 = "));printInteger(settings.backlash_y_count); - printPgmString(PSTR("(counts to compensate for backlash in x)\r\n$10 = "));printInteger(settings.backlash_z_count); + printPgmString(PSTR(" (mm/arc segment)\r\n$7 = ")); printInteger(settings.invert_mask); + printPgmString(PSTR(" (step port invert mask. binary = ")); printIntegerInBase(settings.invert_mask, 2); + printPgmString(PSTR(")\r\n$8 = "));printInteger(settings.backlash_x_count); + printPgmString(PSTR("(counts to compensate for backlash in x)\r\n$9 = "));printInteger(settings.backlash_y_count); + printPgmString(PSTR("(counts to compensate for backlash in x)\r\n$10 = "));printInteger(settings.backlash_z_count); printPgmString(PSTR("(counts to compensate for backlash in z)\r\n")); printPgmString(PSTR("\r\n'$x=value' to set parameter or just '$' to dump current settings\r\n")); } int read_settings() { // Check version-byte of eeprom - uint8_t version = eeprom_get_char(0); + uint8_t version = eeprom_get_char(0); if (version != SETTINGS_VERSION) { return(FALSE); } // Read settings-record and check checksum if (!(memcpy_from_eeprom_with_checksum((char*)&settings, 1, sizeof(struct Settings)))) { @@ -86,7 +86,7 @@ void store_setting(int parameter, double value) { case 8: settings.backlash_x_count= trunc(value); break; case 9: settings.backlash_y_count= trunc(value); break; case 10: settings.backlash_z_count= trunc(value); break; - default: + default: printPgmString(PSTR("Unknown parameter\r\n")); return; } diff --git a/config.h b/config.h index e20cf2446..139bdf431 100644 --- a/config.h +++ b/config.h @@ -1,5 +1,5 @@ /* - config.h - eeprom and compile time configuration handling + config.h - eeprom and compile time configuration handling Part of Grbl Copyright (c) 2009 Simen Svale Skogsrud @@ -31,10 +31,10 @@ #define STEPPERS_ENABLE_DDR DDRB // pin 13, with LED #define STEPPERS_ENABLE_PORT PORTB -#define STEPPERS_ENABLE_BIT 5 +#define STEPPERS_ENABLE_BIT 5 #define STEPPING_DDR DDRD -#define STEPPING_PORT PORTD +#define STEPPING_PORT PORTD #define X_STEP_BIT 7 #define Y_STEP_BIT 5 #define Z_STEP_BIT 3 diff --git a/gcode.c b/gcode.c index 19210a688..125653605 100644 --- a/gcode.c +++ b/gcode.c @@ -58,7 +58,7 @@ struct ParserState gc; extern int32_t position[3]; -// This routine is required to get the correct state into the +// This routine is required to get the correct state into the // Parser if the position is manipulated using the buttons. void set_gcPosition() { @@ -72,13 +72,13 @@ void set_gcPosition() #define FAIL(status) gc.status_code = status; int read_double(char *line, // <- string: line of RS274/NGC code being processed - int *char_counter, // <- pointer to a counter for position on the line - double *double_ptr); // <- pointer to double to be read + int *char_counter, // <- pointer to a counter for position on the line + double *double_ptr); // <- pointer to double to be read int next_statement(char *letter, double *double_ptr, char *line, int *char_counter); -void select_plane(uint8_t axis_0, uint8_t axis_1, uint8_t axis_2) +void select_plane(uint8_t axis_0, uint8_t axis_1, uint8_t axis_2) { gc.plane_axis_0 = axis_0; gc.plane_axis_1 = axis_1; @@ -97,7 +97,7 @@ inline float to_millimeters(double value) { return(gc.inches_mode ? (value * MM_PER_INCH) : value); } -// Find the angle in radians of deviance from the positive y axis. negative angles to the left of y-axis, +// Find the angle in radians of deviance from the positive y axis. negative angles to the left of y-axis, // positive to the right. double theta(double x, double y) { @@ -105,7 +105,7 @@ double theta(double x, double y) if (y>0) { return(theta); } else { - if (theta>0) + if (theta>0) { return(M_PI-theta); } else { @@ -117,34 +117,34 @@ double theta(double x, double y) // Executes one line of 0-terminated G-Code. The line is assumed to contain only uppercase // characters and signed floats (no whitespace). uint8_t gc_execute_line(char *line) { - int char_counter = 0; + int char_counter = 0; char letter; double value; int32_t line_number=0; double unit_converted_value; double inverse_feed_rate = -1; // negative inverse_feed_rate means no inverse_feed_rate specified int radius_mode = FALSE; - + uint8_t absolute_override = FALSE; // 1 = absolute motion for this block only {G53} - uint8_t next_action = NEXT_ACTION_DEFAULT; // The action that will be taken by the parsed line - - double target[3], offset[3]; - + uint8_t next_action = NEXT_ACTION_DEFAULT; // The action that will be taken by the parsed line + + double target[3], offset[3]; + double p = 0, r = 0; // Stores the value of R and P statements until their meaning is determined int int_value; // A truncated integer version of parameter value of the current statement - + clear_vector(target); clear_vector(offset); gc.status_code = GCSTATUS_OK; - + // Disregard comments and block delete if (line[0] == '(') { return(gc.status_code); } if (line[0] == '/') { char_counter++; } // ignore block delete - - + + // If the line starts with an '$' it is a configuration-command - if (line[0] == '$') { + if (line[0] == '$') { // Parameter lines are on the form '$4=374.3' or '$' to dump current settings char_counter = 1; if(line[char_counter] == 0) { dump_settings(); return(GCSTATUS_OK); } @@ -154,18 +154,18 @@ uint8_t gc_execute_line(char *line) { if(line[char_counter] != 0) { return(GCSTATUS_UNSUPPORTED_STATEMENT); } store_setting(p, value); } - + // Not a comment. Not a configuration-command. Then we'll handle this as g-code. - // If the machine step buffer is full, return with error. This is to prevent + // If the machine step buffer is full, return with error. This is to prevent // blocking. The sequencer that feeds grbl should check before sending whether // it can send right now. - + if (st_buffer_full()){ FAIL(GCSTATUS_BUFFER_FULL); return(gc.status_code); - } + } // Pass 1: Command statements while(next_statement(&letter, &value, line, &char_counter)) { @@ -194,14 +194,14 @@ uint8_t gc_execute_line(char *line) { default: FAIL(GCSTATUS_UNSUPPORTED_STATEMENT); } break; - + case 'N': line_number = int_value % 100000; //Spec puts line number up to 99999 break; - + case 'M': switch(int_value) { - case 0: case 1: gc.program_flow = PROGRAM_FLOW_PAUSED; + case 0: case 1: gc.program_flow = PROGRAM_FLOW_PAUSED; /* gc.motion_mode = NEXT_ACTION_HALT; */ @@ -212,13 +212,13 @@ uint8_t gc_execute_line(char *line) { case 4: gc.spindle_direction = -1; break; case 5: gc.spindle_direction = 0; break; default: FAIL(GCSTATUS_UNSUPPORTED_STATEMENT); - } + } break; case 'T': gc.tool = int_value; break; } if(gc.status_code) { break; } } - + // If there were any errors parsing this line, we will return right away with the bad news if (gc.status_code) { return(gc.status_code); } @@ -231,7 +231,7 @@ uint8_t gc_execute_line(char *line) { int_value = trunc(value); unit_converted_value = to_millimeters(value); switch(letter) { - case 'F': + case 'F': if (gc.inverse_feed_rate_mode) { inverse_feed_rate = unit_converted_value; // seconds per motion for this motion only } else { @@ -251,50 +251,50 @@ uint8_t gc_execute_line(char *line) { break; } } - + // If there were any errors parsing this line, we will return right away with the bad news if (gc.status_code) { return(gc.status_code); } - + // Update spindle state if (gc.spindle_direction) { spindle_run(gc.spindle_direction, gc.spindle_speed); } else { spindle_stop(); } - + // Perform any physical actions switch (next_action) { case NEXT_ACTION_GO_HOME: mc_go_home(line_number); break; case NEXT_ACTION_DWELL: mc_dwell(trunc(p*1000), line_number); break; case NEXT_ACTION_HALT: mc_halt(line_number); break; - case NEXT_ACTION_REPOSITION: mc_reposition(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], line_number); break; - case NEXT_ACTION_DEFAULT: + case NEXT_ACTION_REPOSITION: mc_reposition(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], line_number); break; + case NEXT_ACTION_DEFAULT: switch (gc.motion_mode) { case MOTION_MODE_CANCEL: break; case MOTION_MODE_SEEK: mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], gc.seek_rate, FALSE, line_number); break; case MOTION_MODE_LINEAR: - mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], + mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], (gc.inverse_feed_rate_mode) ? inverse_feed_rate : gc.feed_rate, gc.inverse_feed_rate_mode, line_number); break; case MOTION_MODE_CW_ARC: case MOTION_MODE_CCW_ARC: if (radius_mode) { - /* + /* We need to calculate the center of the circle that has the designated radius and passes through both the current position and the target position. This method calculates the following - set of equations where [x,y] is the vector from current to target position, d == magnitude of + set of equations where [x,y] is the vector from current to target position, d == magnitude of that vector, h == hypotenuse of the triangle formed by the radius of the circle, the distance to - the center of the travel vector. A vector perpendicular to the travel vector [-y,x] is scaled to the - length of h [-y/d*h, x/d*h] and added to the center of the travel vector [x/2,y/2] to form the new point + the center of the travel vector. A vector perpendicular to the travel vector [-y,x] is scaled to the + length of h [-y/d*h, x/d*h] and added to the center of the travel vector [x/2,y/2] to form the new point [i,j] at [x/2-y/d*h, y/2+x/d*h] which will be the center of our arc. - + d^2 == x^2 + y^2 h^2 == r^2 - (d/2)^2 i == x/2 - y/d*h j == y/2 + x/d*h - + O <- [i,j] - | r - | @@ -303,38 +303,38 @@ uint8_t gc_execute_line(char *line) { - | [0,0] -> C -----------------+--------------- T <- [x,y] | <------ d/2 ---->| - + C - Current position T - Target position O - center of circle that pass through both C and T d - distance from C to T r - designated radius h - distance from center of CT to O - + Expanding the equations: d -> sqrt(x^2 + y^2) h -> sqrt(4 * r^2 - x^2 - y^2)/2 - i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2 + i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2 j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2 - + Which can be written: - + i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2 j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2 - + Which we for size and speed reasons optimize to: h_x2_div_d = sqrt(4 * r^2 - x^2 - y^2)/sqrt(x^2 + y^2) i = (x - (y * h_x2_div_d))/2 j = (y + (x * h_x2_div_d))/2 - + */ - + // Calculate the change in position along each selected axis double x = target[gc.plane_axis_0]-gc.position[gc.plane_axis_0]; double y = target[gc.plane_axis_1]-gc.position[gc.plane_axis_1]; - + clear_vector(&offset); double h_x2_div_d = -sqrt(4 * r*r - x*x - y*y)/hypot(x,y); // == -(h * 2 / d) // If r is smaller than d, the arc is now traversing the complex plane beyond the reach of any @@ -342,56 +342,56 @@ uint8_t gc_execute_line(char *line) { if(isnan(h_x2_div_d)) { FAIL(GCSTATUS_FLOATING_POINT_ERROR); return(gc.status_code); } // Invert the sign of h_x2_div_d if the circle is counter clockwise (see sketch below) if (gc.motion_mode == MOTION_MODE_CCW_ARC) { h_x2_div_d = -h_x2_div_d; } - + /* The counter clockwise circle lies to the left of the target direction. When offset is positive, the left hand circle will be generated - when it is negative the right hand circle is generated. - - + + T <-- Target position - - ^ + + ^ Clockwise circles with this center | Clockwise circles with this center will have will have > 180 deg of angular travel | < 180 deg of angular travel, which is a good thing! - \ | / + \ | / center of arc when h_x2_div_d is positive -> x <----- | -----> x <- center of arc when h_x2_div_d is negative | | - + C <-- Current position */ - - // Negative R is g-code-alese for "I want a circle with more than 180 degrees of travel" (go figure!), - // even though it is advised against ever generating such circles in a single line of g-code. By + + // Negative R is g-code-alese for "I want a circle with more than 180 degrees of travel" (go figure!), + // even though it is advised against ever generating such circles in a single line of g-code. By // inverting the sign of h_x2_div_d the center of the circles is placed on the opposite side of the line of // travel and thus we get the unadvisably long arcs as prescribed. - if (r < 0) { h_x2_div_d = -h_x2_div_d; } + if (r < 0) { h_x2_div_d = -h_x2_div_d; } // Complete the operation by calculating the actual center of the arc offset[gc.plane_axis_0] = (x-(y*h_x2_div_d))/2; offset[gc.plane_axis_1] = (y+(x*h_x2_div_d))/2; - } - + } + /* - This segment sets up an clockwise or counterclockwise arc from the current position to the target position around - the center designated by the offset vector. All theta-values measured in radians of deviance from the positive - y-axis. + This segment sets up an clockwise or counterclockwise arc from the current position to the target position around + the center designated by the offset vector. All theta-values measured in radians of deviance from the positive + y-axis. | <- theta == 0 - * * * - * * - * * - * O ----T <- theta_end (e.g. 90 degrees: theta_end == PI/2) - * / + * * * + * * + * * + * O ----T <- theta_end (e.g. 90 degrees: theta_end == PI/2) + * / C <- theta_start (e.g. -145 degrees: theta_start == -PI*(3/4)) */ - + // Find the radius double radius = hypot(offset[gc.plane_axis_0], offset[gc.plane_axis_1]); if (radius<0.0001) break; // calculate the theta (angle) of the current point double theta_start = theta(-offset[gc.plane_axis_0], -offset[gc.plane_axis_1]); // calculate the theta (angle) of the target point - double theta_end = theta(target[gc.plane_axis_0] - offset[gc.plane_axis_0] - gc.position[gc.plane_axis_0], + double theta_end = theta(target[gc.plane_axis_0] - offset[gc.plane_axis_0] - gc.position[gc.plane_axis_0], target[gc.plane_axis_1] - offset[gc.plane_axis_1] - gc.position[gc.plane_axis_1]); // double theta_end = theta(5,0); // ensure that the difference is positive so that we have clockwise travel @@ -406,34 +406,34 @@ uint8_t gc_execute_line(char *line) { // Calculate the motion along the depth axis of the helix double depth = target[gc.plane_axis_2]-gc.position[gc.plane_axis_2]; // Trace the arc - -/* - printPgmString(PSTR("values in gc_execute line:\r\n")); + +/* + printPgmString(PSTR("values in gc_execute line:\r\n")); printPgmString(PSTR("theta start: ")); printFloat(theta_start); printPgmString(PSTR("\r\ntheta end: ")); printFloat(theta_end); - printPgmString(PSTR("\r\noffset: ")); + printPgmString(PSTR("\r\noffset: ")); printFloat(offset[gc.plane_axis_0]); - printPgmString(PSTR(", ")); + printPgmString(PSTR(", ")); printFloat(offset[gc.plane_axis_1]); - printPgmString(PSTR("\r\n\r\n")); -*/ - - mc_arc(theta_start, angular_travel, radius, depth, - gc.plane_axis_0, gc.plane_axis_1, gc.plane_axis_2, + printPgmString(PSTR("\r\n\r\n")); +*/ + + mc_arc(theta_start, angular_travel, radius, depth, + gc.plane_axis_0, gc.plane_axis_1, gc.plane_axis_2, target[X_AXIS], target[Y_AXIS], target[Z_AXIS], - (gc.inverse_feed_rate_mode) ? inverse_feed_rate : gc.feed_rate, + (gc.inverse_feed_rate_mode) ? inverse_feed_rate : gc.feed_rate, gc.inverse_feed_rate_mode, line_number); // Finish off with a line to make sure we arrive exactly where we think we are -/* mc_line( - (gc.inverse_feed_rate_mode) ? inverse_feed_rate : gc.feed_rate, +/* mc_line( + (gc.inverse_feed_rate_mode) ? inverse_feed_rate : gc.feed_rate, gc.inverse_feed_rate_mode, line_number); */ break; - } + } } - + // As far as the parser is concerned, the position is now == target. In reality the // motion control system might still be processing the action and the real tool position // in any intermediate location. @@ -448,7 +448,7 @@ int next_statement(char *letter, double *double_ptr, char *line, int *char_count if (line[*char_counter] == 0) { return(0); // No more statements } - + *letter = line[*char_counter]; if((*letter < 'A') || (*letter > 'Z')) { FAIL(GCSTATUS_EXPECTED_COMMAND_LETTER); @@ -462,16 +462,16 @@ int next_statement(char *letter, double *double_ptr, char *line, int *char_count } int read_double(char *line, //!< string: line of RS274/NGC code being processed - int *char_counter, //!< pointer to a counter for position on the line - double *double_ptr) //!< pointer to double to be read + int *char_counter, //!< pointer to a counter for position on the line + double *double_ptr) //!< pointer to double to be read { char *start = line + *char_counter; char *end; - + *double_ptr = strtod(start, &end); - if(end == start) { - FAIL(GCSTATUS_BAD_NUMBER_FORMAT); - return(0); + if(end == start) { + FAIL(GCSTATUS_BAD_NUMBER_FORMAT); + return(0); }; *char_counter = end - line; diff --git a/gcode/zoetrope.gcode b/gcode/zoetrope.gcode index 2af194bd6..016577aa3 100644 --- a/gcode/zoetrope.gcode +++ b/gcode/zoetrope.gcode @@ -1,112 +1,112 @@ G90 F1000 -G1 X-27.7814 Y11.3222 -G1 X-13.7952 Y1.99803 -G1 X-27.7814 Y11.3222 -G1 X-27.7814 Y1.99803 -G1 X-27.7814 Y11.3222 -G1 X-27.7814 Y1.99803 -G1 X-13.7952 Y1.99803 -G1 X-13.7952 Y11.3222 -G1 X-13.7952 Y1.99803 -G1 X-10.8055 Y21.1219 -G1 X-11.3961 Y19.7548 -G1 X-11.558 Y17.878 -G1 X-10.7814 Y15.9202 -G1 X-9.92396 Y14.9009 -G1 X-8.12809 Y13.8007 -G1 X-6.25129 Y13.6388 -G1 X-4.80324 Y13.9866 -G1 X-3.27425 Y15.2728 -G1 X-2.68367 Y16.64 -G1 X-2.52182 Y18.5168 -G1 X-3.29837 Y20.4745 -G1 X-4.15584 Y21.4938 -G1 X-5.95171 Y22.5941 -G1 X-7.8285 Y22.7559 -G1 X-9.27656 Y22.4081 -G1 X-10.8055 Y21.1219 -G1 X4.27576 Y18.746 -G1 X12.2103 Y17.788 -G1 X12.3699 Y19.1104 -G1 X11.8684 Y20.5127 -G1 X11.287 Y21.2537 -G1 X10.0444 Y22.0746 -G1 X8.06077 Y22.3141 -G1 X6.65853 Y21.8125 -G1 X5.17645 Y20.6498 -G1 X4.27576 Y18.746 -G1 X4.1161 Y17.4235 -G1 X4.53783 Y15.3601 -G1 X5.70059 Y13.878 -G1 X6.94317 Y13.0572 -G1 X8.9268 Y12.8177 -G1 X10.329 Y13.3192 -G1 X11.8111 Y14.482 -G1 X23.6509 Y14.951 -G1 X14.8687 Y7.80509 -G1 X13.7392 Y6.02745 -G1 X14.0633 Y4.5739 -G1 X14.904 Y3.5407 -G1 X18.7737 Y13.5584 -G1 X21.7161 Y9.94214 -G1 X18.7737 Y13.5584 -G1 X23.2352 Y1.31533 -G1 X14.0474 Y-0.273848 -G1 X23.2352 Y1.31533 -G1 X19.2976 Y0.634252 -G1 X21.3799 Y0.318524 -G1 X22.9194 Y-0.766981 -G1 X23.8027 Y-1.966 -G1 X24.1433 Y-3.9348 -G1 X18.6913 Y-14.6127 -G1 X18.6517 Y-13.1239 -G1 X18.0086 Y-11.3533 -G1 X16.4803 Y-9.90425 -G1 X15.2734 Y-9.34046 -G1 X13.1813 Y-9.0982 -G1 X11.4107 Y-9.74125 -G1 X10.2435 Y-10.6662 -G1 X9.39784 Y-12.4764 -G1 X9.43747 Y-13.9651 -G1 X10.0805 Y-15.7357 -G1 X11.6089 Y-17.1848 -G1 X12.8157 Y-17.7486 -G1 X14.9078 Y-17.9909 -G1 X16.6784 Y-17.3478 -G1 X17.8456 Y-16.4229 -G1 X18.6913 Y-14.6127 -G1 X4.61246 Y-22.8107 -G1 X0.289415 Y-9.50937 -G1 X0.289415 YG1 X-9.50937 -G1 X4.61246 Y-22.8107 -G1 X3.99488 Y-20.9105 -G1 X3.13981 Y-22.589 -G1 X2.07887 Y-23.6341 -G1 X0.178684 Y-24.2517 -G1 X-1.29397 Y-24.03 -G1 X-2.97248 Y-23.175 -G1 X-4.22345 Y-21.4806 -G1 X-4.63517 Y-20.2138 -G1 X-4.61935 Y-18.1078 -G1 X-3.76428 Y-16.4293 -G1 X-2.70335 Y-15.3842 -G1 X-0.803156 Y-14.7666 -G1 X0.669496 Y-14.9883 -G1 X2.34801 Y-15.8433 -G1 X-10.9479 Y-15.8062 -G1 X-17.9553 Y-11.9629 -G1 X-18.5959 Y-13.1308 -G1 X-18.6525 Y-14.619 -G1 X-18.3888 Y-15.5232 -G1 X-17.5412 Y-16.7477 -G1 X-15.7893 Y-17.7085 -G1 X-14.3011 Y-17.7651 -G1 X-12.4927 Y-17.2378 -G1 X-10.9479 Y-15.8062 -G1 X-10.3074 Y-14.6383 -G1 X-9.93052 Y-12.5662 -G1 X-10.4579 Y-10.7577 -G1 X-11.3055 Y-9.53325 -G1 X-13.0573 Y-8.57243 +G1 X-27.7814 Y11.3222 +G1 X-13.7952 Y1.99803 +G1 X-27.7814 Y11.3222 +G1 X-27.7814 Y1.99803 +G1 X-27.7814 Y11.3222 +G1 X-27.7814 Y1.99803 +G1 X-13.7952 Y1.99803 +G1 X-13.7952 Y11.3222 +G1 X-13.7952 Y1.99803 +G1 X-10.8055 Y21.1219 +G1 X-11.3961 Y19.7548 +G1 X-11.558 Y17.878 +G1 X-10.7814 Y15.9202 +G1 X-9.92396 Y14.9009 +G1 X-8.12809 Y13.8007 +G1 X-6.25129 Y13.6388 +G1 X-4.80324 Y13.9866 +G1 X-3.27425 Y15.2728 +G1 X-2.68367 Y16.64 +G1 X-2.52182 Y18.5168 +G1 X-3.29837 Y20.4745 +G1 X-4.15584 Y21.4938 +G1 X-5.95171 Y22.5941 +G1 X-7.8285 Y22.7559 +G1 X-9.27656 Y22.4081 +G1 X-10.8055 Y21.1219 +G1 X4.27576 Y18.746 +G1 X12.2103 Y17.788 +G1 X12.3699 Y19.1104 +G1 X11.8684 Y20.5127 +G1 X11.287 Y21.2537 +G1 X10.0444 Y22.0746 +G1 X8.06077 Y22.3141 +G1 X6.65853 Y21.8125 +G1 X5.17645 Y20.6498 +G1 X4.27576 Y18.746 +G1 X4.1161 Y17.4235 +G1 X4.53783 Y15.3601 +G1 X5.70059 Y13.878 +G1 X6.94317 Y13.0572 +G1 X8.9268 Y12.8177 +G1 X10.329 Y13.3192 +G1 X11.8111 Y14.482 +G1 X23.6509 Y14.951 +G1 X14.8687 Y7.80509 +G1 X13.7392 Y6.02745 +G1 X14.0633 Y4.5739 +G1 X14.904 Y3.5407 +G1 X18.7737 Y13.5584 +G1 X21.7161 Y9.94214 +G1 X18.7737 Y13.5584 +G1 X23.2352 Y1.31533 +G1 X14.0474 Y-0.273848 +G1 X23.2352 Y1.31533 +G1 X19.2976 Y0.634252 +G1 X21.3799 Y0.318524 +G1 X22.9194 Y-0.766981 +G1 X23.8027 Y-1.966 +G1 X24.1433 Y-3.9348 +G1 X18.6913 Y-14.6127 +G1 X18.6517 Y-13.1239 +G1 X18.0086 Y-11.3533 +G1 X16.4803 Y-9.90425 +G1 X15.2734 Y-9.34046 +G1 X13.1813 Y-9.0982 +G1 X11.4107 Y-9.74125 +G1 X10.2435 Y-10.6662 +G1 X9.39784 Y-12.4764 +G1 X9.43747 Y-13.9651 +G1 X10.0805 Y-15.7357 +G1 X11.6089 Y-17.1848 +G1 X12.8157 Y-17.7486 +G1 X14.9078 Y-17.9909 +G1 X16.6784 Y-17.3478 +G1 X17.8456 Y-16.4229 +G1 X18.6913 Y-14.6127 +G1 X4.61246 Y-22.8107 +G1 X0.289415 Y-9.50937 +G1 X0.289415 YG1 X-9.50937 +G1 X4.61246 Y-22.8107 +G1 X3.99488 Y-20.9105 +G1 X3.13981 Y-22.589 +G1 X2.07887 Y-23.6341 +G1 X0.178684 Y-24.2517 +G1 X-1.29397 Y-24.03 +G1 X-2.97248 Y-23.175 +G1 X-4.22345 Y-21.4806 +G1 X-4.63517 Y-20.2138 +G1 X-4.61935 Y-18.1078 +G1 X-3.76428 Y-16.4293 +G1 X-2.70335 Y-15.3842 +G1 X-0.803156 Y-14.7666 +G1 X0.669496 Y-14.9883 +G1 X2.34801 Y-15.8433 +G1 X-10.9479 Y-15.8062 +G1 X-17.9553 Y-11.9629 +G1 X-18.5959 Y-13.1308 +G1 X-18.6525 Y-14.619 +G1 X-18.3888 Y-15.5232 +G1 X-17.5412 Y-16.7477 +G1 X-15.7893 Y-17.7085 +G1 X-14.3011 Y-17.7651 +G1 X-12.4927 Y-17.2378 +G1 X-10.9479 Y-15.8062 +G1 X-10.3074 Y-14.6383 +G1 X-9.93052 Y-12.5662 +G1 X-10.4579 Y-10.7577 +G1 X-11.3055 Y-9.53325 +G1 X-13.0573 Y-8.57243 G1 X-14.5455 Y-8.51583 diff --git a/i2c.cpp b/i2c.cpp index 004b42b59..179540272 100644 --- a/i2c.cpp +++ b/i2c.cpp @@ -1,5 +1,5 @@ /* - i2c.cpp - + i2c.cpp - Part of Grbl: An embedded CNC Controller with rs274/ngc (g-code) support Copyright (c) 2010 Albert Daffe @@ -39,13 +39,13 @@ void i2c_init() void i2c_write_value(byte addr, byte config, int32_t value) { - Wire.beginTransmission(addr); + Wire.beginTransmission(addr); Wire.send(config); - Wire.send((char)((value >> 24) & 0xFF)); - Wire.send((char)((value >> 16) & 0xFF)); - Wire.send((char)((value >> 8) & 0xFF)); - Wire.send((char)(value & 0xFF)); - Wire.endTransmission(); + Wire.send((char)((value >> 24) & 0xFF)); + Wire.send((char)((value >> 16) & 0xFF)); + Wire.send((char)((value >> 8) & 0xFF)); + Wire.send((char)(value & 0xFF)); + Wire.endTransmission(); } void i2c_report_position(void) diff --git a/main.c b/main.c index d13c1da61..989a2cd8e 100644 --- a/main.c +++ b/main.c @@ -51,15 +51,15 @@ int main(void) spindle_init(); // initialize spindle controller gc_init(); // initialize gcode-parser sp_init(); // initialize the serial protocol - + DDRD |= (1<<3)|(1<<4)|(1<<5); for(;;){ i2c_report_position(); _delay_ms(1); // Delay is required, otherwise - + // if mc_running and current_mode = SM_RUN then don't get buttons, else do - + if (!(mc_running==0 & (st_current_mode!=SM_RUN))){ i2c_get_buttons(); // i2c_get doesn't work. 1ms seems to be enough if (buttons[0]|buttons[1]|buttons[2]|buttons[3]){ @@ -68,7 +68,7 @@ int main(void) ENABLE_STEPPER_DRIVER_INTERRUPT(); } } - + if (serialAvailable()) sp_process(); // process the serial protocol if (mc_in_arc()) mc_continue_arc(); // if busy drawing an arc, keep drawing } diff --git a/motion_control.c b/motion_control.c index 765f1bd5e..776e0d9bc 100644 --- a/motion_control.c +++ b/motion_control.c @@ -41,7 +41,7 @@ void mc_init() clear_vector(position); } -void mc_dwell(uint32_t milliseconds, int32_t line_number) +void mc_dwell(uint32_t milliseconds, int32_t line_number) { /* st_synchronize(); _delay_ms(milliseconds); @@ -73,45 +73,45 @@ void mc_line(double x, double y, double z, float feed_rate, int invert_feed_rate uint8_t axis; // loop variable int32_t target[3]; // The target position in absolute steps int32_t steps[3]; // The target line in relative steps - + target[X_AXIS] = lround(x*settings.steps_per_mm[0]); target[Y_AXIS] = lround(y*settings.steps_per_mm[1]); - target[Z_AXIS] = lround(z*settings.steps_per_mm[2]); + target[Z_AXIS] = lround(z*settings.steps_per_mm[2]); for(axis = X_AXIS; axis <= Z_AXIS; axis++) { steps[axis] = target[axis]-position[axis]; } - + if (invert_feed_rate) { - st_buffer_block(steps[X_AXIS], steps[Y_AXIS], steps[Z_AXIS], - position[X_AXIS], position[Y_AXIS], position[Z_AXIS], + st_buffer_block(steps[X_AXIS], steps[Y_AXIS], steps[Z_AXIS], + position[X_AXIS], position[Y_AXIS], position[Z_AXIS], lround(ONE_MINUTE_OF_MICROSECONDS/feed_rate), line_number); } else { // Ask old Phytagoras to estimate how many mm our next move is going to take us double millimeters_of_travel = sqrt( - square(steps[X_AXIS]/settings.steps_per_mm[0]) + - square(steps[Y_AXIS]/settings.steps_per_mm[1]) + + square(steps[X_AXIS]/settings.steps_per_mm[0]) + + square(steps[Y_AXIS]/settings.steps_per_mm[1]) + square(steps[Z_AXIS]/settings.steps_per_mm[2])); st_buffer_block(steps[X_AXIS], steps[Y_AXIS], steps[Z_AXIS], - position[X_AXIS], position[Y_AXIS], position[Z_AXIS], + position[X_AXIS], position[Y_AXIS], position[Z_AXIS], lround((millimeters_of_travel/feed_rate)*1000000), line_number); } - memcpy(position, target, sizeof(target)); // position[] = target[] + memcpy(position, target, sizeof(target)); // position[] = target[] } void mc_reposition(double x, double y, double z, int32_t line_number) { int32_t target[3]; // The target position in absolute steps - + target[X_AXIS] = lround(x*settings.steps_per_mm[0]); target[Y_AXIS] = lround(y*settings.steps_per_mm[1]); - target[Z_AXIS] = lround(z*settings.steps_per_mm[2]); - - memcpy(position, target, sizeof(target)); // position[] = target[] + target[Z_AXIS] = lround(z*settings.steps_per_mm[2]); + + memcpy(position, target, sizeof(target)); // position[] = target[] memcpy(actual_position, target, sizeof(target)); // Only really necessary for display - actual - // position gets updated at the start of the + // position gets updated at the start of the // next move, but until then the display would // be wrong. acting_line_number=line_number; @@ -123,7 +123,7 @@ void mc_reposition(double x, double y, double z, int32_t line_number) // circle in millimeters. axis_1 and axis_2 selects the circle plane in tool space. Stick the remaining // axis in axis_l which will be the axis for linear travel if you are tracing a helical motion. -struct arc_to_lineS { // Contains the low level representation for an arc +struct arc_to_lineS { // Contains the low level representation for an arc double target[3]; // in a way that can be converted to lines double theta; double theta_per_segment; @@ -136,12 +136,12 @@ struct arc_to_lineS { // Contains the low level representation for an arc int axis_1; int axis_2; int axis_linear; - int invert_feed_rate; + int invert_feed_rate; int32_t line_number; uint16_t segments; uint16_t i; volatile uint8_t active; -} arc; +} arc; void mc_continue_arc(){ @@ -152,14 +152,14 @@ void mc_continue_arc(){ arc.theta += arc.theta_per_segment; arc.target[arc.axis_1] = arc.center_x+sin(arc.theta)*arc.radius; arc.target[arc.axis_2] = arc.center_y+cos(arc.theta)*arc.radius; - mc_line(arc.target[X_AXIS], - arc.target[Y_AXIS], - arc.target[Z_AXIS], + mc_line(arc.target[X_AXIS], + arc.target[Y_AXIS], + arc.target[Z_AXIS], arc.feed_rate, arc.invert_feed_rate, arc.line_number); } else { - mc_line(arc.end[X_AXIS], - arc.end[Y_AXIS], - arc.end[Z_AXIS], + mc_line(arc.end[X_AXIS], + arc.end[Y_AXIS], + arc.end[Z_AXIS], arc.feed_rate, arc.invert_feed_rate, arc.line_number); } arc.i +=1; @@ -169,20 +169,20 @@ void mc_continue_arc(){ } -// The arc is approximated by generating a huge number of tiny, linear segments. -// The length of each segment is configured in config.h by setting MM_PER_ARC_SEGMENT. -void mc_arc(double theta, double angular_travel, double radius, - double linear_travel, - int axis_1, int axis_2, int axis_linear, +// The arc is approximated by generating a huge number of tiny, linear segments. +// The length of each segment is configured in config.h by setting MM_PER_ARC_SEGMENT. +void mc_arc(double theta, double angular_travel, double radius, + double linear_travel, + int axis_1, int axis_2, int axis_linear, double target_x, double target_y, double target_z, double feed_rate, int invert_feed_rate, int32_t line_number) { double millimeters_of_travel = hypot(angular_travel*radius, labs(linear_travel)); - if (millimeters_of_travel == 0.0) { + if (millimeters_of_travel == 0.0) { //printPgmString(PSTR("\r\nArc length is 0, returning...\r\n")); - return; + return; } - + arc.end[X_AXIS] = target_x; arc.end[Y_AXIS] = target_y; arc.end[Z_AXIS] = target_z; @@ -194,7 +194,7 @@ void mc_arc(double theta, double angular_travel, double radius, arc.radius = radius; arc.segments = ceil(millimeters_of_travel/settings.mm_per_arc_segment); // Multiply inverse feed_rate to compensate for the fact that this movement is approximated - // by a number of discrete segments. The inverse feed_rate should be correct for the sum of + // by a number of discrete segments. The inverse feed_rate should be correct for the sum of // all segments. if (invert_feed_rate) { feed_rate *= arc.segments; } arc.feed_rate = feed_rate; @@ -207,7 +207,7 @@ void mc_arc(double theta, double angular_travel, double radius, arc.center_x = (position[axis_1]/settings.steps_per_mm[axis_1])-sin(theta)*radius; arc.center_y = (position[axis_2]/settings.steps_per_mm[axis_2])-cos(theta)*radius; arc.target[axis_linear] = position[axis_linear]/settings.steps_per_mm[Z_AXIS]; - + arc.i=0; arc.active=1; mc_continue_arc(); // Start drawing arc @@ -238,7 +238,7 @@ void mc_stop() /* void mc_continue(int line_number) -{ +{ st_continue(); } diff --git a/motion_control.h b/motion_control.h index 371da2f30..2d8dc240c 100644 --- a/motion_control.h +++ b/motion_control.h @@ -19,7 +19,7 @@ */ #ifndef motion_control_h -#define motion_control_h +#define motion_control_h #include @@ -37,8 +37,8 @@ void mc_reposition(double x, double y, double z, int32_t line_number); // positive angular_travel means clockwise, negative means counterclockwise. Radius == the radius of the // circle in millimeters. axis_1 and axis_2 selects the circle plane in tool space. Stick the remaining // axis in axis_l which will be the axis for linear travel if you are tracing a helical motion. -void mc_arc(double theta, double angular_travel, double radius, double linear_travel, - int axis_1, int axis_2, int axis_linear, +void mc_arc(double theta, double angular_travel, double radius, double linear_travel, + int axis_1, int axis_2, int axis_linear, double target_x, double target_y, double target_z, double feed_rate, int invert_feed_rate, int32_t line_number); diff --git a/readme.txt b/readme.txt index c4c7dd0af..09af7124f 100644 --- a/readme.txt +++ b/readme.txt @@ -1,4 +1,4 @@ -Grbl - an open source, embedded high performance g-code-parser and CNC milling controller written in optimized C that +Grbl - an open source, embedded high performance g-code-parser and CNC milling controller written in optimized C that will run on a straight Arduino. Documentation: http://dank.bengler.no/-/page/show/5470_grbl @@ -32,5 +32,5 @@ Prioritized to-do: The project was initially inspired by the Arduino GCode Interpreter by Mike Ellery To be done: -- G4 dwell is currently blocking! +- G4 dwell is currently blocking! diff --git a/script/stream.rb b/script/stream.rb index 536f4315d..89667b52e 100644 --- a/script/stream.rb +++ b/script/stream.rb @@ -7,12 +7,12 @@ opts.banner = "Usage: stream [options] gcode-file" opts.on('-v', '--verbose', 'Output more information') do $verbose = true - end + end opts.on('-p', '--prebuffer', 'Prebuffer commands') do $prebuffer = true - end - + end + opts.on('-h', '--help', 'Display this screen') do puts opts exit diff --git a/serial_protocol.c b/serial_protocol.c index 22ef43362..122dbe3ee 100644 --- a/serial_protocol.c +++ b/serial_protocol.c @@ -44,11 +44,11 @@ void prompt() { extern int32_t actual_position[3]; // The current actual position of the tool in absolute steps extern int32_t position[3]; // The current target position of the tool in absolute steps -void sp_init() +void sp_init() { printPgmString(PSTR("\r\nGrbl ")); printPgmString(PSTR(VERSION)); - printPgmString(PSTR("\r\n")); + printPgmString(PSTR("\r\n")); prompt(); } @@ -57,7 +57,7 @@ void return_status(uint8_t status) if (Verbose){ switch(status) { case GCSTATUS_OK: printPgmString(PSTR("ok\r\n")); break; - case GCSTATUS_BAD_NUMBER_FORMAT: printPgmString(PSTR("error: bad number format\r\n")); break; + case GCSTATUS_BAD_NUMBER_FORMAT: printPgmString(PSTR("error: bad number format\r\n")); break; case GCSTATUS_EXPECTED_COMMAND_LETTER: printPgmString(PSTR("error: expected command letter\r\n")); break; case GCSTATUS_UNSUPPORTED_STATEMENT: printPgmString(PSTR("error: unsupported option number\r\n")); break; case GCSTATUS_MOTION_CONTROL_ERROR: printPgmString(PSTR("error: motion control error\r\n")); break; @@ -80,14 +80,14 @@ void return_status(uint8_t status) void print_count_as_mm(float count, char axis, char Pad) { // Convert position in steps to mm: - // pos = steps * 1.27/1600 + // pos = steps * 1.27/1600 // = steps * .00079375 - // = steps * 79375 / 100 000 000 (1e-8) - + // = steps * 79375 / 100 000 000 (1e-8) + long whole; long fraction; float answer; - + if (axis==X_AXIS){ answer = count*DEFAULT_X_UM_PER_STEP; } else if (axis==Y_AXIS){ @@ -114,8 +114,8 @@ void print_count_as_mm(float count, char axis, char Pad) if (fraction<10) printPgmString(PSTR("0")); printInteger(fraction); } -} - +} + void sp_report_position() { @@ -138,7 +138,7 @@ void sp_report_position() print_count_as_mm(actual_position[Z_AXIS], Z_AXIS, 1); printPgmString(PSTR("\n\r\n\r")); -} +} void sp_quick_position() { @@ -165,7 +165,7 @@ void sp_quick_position() printInteger(iterations/100); // The number of iterations left to complete the current_block } printPgmString(PSTR("\n\r")); -} +} extern char buttons[4]; @@ -288,7 +288,7 @@ void process_command(char *line) } if (line[1]!='Q') prompt(); } -} +} void sp_process() { @@ -296,22 +296,22 @@ void sp_process() uint8_t status; // Only gets processed if there is something waiting on the serial port: - while((c = serialRead()) != -1) + while((c = serialRead()) != -1) { // Echo sent characters if required: - if (Verbose) serialWrite(c); - + if (Verbose) serialWrite(c); + if (c == '\r') {serialWrite('\n');} - + if((char_counter > 0) && ((c == '\n') || (c == '\r'))) { // Line is complete. Then execute! line[char_counter] = 0; printString(line); printPgmString(PSTR("\r\n")); if (line[0]=='E'){ process_command(line); char_counter=0; - } else { + } else { status = gc_execute_line(line); - char_counter = 0; + char_counter = 0; return_status(status); } } else if (c <= ' ') { // Throw away whitepace and control characters diff --git a/serial_protocol.h b/serial_protocol.h index c7abdc75a..9e2792cdb 100644 --- a/serial_protocol.h +++ b/serial_protocol.h @@ -24,7 +24,7 @@ void sp_init(); // Read command lines from the serial port and execute them as they -// come in. Blocks until the serial buffer is emptied. +// come in. Blocks until the serial buffer is emptied. void sp_process(); #endif diff --git a/spindle_control.c b/spindle_control.c index 4dbf9fd94..974916503 100644 --- a/spindle_control.c +++ b/spindle_control.c @@ -28,7 +28,7 @@ void spindle_init() SPINDLE_ENABLE_DDR |= 1<= 0) { SPINDLE_DIRECTION_PORT &= ~(1< diff --git a/stepper.c b/stepper.c index 627b07997..0a5eeb854 100644 --- a/stepper.c +++ b/stepper.c @@ -19,7 +19,7 @@ */ /* The timer calculations of this module informed by the 'RepRap cartesian firmware' by Zack Smith - and Philipp Tiefenbacher. The ring buffer implementation gleaned from the wiring_serial library + and Philipp Tiefenbacher. The ring buffer implementation gleaned from the wiring_serial library by David A. Mellis */ #include "stepper.h" @@ -67,7 +67,7 @@ struct Block { extern int32_t position[3]; // The current position of the tool in absolute steps int32_t actual_position[3]; // The current position of the tool in absolute steps - // In this file, this is actually the current position, not + // In this file, this is actually the current position, not // estimated current position... struct Block block_buffer[BLOCK_BUFFER_SIZE]; // A buffer for step instructions @@ -81,14 +81,14 @@ volatile int block_buffer_tail = 0; // Variables used by SIG_OUTPUT_COMPARE1A uint8_t out_bits; // The next stepping-bits to be output struct Block *current_block; // A pointer to the block currently being traced -volatile int32_t counter_x, - counter_y, +volatile int32_t counter_x, + counter_y, counter_z; // counter variables for the bresenham line tracer uint32_t iterations; // The number of iterations left to complete the current_block volatile int busy; // TRUE when SIG_OUTPUT_COMPARE1A is being serviced. Used to avoid retriggering that handler. uint8_t old_direction_bits; // Holds the direction bits from the previous - // call to st_buffer_block, to + // call to st_buffer_block, to // determine if backlash compensation is required. extern char buttons[4]; @@ -97,7 +97,7 @@ void config_step_timer(uint32_t microseconds); char st_buffer_full() { -//In cases where there is a change of direction, two items +//In cases where there is a change of direction, two items // get put onto the st_buffer (the backlash compensation step // and the actual movement). So this check for space in the // buffer checks to see if there are two spaces left. @@ -111,8 +111,8 @@ char st_buffer_full() int nb1; int nb2; - nb2 = (block_buffer_head + 2) % BLOCK_BUFFER_SIZE; - nb1 = (block_buffer_head + 1) % BLOCK_BUFFER_SIZE; + nb2 = (block_buffer_head + 2) % BLOCK_BUFFER_SIZE; + nb1 = (block_buffer_head + 1) % BLOCK_BUFFER_SIZE; return ((nb1 == block_buffer_tail)|| (nb2 == block_buffer_tail)); @@ -125,65 +125,65 @@ int st_buffer_delay(uint32_t milliseconds, int16_t line_number) { st_stop(); return 0; } - + while (st_buffer_full()) { sleep_mode();} // makes sure there are two /* // slots left on buffer printPgmString(PSTR("in st_buffer_delay. Delay = ")); printInteger(milliseconds); printPgmString(PSTR("\r\n"));*/ - - + + // Setup block record block = &block_buffer[block_buffer_head]; block->backlash=0; block->line_number = line_number; - + block->maximum_steps = milliseconds; block->rate = 1000; block->mode = SM_HALT; // Move buffer head block_buffer_head = (block_buffer_head + 1) % BLOCK_BUFFER_SIZE; //next_buffer_head; - + // Ensure that blocks will be processed by enabling the Stepper Driver Interrupt ENABLE_STEPPER_DRIVER_INTERRUPT(); return 1; } // ************************************************************************************************* -// Add a new linear movement to the buffer. steps_x, _y and _z is the signed, relative motion in +// Add a new linear movement to the buffer. steps_x, _y and _z is the signed, relative motion in // steps. Microseconds specify how many microseconds the move should take to perform. // -// DV: +// DV: // 1. Works out how many steps to go in each direction // 2. Takes total time and divides by number of steps to get time for one step -// 3. Put time per step, and number of steps in x, y, z into block record. +// 3. Put time per step, and number of steps in x, y, z into block record. // 4. Enable timer. int st_buffer_block(int32_t steps_x, int32_t steps_y, int32_t steps_z, int32_t pos_x, int32_t pos_y, int32_t pos_z, - uint32_t microseconds, + uint32_t microseconds, int16_t line_number) { uint8_t direction_bits = 0; uint8_t changed_dir; struct Block *block; struct Block *comp_block=NULL; uint32_t maximum_steps; - + maximum_steps = max(labs(steps_x), max(labs(steps_y), labs(steps_z))); - // Don't process empty blocks + // Don't process empty blocks if (maximum_steps==0) {return 0;} - - // Determine direction bits + + // Determine direction bits if (steps_x < 0) { direction_bits |= (1<backlash = 1; comp_block->direction_bits = direction_bits; comp_block->line_number = line_number; - + comp_block->steps_x = 0; comp_block->steps_y = 0; - comp_block->steps_z = 0; - + comp_block->steps_z = 0; + comp_block->pos_x = pos_x; comp_block->pos_y = pos_y; - comp_block->pos_z = pos_z; + comp_block->pos_z = pos_z; changed_dir = direction_bits^old_direction_bits; @@ -207,13 +207,13 @@ int st_buffer_block(int32_t steps_x, int32_t steps_y, int32_t steps_z, if (changed_dir & (1<steps_x=settings.backlash_x_count; if (changed_dir & (1<steps_y=settings.backlash_y_count; if (changed_dir & (1<steps_z=settings.backlash_z_count; - + // Use same rate for backlash compensation as for the block itself: comp_block->rate = microseconds/maximum_steps; comp_block->mode = SM_RUN; comp_block->maximum_steps = max(comp_block->steps_x, max(comp_block->steps_y, comp_block->steps_z)); - // If compensation is not empty, advance the end of the queue + // If compensation is not empty, advance the end of the queue if (comp_block->maximum_steps > 0) { block_buffer_head = (block_buffer_head + 1) % BLOCK_BUFFER_SIZE; } @@ -223,25 +223,25 @@ int st_buffer_block(int32_t steps_x, int32_t steps_y, int32_t steps_z, block = &block_buffer[block_buffer_head]; block->backlash=0; block->line_number = line_number; - + block->steps_x = labs(steps_x); block->steps_y = labs(steps_y); - block->steps_z = labs(steps_z); - + block->steps_z = labs(steps_z); + block->pos_x = pos_x; block->pos_y = pos_y; - block->pos_z = pos_z; - + block->pos_z = pos_z; + block->maximum_steps = maximum_steps; block->rate = microseconds/block->maximum_steps; block->mode = SM_RUN; // Compute direction bits for this block block->direction_bits = direction_bits; - + // Move buffer head block_buffer_head = (block_buffer_head + 1) % BLOCK_BUFFER_SIZE; //next_buffer_head; - + // Ensure that blocks will be processed by enabling The Stepper Driver Interrupt ENABLE_STEPPER_DRIVER_INTERRUPT(); return 1; @@ -249,18 +249,18 @@ int st_buffer_block(int32_t steps_x, int32_t steps_y, int32_t steps_z, // ************************************************************************************************* // "The Stepper Driver Interrupt" - This timer interrupt is the workhorse of Trbl. It is executed at the rate set with -// config_step_timer. It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately. +// config_step_timer. It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately. // It is supported by The Stepper Port Reset Interrupt which it uses to reset the stepper port after each pulse. -// +// // DV: // If this is a new block: // 1. Set up counters // 2. Set up timer // 3. Fire interupt // else if we're already ticking: -// 1. On each of x, y, z: +// 1. On each of x, y, z: // add number of steps in direction -// +// char st_process_manual_buttons(void); @@ -282,9 +282,9 @@ SIGNAL(SIG_OUTPUT_COMPARE1A) busy = TRUE; sei(); // Re enable interrupts (normally disabled while inside an interrupt handler) - // We re-enable interrupts in order for SIG_OVERFLOW2 to be able to be triggered + // We re-enable interrupts in order for SIG_OVERFLOW2 to be able to be triggered // at exactly the right time even if we occasionally spend a lot of time inside this handler. - + // If there is no current block, attempt to pop one from the buffer if (current_block == NULL) { // Anything in the buffer? @@ -314,7 +314,7 @@ SIGNAL(SIG_OUTPUT_COMPARE1A) STEPPERS_ENABLE_PORT &= ~(1<direction_bits; - + out_bits=0; if (buttons[0] < 0) { out_bits |= (1<0){ if (abs(buttons[1])>abs(buttons[0])){ // Need code to deal with different speeds on x and y simultaneously // Will do this by only updating the slower one every nth frame, but // too lazy to write it right now. - + } - - + + delay = FULL_SPEED_DELAY << (8-abs(buttons[0])); config_step_timer(delay); // Takes microseconds between ticks @@ -565,7 +565,7 @@ char st_process_manual_buttons(void) actual_position[X_AXIS]+=1; } - } + } if (abs(buttons[1])>0){ delay = FULL_SPEED_DELAY << (8-abs(buttons[1])); config_step_timer(delay); // Takes microseconds between ticks @@ -576,7 +576,7 @@ char st_process_manual_buttons(void) } else { actual_position[Y_AXIS]+=1; } - } + } if (abs(buttons[2])>0){ delay = FULL_SPEED_DELAY << (8-abs(buttons[2])); config_step_timer(delay); // Takes microseconds between ticks @@ -587,7 +587,7 @@ char st_process_manual_buttons(void) } else { actual_position[Z_AXIS]+=1; } - } + } // Update the actual position register based on // steps about to be issued. diff --git a/stepper.h b/stepper.h index ada297167..a7436444e 100644 --- a/stepper.h +++ b/stepper.h @@ -19,7 +19,7 @@ */ #ifndef stepper_h -#define stepper_h +#define stepper_h #include #include @@ -35,13 +35,13 @@ extern uint32_t iterations; // The number of iterations left to compl // Initialize and start the stepper motor subsystem void st_init(); -// Add a new linear movement to the buffer. steps_x, _y and _z is the signed, +// Add a new linear movement to the buffer. steps_x, _y and _z is the signed, // relative motion in steps. // pos_x, _y, _z is the position in absolute steps at the start of the move // Microseconds specify how many microseconds the move should take to perform. -int st_buffer_block(int32_t steps_x, int32_t steps_y, int32_t steps_z, +int st_buffer_block(int32_t steps_x, int32_t steps_y, int32_t steps_z, int32_t pos_x, int32_t pos_y, int32_t pos_z, - uint32_t rate, + uint32_t rate, int16_t line_number); // Returns true if the stepper buffer is full. This can allow the controlling diff --git a/virtfunc.cpp b/virtfunc.cpp index 08ed2ea71..fc68ca07c 100644 --- a/virtfunc.cpp +++ b/virtfunc.cpp @@ -1,4 +1,4 @@ extern "C" void __cxa_pure_virtual(void) { while(1); -} +} diff --git a/wiring_serial.c b/wiring_serial.c index fb63a4891..b48a106d2 100644 --- a/wiring_serial.c +++ b/wiring_serial.c @@ -48,11 +48,11 @@ void beginSerial(long baud) { UBRR0H = ((F_CPU / 16 + baud / 2) / baud - 1) >> 8; UBRR0L = ((F_CPU / 16 + baud / 2) / baud - 1); - + // enable rx and tx sbi(UCSR0B, RXEN0); sbi(UCSR0B, TXEN0); - + // enable interrupt on complete reception of a byte sbi(UCSR0B, RXCIE0); cbi(UCSR0B, UDRIE0); @@ -117,7 +117,7 @@ SIGNAL(USART_UDRE_vect) // There is more data in the output buffer. Send the next byte unsigned char c = tx_buffer[tx_tail]; tx_tail = (tx_tail + 1) % TX_BUFFER_SIZE; - + UDR0 = c; } } @@ -126,15 +126,15 @@ void serialWrite(unsigned char c) { unsigned char empty = (tx_head == tx_tail); unsigned char i = (tx_head + 1) % TX_BUFFER_SIZE; - - // If the output buffer is full, there's nothing for it other than to + + // If the output buffer is full, there's nothing for it other than to // wait for the interrupt handler to empty it a bit while (i == tx_tail) ; - + tx_buffer[tx_head] = c; tx_head = i; - + if (empty) { // The buffer was empty before the new character was added, so enable interrupt on // USART Data Register empty. The interrupt handler will take it from there @@ -148,15 +148,15 @@ void HardwareSerial::write(uint8_t c) { bool empty = (_tx_buffer->head == _tx_buffer->tail); int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE; - - // If the output buffer is full, there's nothing for it other than to + + // If the output buffer is full, there's nothing for it other than to // wait for the interrupt handler to empty it a bit while (i == _tx_buffer->tail) ; - + _tx_buffer->buffer[_tx_buffer->head] = c; _tx_buffer->head = i; - + if (empty) { // The buffer was empty, so enable interrupt on // USART Data Register empty. The interrupt handler will take it from there @@ -197,7 +197,7 @@ void printByte(unsigned char c) // { // printByte('\n'); // } -// +// void printString(const char *s) { while (*s) @@ -213,14 +213,14 @@ void printPgmString(const char *s) } void printIntegerInBase(unsigned long n, unsigned long base) -{ - unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars. +{ + unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars. unsigned long i = 0; if (n == 0) { printByte('0'); return; - } + } while (n > 0) { buf[i++] = n % base; @@ -256,12 +256,12 @@ void printFloat(double n) // { // printIntegerInBase(n, 16); // } -// +// // void printOctal(unsigned long n) // { // printIntegerInBase(n, 8); // } -// +// // void printBinary(unsigned long n) // { // printIntegerInBase(n, 2); @@ -274,11 +274,11 @@ void print(const char *format, ...) { char buf[256]; va_list ap; - + va_start(ap, format); vsnprintf(buf, 256, format, ap); va_end(ap); - + printString(buf); } */